@esportsplus/typescript 0.29.6 → 0.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -3
- package/bin/tsc-alias +1 -1
- package/bin/tsc-lsp +3 -0
- package/build/cli/diagnostics.d.ts +8 -0
- package/build/cli/diagnostics.js +95 -0
- package/build/cli/tsc.d.ts +12 -2
- package/build/cli/tsc.js +343 -52
- package/build/compiler/ast.d.ts +7 -5
- package/build/compiler/ast.js +6 -6
- package/build/compiler/code.d.ts +5 -4
- package/build/compiler/code.js +12 -1
- package/build/compiler/coordinator.d.ts +16 -7
- package/build/compiler/coordinator.js +75 -41
- package/build/compiler/imports.d.ts +8 -3
- package/build/compiler/imports.js +34 -24
- package/build/compiler/index.d.ts +3 -0
- package/build/compiler/index.js +1 -0
- package/build/compiler/language-service.d.ts +36 -6
- package/build/compiler/language-service.js +252 -58
- package/build/compiler/plugins/index.d.ts +4 -2
- package/build/compiler/plugins/tsc.d.ts +1 -1
- package/build/compiler/plugins/vite.d.ts +6 -3
- package/build/compiler/plugins/vite.js +15 -8
- package/build/compiler/sourcemap.d.ts +52 -0
- package/build/compiler/sourcemap.js +265 -0
- package/build/compiler/types.d.ts +7 -6
- package/build/compiler/uid.d.ts +5 -2
- package/build/compiler/uid.js +33 -4
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/jsonc.d.ts +2 -0
- package/build/jsonc.js +85 -0
- package/build/lsp/bin.d.ts +1 -0
- package/build/lsp/bin.js +2 -0
- package/build/lsp/diagnostics.d.ts +10 -0
- package/build/lsp/diagnostics.js +69 -0
- package/build/lsp/index.d.ts +2 -0
- package/build/lsp/index.js +2 -0
- package/build/lsp/server.d.ts +4 -0
- package/build/lsp/server.js +130 -0
- package/build/lsp/workspace.d.ts +14 -0
- package/build/lsp/workspace.js +46 -0
- package/build/probe/adapter.d.ts +14 -0
- package/build/probe/adapter.js +42 -0
- package/build/probe/async/channel.d.ts +4 -0
- package/build/probe/async/channel.js +560 -0
- package/build/probe/async/value.d.ts +9 -0
- package/build/probe/async/value.js +16 -0
- package/build/probe/channels.d.ts +4 -0
- package/build/probe/channels.js +16 -0
- package/build/probe/exceptions/channel.d.ts +5 -0
- package/build/probe/exceptions/channel.js +657 -0
- package/build/probe/exceptions/jsdoc.d.ts +8 -0
- package/build/probe/exceptions/jsdoc.js +34 -0
- package/build/probe/exceptions/value.d.ts +39 -0
- package/build/probe/exceptions/value.js +158 -0
- package/build/probe/kernel/analyze.d.ts +8 -0
- package/build/probe/kernel/analyze.js +68 -0
- package/build/probe/kernel/ast.d.ts +11 -0
- package/build/probe/kernel/ast.js +49 -0
- package/build/probe/kernel/config.d.ts +5 -0
- package/build/probe/kernel/config.js +209 -0
- package/build/probe/kernel/fixpoint.d.ts +6 -0
- package/build/probe/kernel/fixpoint.js +206 -0
- package/build/probe/kernel/format.d.ts +4 -0
- package/build/probe/kernel/format.js +32 -0
- package/build/probe/kernel/graph.d.ts +4 -0
- package/build/probe/kernel/graph.js +507 -0
- package/build/probe/kernel/ids.d.ts +8 -0
- package/build/probe/kernel/ids.js +66 -0
- package/build/probe/kernel/program.d.ts +8 -0
- package/build/probe/kernel/program.js +13 -0
- package/build/probe/kernel/types.d.ts +134 -0
- package/build/probe/kernel/types.js +1 -0
- package/build/probe/overlay/base/async.jsonc +13 -0
- package/build/probe/overlay/base/exceptions.jsonc +54 -0
- package/build/probe/overlay/base/resources.jsonc +57 -0
- package/build/probe/overlay/load.d.ts +18 -0
- package/build/probe/overlay/load.js +302 -0
- package/build/probe/overlay/presets/express.jsonc +25 -0
- package/build/probe/overlay/presets/node.jsonc +17 -0
- package/build/probe/resources/channel.d.ts +4 -0
- package/build/probe/resources/channel.js +798 -0
- package/build/probe/resources/value.d.ts +9 -0
- package/build/probe/resources/value.js +36 -0
- package/build/ts.d.ts +3 -0
- package/build/ts.js +3 -0
- package/build/tsconfig.d.ts +2 -0
- package/build/tsconfig.js +150 -0
- package/package.json +29 -9
- package/tsconfig.base.json +19 -0
- package/tsconfig.dev.json +13 -0
- package/tsconfig.package.json +4 -1
- package/.claude/skills/code-audit/registry-typescript.json +0 -326
- package/.editorconfig +0 -9
- package/.gitattributes +0 -2
- package/.github/dependabot.yml +0 -25
- package/.github/workflows/bump.yml +0 -27
- package/.github/workflows/dependabot.yml +0 -58
- package/.github/workflows/publish.yml +0 -42
- package/.github/workflows/templates/bump.yml +0 -9
- package/.github/workflows/templates/dependabot.yml +0 -12
- package/.github/workflows/templates/publish.yml +0 -16
- package/pnpm-workspace.yaml +0 -6
- package/src/cli/tsc.ts +0 -235
- package/src/compiler/ast.ts +0 -60
- package/src/compiler/code.ts +0 -27
- package/src/compiler/coordinator.ts +0 -284
- package/src/compiler/imports.ts +0 -185
- package/src/compiler/index.ts +0 -7
- package/src/compiler/language-service.ts +0 -121
- package/src/compiler/plugins/index.ts +0 -5
- package/src/compiler/plugins/tsc.ts +0 -6
- package/src/compiler/plugins/vite.ts +0 -91
- package/src/compiler/types.ts +0 -83
- package/src/compiler/uid.ts +0 -10
- package/src/constants.ts +0 -4
- package/src/index.ts +0 -1
- package/tests/cli/tsc.test.ts +0 -155
- package/tests/compiler/ast.test.ts +0 -131
- package/tests/compiler/code.test.ts +0 -73
- package/tests/compiler/coordinator.bench.ts +0 -101
- package/tests/compiler/coordinator.test.ts +0 -872
- package/tests/compiler/imports.test.ts +0 -167
- package/tests/compiler/language-service.test.ts +0 -90
- package/tests/compiler/plugins.test.ts +0 -172
- package/tests/compiler/uid.test.ts +0 -70
- package/tsconfig.json +0 -3
- package/vitest.config.ts +0 -14
package/build/cli/tsc.js
CHANGED
|
@@ -1,59 +1,196 @@
|
|
|
1
|
+
import { DiagnosticCategory } from 'typescript/unstable/sync';
|
|
1
2
|
import { createRequire } from 'module';
|
|
3
|
+
import { format } from './diagnostics.js';
|
|
2
4
|
import { PACKAGE_NAME } from '../constants.js';
|
|
3
5
|
import { pathToFileURL } from 'url';
|
|
4
6
|
import { spawn } from 'child_process';
|
|
5
7
|
import coordinator from '../compiler/coordinator.js';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import languageService from '../compiler/language-service.js';
|
|
6
10
|
import path from 'path';
|
|
7
|
-
import
|
|
11
|
+
import sourcemap from '../compiler/sourcemap.js';
|
|
12
|
+
import { analyze, analyzeProgram } from '../probe/kernel/analyze.js';
|
|
13
|
+
import { formatDiagnostics } from '../probe/kernel/format.js';
|
|
14
|
+
import { loadConfigFromTsconfig } from '../probe/kernel/config.js';
|
|
15
|
+
import { stripJsonc } from '../jsonc.js';
|
|
16
|
+
import { readPlugins } from '../tsconfig.js';
|
|
8
17
|
const BACKSLASH_REGEX = /\\/g;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
const INFORMATIONAL_FLAGS = new Set(['--help', '--init', '--showConfig', '--version', '-h', '-v']);
|
|
19
|
+
const NO_EMIT_FLAGS = new Set(['--noEmit', '-noEmit']);
|
|
20
|
+
const WATCH_FLAGS = new Set(['--watch', '-w']);
|
|
21
|
+
let require = createRequire(import.meta.url), skipFlags = new Set([...INFORMATIONAL_FLAGS, ...NO_EMIT_FLAGS]);
|
|
22
|
+
async function build(tsconfig, pluginConfigs, instance, noEmit = false) {
|
|
23
|
+
let opened = instance === undefined ? languageService.open(tsconfig) : undefined, root = path.dirname(path.resolve(tsconfig)), owned = instance === undefined, api = opened?.api ?? instance, snapshot = opened?.snapshot ?? api.updateSnapshot({ openProjects: [tsconfig] }), project = opened?.project ?? snapshot.getProject(tsconfig);
|
|
24
|
+
if (!project) {
|
|
25
|
+
teardown(snapshot, tsconfig, owned);
|
|
26
|
+
throw new Error(`${PACKAGE_NAME}: project not found for ${tsconfig}`);
|
|
27
|
+
}
|
|
28
|
+
let configDiagnostics = project.program.getConfigFileParsingDiagnostics();
|
|
29
|
+
if (configDiagnostics.some((diagnostic) => diagnostic.category === DiagnosticCategory.Error)) {
|
|
30
|
+
console.error(format(configDiagnostics, root));
|
|
31
|
+
teardown(snapshot, tsconfig, owned);
|
|
16
32
|
process.exit(1);
|
|
17
33
|
}
|
|
18
|
-
let plugins =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
let { fileNames, options } = api.parseConfigFile(tsconfig), plugins, shared = new Map(), transformedFiles = new Map();
|
|
35
|
+
runAnalyze(tsconfig, project.program, project.checker);
|
|
36
|
+
try {
|
|
37
|
+
plugins = await loadPlugins(pluginConfigs, root);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
41
|
+
teardown(snapshot, tsconfig, owned);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
for (let i = 0, n = fileNames.length; i < n; i++) {
|
|
45
|
+
let fileName = fileNames[i], sourceFile = project.program.getSourceFile(fileName);
|
|
22
46
|
if (!sourceFile) {
|
|
23
47
|
continue;
|
|
24
48
|
}
|
|
25
|
-
let result = coordinator.transform(plugins, sourceFile.getFullText(), sourceFile, program, root, shared);
|
|
49
|
+
let result = coordinator.transform(plugins, sourceFile.getFullText(), sourceFile, { checker: project.checker, configPath: tsconfig, program: project.program }, root, shared);
|
|
26
50
|
if (result.changed) {
|
|
27
|
-
transformedFiles.set(normalizePath(fileName), result.code);
|
|
51
|
+
transformedFiles.set(normalizePath(fileName), { code: result.code, mapping: result.map });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
let program = transformedFiles.size === 0
|
|
55
|
+
? project.program
|
|
56
|
+
: languageService.updateMany(tsconfig, new Map([...transformedFiles].map(([fileName, entry]) => [fileName, entry.code]))).program;
|
|
57
|
+
let diagnostics = [
|
|
58
|
+
...program.getConfigFileParsingDiagnostics(),
|
|
59
|
+
...program.getSyntacticDiagnostics(),
|
|
60
|
+
...program.getBindDiagnostics(),
|
|
61
|
+
...program.getSemanticDiagnostics(),
|
|
62
|
+
...program.getGlobalDiagnostics(),
|
|
63
|
+
...program.getProgramDiagnostics()
|
|
64
|
+
];
|
|
65
|
+
if (diagnostics.length > 0) {
|
|
66
|
+
console.error(format(diagnostics, root, transformedFiles));
|
|
67
|
+
}
|
|
68
|
+
if (diagnostics.some((diagnostic) => diagnostic.category === DiagnosticCategory.Error)) {
|
|
69
|
+
teardown(snapshot, tsconfig, owned);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
if (noEmit) {
|
|
73
|
+
teardown(snapshot, tsconfig, owned);
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
let code = await emit(tsconfig, fileNames, transformedFiles, root, options);
|
|
77
|
+
teardown(snapshot, tsconfig, owned);
|
|
78
|
+
if (code !== 0) {
|
|
79
|
+
process.exit(code);
|
|
80
|
+
}
|
|
81
|
+
return runTscAlias(process.argv.slice(2)).then((exitCode) => process.exit(exitCode));
|
|
82
|
+
}
|
|
83
|
+
function classifyFlags(args) {
|
|
84
|
+
let informational = false, noEmit = false, watch = false;
|
|
85
|
+
for (let i = 0, n = args.length; i < n; i++) {
|
|
86
|
+
let arg = args[i];
|
|
87
|
+
if (INFORMATIONAL_FLAGS.has(arg)) {
|
|
88
|
+
informational = true;
|
|
89
|
+
}
|
|
90
|
+
else if (NO_EMIT_FLAGS.has(arg)) {
|
|
91
|
+
noEmit = true;
|
|
92
|
+
}
|
|
93
|
+
else if (WATCH_FLAGS.has(arg)) {
|
|
94
|
+
watch = true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { informational, noEmit, watch };
|
|
98
|
+
}
|
|
99
|
+
function collectMaps(dir, results) {
|
|
100
|
+
for (let entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
101
|
+
let full = path.join(dir, entry.name);
|
|
102
|
+
if (entry.isDirectory()) {
|
|
103
|
+
collectMaps(full, results);
|
|
104
|
+
}
|
|
105
|
+
else if (entry.name.endsWith('.js.map')) {
|
|
106
|
+
results.push(full);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function composeSourceMaps(mirrorOut, mirror, root, transformedFiles) {
|
|
111
|
+
let maps = [];
|
|
112
|
+
collectMaps(mirrorOut, maps);
|
|
113
|
+
for (let i = 0, n = maps.length; i < n; i++) {
|
|
114
|
+
let mapPath = maps[i], raw;
|
|
115
|
+
try {
|
|
116
|
+
raw = JSON.parse(fs.readFileSync(mapPath, 'utf8'));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (!raw.sources || raw.sources.length === 0 || typeof raw.sources[0] !== 'string' || typeof raw.mappings !== 'string') {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
let mirrorSource = path.resolve(path.dirname(mapPath), raw.sources[0]), relative = path.relative(mirror, mirrorSource), realSource = normalizePath(path.join(root, relative)), entry = transformedFiles.get(realSource);
|
|
125
|
+
if (!entry) {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
let composed = sourcemap.composeEmittedMap({ mappings: raw.mappings, names: raw.names ?? [], sources: raw.sources, version: 3 }, entry.mapping, entry.code, fs.readFileSync(path.join(root, relative), 'utf8'));
|
|
129
|
+
if (raw.file !== undefined) {
|
|
130
|
+
composed.file = raw.file;
|
|
28
131
|
}
|
|
132
|
+
if (raw.sourceRoot !== undefined) {
|
|
133
|
+
composed.sourceRoot = raw.sourceRoot;
|
|
134
|
+
}
|
|
135
|
+
fs.writeFileSync(mapPath, JSON.stringify(composed));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function emit(tsconfig, fileNames, transformedFiles, root, options) {
|
|
139
|
+
let tscJs = path.join(path.dirname(require.resolve('typescript/package.json')), 'lib', 'tsc.js');
|
|
140
|
+
if (transformedFiles.size === 0) {
|
|
141
|
+
return spawnTsc(tscJs, ['-p', tsconfig]);
|
|
29
142
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
143
|
+
let mirror = fs.mkdtempSync(path.join(root, '.esportsplus-tsc-'));
|
|
144
|
+
try {
|
|
145
|
+
let declaration = options.declaration === true, files = [], mirrorDecl = path.join(mirror, '__decl'), mirrorOut = path.join(mirror, '__emit'), realOutDir = typeof options.outDir === 'string' ? path.resolve(options.outDir) : root, realDeclDir = declaration
|
|
146
|
+
? (typeof options.declarationDir === 'string' ? path.resolve(options.declarationDir) : realOutDir)
|
|
147
|
+
: undefined, realRootDir = typeof options.rootDir === 'string' ? path.resolve(options.rootDir) : undefined, separateDecl = realDeclDir !== undefined && normalizePath(realDeclDir) !== normalizePath(realOutDir);
|
|
148
|
+
for (let i = 0, n = fileNames.length; i < n; i++) {
|
|
149
|
+
let source = path.resolve(fileNames[i]), relative = path.relative(root, source);
|
|
150
|
+
if (relative.startsWith('..')) {
|
|
151
|
+
throw new Error(`${PACKAGE_NAME}: source ${normalizePath(source)} resolves outside the project root ${normalizePath(root)}; monorepo-external sources are not supported by the transform emit path`);
|
|
36
152
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
153
|
+
let target = path.join(mirror, relative), transformed = transformedFiles.get(normalizePath(fileNames[i]));
|
|
154
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
155
|
+
if (transformed === undefined) {
|
|
156
|
+
fs.copyFileSync(source, target);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
fs.writeFileSync(target, transformed.code);
|
|
160
|
+
}
|
|
161
|
+
files.push(normalizePath(target));
|
|
162
|
+
}
|
|
163
|
+
let compilerOptions = {
|
|
164
|
+
outDir: normalizePath(mirrorOut)
|
|
41
165
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
166
|
+
if (declaration) {
|
|
167
|
+
compilerOptions.declarationDir = normalizePath(separateDecl ? mirrorDecl : mirrorOut);
|
|
168
|
+
}
|
|
169
|
+
if (realRootDir !== undefined) {
|
|
170
|
+
compilerOptions.rootDir = normalizePath(path.join(mirror, path.relative(root, realRootDir)));
|
|
171
|
+
}
|
|
172
|
+
fs.writeFileSync(path.join(mirror, 'tsconfig.json'), JSON.stringify({
|
|
173
|
+
compilerOptions,
|
|
174
|
+
exclude: [],
|
|
175
|
+
extends: normalizePath(tsconfig),
|
|
176
|
+
files,
|
|
177
|
+
include: []
|
|
51
178
|
}));
|
|
179
|
+
let code = await spawnTsc(tscJs, ['-p', path.join(mirror, 'tsconfig.json')]);
|
|
180
|
+
if (code === 0) {
|
|
181
|
+
if (fs.existsSync(mirrorOut)) {
|
|
182
|
+
composeSourceMaps(mirrorOut, mirror, root, transformedFiles);
|
|
183
|
+
fs.cpSync(mirrorOut, realOutDir, { force: true, recursive: true });
|
|
184
|
+
}
|
|
185
|
+
if (separateDecl && realDeclDir !== undefined && fs.existsSync(mirrorDecl)) {
|
|
186
|
+
fs.cpSync(mirrorDecl, realDeclDir, { force: true, recursive: true });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return code;
|
|
52
190
|
}
|
|
53
|
-
|
|
54
|
-
|
|
191
|
+
finally {
|
|
192
|
+
fs.rmSync(mirror, { force: true, recursive: true });
|
|
55
193
|
}
|
|
56
|
-
return runTscAlias(process.argv.slice(2)).then((code) => process.exit(code));
|
|
57
194
|
}
|
|
58
195
|
function isPlugin(value) {
|
|
59
196
|
return typeof value === 'object' && value !== null && 'transform' in value && typeof value.transform === 'function';
|
|
@@ -75,18 +212,15 @@ async function loadPlugins(configs, root) {
|
|
|
75
212
|
}
|
|
76
213
|
if (Array.isArray(plugin)) {
|
|
77
214
|
for (let j = 0, m = plugin.length; j < m; j++) {
|
|
78
|
-
if (isPlugin(plugin[j])) {
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
console.error(`${PACKAGE_NAME}: plugin ${config.transform}[${j}] uses an invalid plugin format`);
|
|
215
|
+
if (!isPlugin(plugin[j])) {
|
|
216
|
+
throw new Error(`${PACKAGE_NAME}: plugin ${config.transform}[${j}] uses an invalid plugin format, expected { transform: Function }`);
|
|
83
217
|
}
|
|
218
|
+
plugins.push(plugin[j]);
|
|
84
219
|
}
|
|
85
220
|
return;
|
|
86
221
|
}
|
|
87
222
|
if (!isPlugin(plugin)) {
|
|
88
|
-
|
|
89
|
-
return;
|
|
223
|
+
throw new Error(`${PACKAGE_NAME}: plugin ${config.transform} uses an invalid plugin format, expected { transform: Function } or Plugin[]`);
|
|
90
224
|
}
|
|
91
225
|
plugins.push(plugin);
|
|
92
226
|
}));
|
|
@@ -95,20 +229,27 @@ async function loadPlugins(configs, root) {
|
|
|
95
229
|
return plugins;
|
|
96
230
|
}
|
|
97
231
|
function main() {
|
|
98
|
-
let
|
|
232
|
+
let args = process.argv.slice(2), tsconfig = projectPath(args) ?? languageService.findConfig(process.cwd());
|
|
99
233
|
if (!tsconfig) {
|
|
100
234
|
return passthrough();
|
|
101
235
|
}
|
|
102
|
-
let
|
|
103
|
-
|
|
236
|
+
let flags = classifyFlags(args);
|
|
237
|
+
let pluginConfigs = resolvePluginConfigs(tsconfig);
|
|
238
|
+
if (pluginConfigs.length === 0) {
|
|
239
|
+
if (!flags.informational && !flags.watch) {
|
|
240
|
+
runAnalyze(tsconfig);
|
|
241
|
+
}
|
|
104
242
|
return passthrough();
|
|
105
243
|
}
|
|
106
|
-
|
|
107
|
-
if (pluginConfigs.length === 0) {
|
|
244
|
+
if (flags.informational) {
|
|
108
245
|
return passthrough();
|
|
109
246
|
}
|
|
247
|
+
if (flags.watch) {
|
|
248
|
+
console.error(`${PACKAGE_NAME}: --watch is not supported on the transformer plugin path; run a one-shot build or use real tsc directly`);
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
110
251
|
console.log(`${PACKAGE_NAME}: found ${pluginConfigs.length} transformer plugin(s), using coordinated build...`);
|
|
111
|
-
build(
|
|
252
|
+
build(tsconfig, pluginConfigs, undefined, flags.noEmit).catch((err) => {
|
|
112
253
|
console.error(`${PACKAGE_NAME}: ${err}`);
|
|
113
254
|
process.exit(1);
|
|
114
255
|
});
|
|
@@ -116,9 +257,52 @@ function main() {
|
|
|
116
257
|
function normalizePath(fileName) {
|
|
117
258
|
return path.resolve(fileName).replace(BACKSLASH_REGEX, '/');
|
|
118
259
|
}
|
|
260
|
+
function projectPath(args) {
|
|
261
|
+
for (let i = 0, n = args.length; i < n; i++) {
|
|
262
|
+
let arg = args[i], value;
|
|
263
|
+
if (arg === '-p' || arg === '--project') {
|
|
264
|
+
value = args[i + 1];
|
|
265
|
+
}
|
|
266
|
+
else if (arg.startsWith('--project=')) {
|
|
267
|
+
value = arg.slice('--project='.length);
|
|
268
|
+
}
|
|
269
|
+
if (value !== undefined) {
|
|
270
|
+
let resolved = path.resolve(value);
|
|
271
|
+
return fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()
|
|
272
|
+
? path.join(resolved, 'tsconfig.json')
|
|
273
|
+
: resolved;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
function runAnalyze(tsconfig, program, checker) {
|
|
279
|
+
let config;
|
|
280
|
+
try {
|
|
281
|
+
config = loadConfigFromTsconfig(tsconfig);
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
console.error(`${PACKAGE_NAME}: analyze config error: ${error instanceof Error ? error.message : String(error)}`);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (!config) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
let result = program && checker ? analyzeProgram(program, checker, config) : analyze(config);
|
|
292
|
+
if (result.diagnostics.length > 0) {
|
|
293
|
+
console.error(formatDiagnostics(result.diagnostics, config.projectRoot));
|
|
294
|
+
if (config.failOnFindings) {
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
console.error(`${PACKAGE_NAME}: analyze failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
119
303
|
function passthrough() {
|
|
120
|
-
let args = process.argv.slice(2);
|
|
121
|
-
spawn(process.execPath, [
|
|
304
|
+
let args = process.argv.slice(2), tsDir = path.dirname(require.resolve('typescript/package.json'));
|
|
305
|
+
spawn(process.execPath, [path.join(tsDir, 'lib', 'tsc.js'), ...args], { stdio: 'inherit' })
|
|
122
306
|
.on('exit', async (code) => {
|
|
123
307
|
if (code === 0) {
|
|
124
308
|
code = await runTscAlias(args);
|
|
@@ -126,6 +310,13 @@ function passthrough() {
|
|
|
126
310
|
process.exit(code ?? 0);
|
|
127
311
|
});
|
|
128
312
|
}
|
|
313
|
+
function resolvePluginConfigs(tsconfig) {
|
|
314
|
+
let plugins = readPlugins(tsconfig);
|
|
315
|
+
if (!Array.isArray(plugins)) {
|
|
316
|
+
return [];
|
|
317
|
+
}
|
|
318
|
+
return plugins.filter((p) => typeof p === 'object' && p !== null && 'transform' in p);
|
|
319
|
+
}
|
|
129
320
|
function runTscAlias(args) {
|
|
130
321
|
for (let i = 0, n = args.length; i < n; i++) {
|
|
131
322
|
if (skipFlags.has(args[i])) {
|
|
@@ -137,7 +328,107 @@ function runTscAlias(args) {
|
|
|
137
328
|
child.on('exit', (code) => resolve(code ?? 0));
|
|
138
329
|
});
|
|
139
330
|
}
|
|
331
|
+
function spawnTsc(tscJs, args) {
|
|
332
|
+
return new Promise((resolve) => {
|
|
333
|
+
let child = spawn(process.execPath, [tscJs, ...args], { stdio: 'inherit' });
|
|
334
|
+
child.on('exit', (code) => resolve(code ?? 0));
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function legacyStripJsonc(text) {
|
|
338
|
+
let escaped = false, inBlockComment = false, inLineComment = false, inString = false, stripped = '';
|
|
339
|
+
for (let i = 0, n = text.length; i < n; i++) {
|
|
340
|
+
let char = text[i], next = text[i + 1];
|
|
341
|
+
if (inLineComment) {
|
|
342
|
+
if (char === '\n') {
|
|
343
|
+
inLineComment = false;
|
|
344
|
+
stripped += char;
|
|
345
|
+
}
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (inBlockComment) {
|
|
349
|
+
if (char === '*' && next === '/') {
|
|
350
|
+
inBlockComment = false;
|
|
351
|
+
i++;
|
|
352
|
+
}
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (inString) {
|
|
356
|
+
stripped += char;
|
|
357
|
+
if (escaped) {
|
|
358
|
+
escaped = false;
|
|
359
|
+
}
|
|
360
|
+
else if (char === '\\') {
|
|
361
|
+
escaped = true;
|
|
362
|
+
}
|
|
363
|
+
else if (char === '"') {
|
|
364
|
+
inString = false;
|
|
365
|
+
}
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (char === '"') {
|
|
369
|
+
inString = true;
|
|
370
|
+
stripped += char;
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (char === '/' && next === '/') {
|
|
374
|
+
inLineComment = true;
|
|
375
|
+
i++;
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
if (char === '/' && next === '*') {
|
|
379
|
+
inBlockComment = true;
|
|
380
|
+
i++;
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
stripped += char;
|
|
384
|
+
}
|
|
385
|
+
escaped = false;
|
|
386
|
+
inString = false;
|
|
387
|
+
let result = '';
|
|
388
|
+
for (let i = 0, n = stripped.length; i < n; i++) {
|
|
389
|
+
let char = stripped[i];
|
|
390
|
+
if (inString) {
|
|
391
|
+
result += char;
|
|
392
|
+
if (escaped) {
|
|
393
|
+
escaped = false;
|
|
394
|
+
}
|
|
395
|
+
else if (char === '\\') {
|
|
396
|
+
escaped = true;
|
|
397
|
+
}
|
|
398
|
+
else if (char === '"') {
|
|
399
|
+
inString = false;
|
|
400
|
+
}
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (char === '"') {
|
|
404
|
+
inString = true;
|
|
405
|
+
result += char;
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
if (char === ',') {
|
|
409
|
+
let j = i + 1;
|
|
410
|
+
while (j < n && (stripped[j] === ' ' || stripped[j] === '\n' || stripped[j] === '\r' || stripped[j] === '\t')) {
|
|
411
|
+
j++;
|
|
412
|
+
}
|
|
413
|
+
if (stripped[j] === ']' || stripped[j] === '}') {
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
result += char;
|
|
418
|
+
}
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
void legacyStripJsonc;
|
|
422
|
+
function teardown(snapshot, configPath, owned) {
|
|
423
|
+
if (owned) {
|
|
424
|
+
languageService.dispose(configPath);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (!snapshot.isDisposed()) {
|
|
428
|
+
snapshot.dispose();
|
|
429
|
+
}
|
|
430
|
+
}
|
|
140
431
|
if (process.env.VITEST === undefined) {
|
|
141
432
|
main();
|
|
142
433
|
}
|
|
143
|
-
export { build, isPlugin, loadPlugins, normalizePath, runTscAlias };
|
|
434
|
+
export { build, classifyFlags, isPlugin, loadPlugins, main, normalizePath, projectPath, resolvePluginConfigs, runTscAlias, stripJsonc };
|
package/build/compiler/ast.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import type { Range } from './types.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { Expression, Node } from 'typescript/unstable/ast';
|
|
3
|
+
declare const inRange: (ranges: Range[], start: number, end: number) => boolean;
|
|
4
|
+
declare const test: (node: Node, fn: (n: Node) => boolean) => boolean;
|
|
3
5
|
declare const _default: {
|
|
4
6
|
expression: {
|
|
5
|
-
name: (node:
|
|
7
|
+
name: (node: Expression) => string | null;
|
|
6
8
|
};
|
|
7
|
-
inRange:
|
|
9
|
+
inRange: typeof inRange;
|
|
8
10
|
property: {
|
|
9
|
-
path: (node:
|
|
11
|
+
path: (node: Expression) => string | null;
|
|
10
12
|
};
|
|
11
|
-
test:
|
|
13
|
+
test: typeof test;
|
|
12
14
|
};
|
|
13
15
|
export default _default;
|
|
14
16
|
export type { Range };
|
package/build/compiler/ast.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isIdentifier, isPropertyAccessExpression } from 'typescript/unstable/ast/is';
|
|
2
2
|
const expression = {
|
|
3
3
|
name: (node) => {
|
|
4
|
-
if (
|
|
4
|
+
if (isIdentifier(node)) {
|
|
5
5
|
return node.text;
|
|
6
6
|
}
|
|
7
|
-
if (
|
|
7
|
+
if (isPropertyAccessExpression(node)) {
|
|
8
8
|
return property.path(node);
|
|
9
9
|
}
|
|
10
10
|
return null;
|
|
@@ -22,11 +22,11 @@ const inRange = (ranges, start, end) => {
|
|
|
22
22
|
const property = {
|
|
23
23
|
path: (node) => {
|
|
24
24
|
let current = node, parts = [];
|
|
25
|
-
while (
|
|
25
|
+
while (isPropertyAccessExpression(current)) {
|
|
26
26
|
parts.push(current.name.text);
|
|
27
27
|
current = current.expression;
|
|
28
28
|
}
|
|
29
|
-
if (
|
|
29
|
+
if (isIdentifier(current)) {
|
|
30
30
|
parts.push(current.text);
|
|
31
31
|
return parts.reverse().join('.');
|
|
32
32
|
}
|
|
@@ -37,6 +37,6 @@ const test = (node, fn) => {
|
|
|
37
37
|
if (fn(node)) {
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
|
-
return !!
|
|
40
|
+
return !!node.forEachChild(child => test(child, fn) || undefined);
|
|
41
41
|
};
|
|
42
42
|
export default { expression, inRange, property, test };
|
package/build/compiler/code.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
declare
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
1
|
+
declare function code(literals: TemplateStringsArray, ...values: unknown[]): string;
|
|
2
|
+
declare namespace code {
|
|
3
|
+
var _a: (str: string) => string;
|
|
4
|
+
export { _a as escape };
|
|
5
|
+
}
|
|
5
6
|
export default code;
|
package/build/compiler/code.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
const BACKSLASH_REGEX = /\\/g;
|
|
2
|
+
const CR_REGEX = /\r/g;
|
|
3
|
+
const LINE_SEPARATOR_REGEX = /\u2028/g;
|
|
4
|
+
const NEWLINE_REGEX = /\n/g;
|
|
5
|
+
const PARAGRAPH_SEPARATOR_REGEX = /\u2029/g;
|
|
1
6
|
const SINGLE_QUOTE_REGEX = /'/g;
|
|
2
7
|
const code = (literals, ...values) => {
|
|
3
8
|
let buffer = '';
|
|
@@ -12,6 +17,12 @@ const code = (literals, ...values) => {
|
|
|
12
17
|
return buffer;
|
|
13
18
|
};
|
|
14
19
|
code.escape = (str) => {
|
|
15
|
-
return str
|
|
20
|
+
return str
|
|
21
|
+
.replace(BACKSLASH_REGEX, '\\\\')
|
|
22
|
+
.replace(SINGLE_QUOTE_REGEX, "\\'")
|
|
23
|
+
.replace(NEWLINE_REGEX, '\\n')
|
|
24
|
+
.replace(CR_REGEX, '\\r')
|
|
25
|
+
.replace(LINE_SEPARATOR_REGEX, '\\u2028')
|
|
26
|
+
.replace(PARAGRAPH_SEPARATOR_REGEX, '\\u2029');
|
|
16
27
|
};
|
|
17
28
|
export default code;
|
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
import type { SourceFile } from 'typescript/unstable/ast';
|
|
2
|
+
import type { Checker, Program } from 'typescript/unstable/sync';
|
|
1
3
|
import type { Plugin, SharedContext } from './types.js';
|
|
2
|
-
import {
|
|
4
|
+
import type { OffsetAnchor, PositionMapping } from './sourcemap.js';
|
|
3
5
|
type CoordinatorResult = {
|
|
4
6
|
changed: boolean;
|
|
5
7
|
code: string;
|
|
6
|
-
|
|
8
|
+
map: PositionMapping;
|
|
7
9
|
};
|
|
8
|
-
declare const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
declare const transform: (plugins: Plugin[], code: string, file: SourceFile, project: {
|
|
11
|
+
checker: Checker;
|
|
12
|
+
configPath?: string;
|
|
13
|
+
program: Program;
|
|
14
|
+
}, root: string, shared: SharedContext) => {
|
|
15
|
+
changed: boolean;
|
|
16
|
+
code: string;
|
|
17
|
+
map: {
|
|
18
|
+
generations: OffsetAnchor[][];
|
|
13
19
|
};
|
|
14
20
|
};
|
|
21
|
+
declare const _default: {
|
|
22
|
+
transform: typeof transform;
|
|
23
|
+
};
|
|
15
24
|
export default _default;
|
|
16
25
|
export type { CoordinatorResult };
|