ttsc 0.8.1 → 0.10.0
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 +39 -68
- package/cmd/ttsc/api_compile.go +109 -115
- package/cmd/ttsc/api_transform.go +54 -51
- package/cmd/ttsc/main.go +103 -121
- package/driver/program.go +30 -2
- package/driver/rewrite.go +126 -9
- package/go.mod +2 -0
- package/lib/TtscCompiler.js +28 -46
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.js +8 -38
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.js +36 -63
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/project/readProjectConfig.js +108 -60
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +15 -45
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.js +10 -40
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +21 -48
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.js +14 -44
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +7 -0
- package/lib/compiler/internal/runBuild.js +47 -66
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.js +18 -48
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +41 -75
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +7 -37
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +48 -69
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +53 -64
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +328 -57
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +8 -0
- package/lib/plugin/internal/buildSourcePlugin.js +287 -139
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +2 -0
- package/lib/plugin/internal/loadProjectPlugins.js +197 -9
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerContext.d.ts +16 -3
- package/lib/structures/ITtscCompilerResult.d.ts +4 -0
- package/lib/structures/ITtscCompilerTransformation.d.ts +2 -0
- package/lib/structures/ITtscPluginFactoryContext.d.ts +6 -3
- package/lib/structures/ITtscProjectPluginConfig.d.ts +8 -7
- package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +2 -0
- package/lib/structures/internal/ITtscProjectLocatorOptions.d.ts +2 -0
- package/lib/structures/internal/TtscCommonOptions.d.ts +2 -0
- package/package.json +9 -14
- package/shim/diagnosticwriter/lint.go +8 -0
- package/shim/printer/go.mod +5 -0
- package/shim/printer/shim.go +23 -0
- package/src/TtscCompiler.ts +20 -5
- package/src/compiler/internal/buildNativeCompiler.ts +2 -2
- package/src/compiler/internal/compileProjectInMemory.ts +21 -16
- package/src/compiler/internal/project/readProjectConfig.ts +134 -35
- package/src/compiler/internal/project/resolveProjectConfig.ts +2 -2
- package/src/compiler/internal/resolveBinary.ts +2 -2
- package/src/compiler/internal/resolveEmittedJavaScript.ts +11 -7
- package/src/compiler/internal/resolveTsgo.ts +2 -2
- package/src/compiler/internal/runBuild.ts +34 -21
- package/src/compiler/internal/runSingleFileEmit.ts +3 -3
- package/src/compiler/internal/transformProjectInMemory.ts +37 -37
- package/src/launcher/internal/getCompilerVersionText.ts +2 -2
- package/src/launcher/internal/prepareExecution.ts +14 -4
- package/src/launcher/internal/runTtsc.ts +30 -4
- package/src/launcher/internal/runTtsx.ts +377 -26
- package/src/plugin/internal/buildSourcePlugin.ts +321 -50
- package/src/plugin/internal/loadProjectPlugins.ts +266 -10
- package/src/structures/ITtscCompilerContext.ts +17 -3
- package/src/structures/ITtscCompilerResult.ts +5 -0
- package/src/structures/ITtscCompilerTransformation.ts +3 -0
- package/src/structures/ITtscPluginFactoryContext.ts +6 -3
- package/src/structures/ITtscProjectPluginConfig.ts +8 -7
- package/src/structures/internal/ITtscParsedProjectConfig.ts +2 -0
- package/src/structures/internal/ITtscProjectLocatorOptions.ts +2 -0
- package/src/structures/internal/TtscCommonOptions.ts +2 -0
- package/utility/host.go +622 -20
- package/cmd/ttsc/main_test.go +0 -288
- package/test/compiler.test.ts +0 -422
- package/test/platform.test.ts +0 -12
- package/test/project.test.ts +0 -197
- package/test/source-build.test.ts +0 -45
- package/test/tsgo.test.ts +0 -69
package/src/TtscCompiler.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
import { compileProjectInMemory } from "./compiler/internal/compileProjectInMemory";
|
|
5
5
|
import { resolveProjectConfig } from "./compiler/internal/project/resolveProjectConfig";
|
|
@@ -66,6 +66,7 @@ export class TtscCompiler {
|
|
|
66
66
|
cacheDir: this.resolvePluginCacheDir(),
|
|
67
67
|
cwd: execution.cwd,
|
|
68
68
|
entries: this.context.plugins,
|
|
69
|
+
projectRoot: execution.projectRoot,
|
|
69
70
|
tsconfig: execution.tsconfig,
|
|
70
71
|
});
|
|
71
72
|
return loaded.nativePlugins.map((plugin) => plugin.binary);
|
|
@@ -161,7 +162,9 @@ export class TtscCompiler {
|
|
|
161
162
|
});
|
|
162
163
|
return {
|
|
163
164
|
cwd,
|
|
164
|
-
projectRoot:
|
|
165
|
+
projectRoot: this.context.projectRoot
|
|
166
|
+
? path.resolve(cwd, this.context.projectRoot)
|
|
167
|
+
: path.dirname(tsconfig),
|
|
165
168
|
tsconfig,
|
|
166
169
|
};
|
|
167
170
|
}
|
|
@@ -243,8 +246,11 @@ function runTransformation(
|
|
|
243
246
|
|
|
244
247
|
function toCompilerResult(project: ProjectResult): ITtscCompilerResult {
|
|
245
248
|
const { output, result } = project;
|
|
246
|
-
if (result.status === 0 && result.diagnostics
|
|
249
|
+
if (result.status === 0 && !hasErrorDiagnostics(result.diagnostics)) {
|
|
247
250
|
return {
|
|
251
|
+
...(result.diagnostics.length === 0
|
|
252
|
+
? {}
|
|
253
|
+
: { diagnostics: result.diagnostics }),
|
|
248
254
|
output,
|
|
249
255
|
type: "success",
|
|
250
256
|
};
|
|
@@ -277,8 +283,11 @@ function toCompilerTransformation(
|
|
|
277
283
|
project: ProjectTransformation,
|
|
278
284
|
): ITtscCompilerTransformation {
|
|
279
285
|
const { result, typescript } = project;
|
|
280
|
-
if (result.status === 0 && result.diagnostics
|
|
286
|
+
if (result.status === 0 && !hasErrorDiagnostics(result.diagnostics)) {
|
|
281
287
|
return {
|
|
288
|
+
...(result.diagnostics.length === 0
|
|
289
|
+
? {}
|
|
290
|
+
: { diagnostics: result.diagnostics }),
|
|
282
291
|
type: "success",
|
|
283
292
|
typescript,
|
|
284
293
|
};
|
|
@@ -293,6 +302,12 @@ function toCompilerTransformation(
|
|
|
293
302
|
};
|
|
294
303
|
}
|
|
295
304
|
|
|
305
|
+
function hasErrorDiagnostics(
|
|
306
|
+
diagnostics: readonly ITtscCompilerDiagnostic[],
|
|
307
|
+
): boolean {
|
|
308
|
+
return diagnostics.some((diagnostic) => diagnostic.category === "error");
|
|
309
|
+
}
|
|
310
|
+
|
|
296
311
|
function normalizeError(error: unknown): unknown {
|
|
297
312
|
if (!(error instanceof Error)) {
|
|
298
313
|
return error;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
5
|
|
|
6
|
+
import { hasProjectPluginEntries } from "../../plugin/internal/loadProjectPlugins";
|
|
6
7
|
import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
|
|
7
8
|
import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
|
|
8
|
-
import type { ITtscProjectPluginConfig } from "../../structures/ITtscProjectPluginConfig";
|
|
9
9
|
import type { ITtscParsedProjectConfig } from "../../structures/internal/ITtscParsedProjectConfig";
|
|
10
10
|
import type { TtscBuildResult } from "../../structures/internal/TtscBuildResult";
|
|
11
11
|
import { buildNativeCompiler } from "./buildNativeCompiler";
|
|
@@ -20,22 +20,23 @@ export function compileProjectInMemory(options: ITtscCompilerContext): {
|
|
|
20
20
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
21
21
|
const project = readProjectConfig({
|
|
22
22
|
cwd,
|
|
23
|
+
projectRoot: options.projectRoot,
|
|
23
24
|
tsconfig: options.tsconfig,
|
|
24
25
|
});
|
|
25
|
-
if (
|
|
26
|
+
if (hasConfiguredPlugins(options, project)) {
|
|
26
27
|
return compileProjectWithPlugins(options, cwd, project);
|
|
27
28
|
}
|
|
28
29
|
const tsconfig = project.path;
|
|
29
30
|
const binary = buildNativeCompiler({
|
|
30
|
-
cacheBaseDir:
|
|
31
|
+
cacheBaseDir: project.root,
|
|
31
32
|
cacheDir: options.cacheDir,
|
|
32
33
|
packageRoot: packageRootDir(),
|
|
33
34
|
});
|
|
34
35
|
const res = spawnSync(
|
|
35
36
|
binary,
|
|
36
|
-
["api-compile", "--cwd",
|
|
37
|
+
["api-compile", "--cwd", project.root, "--tsconfig", tsconfig],
|
|
37
38
|
{
|
|
38
|
-
cwd:
|
|
39
|
+
cwd: project.root,
|
|
39
40
|
encoding: "utf8",
|
|
40
41
|
env: { ...process.env, ...options.env },
|
|
41
42
|
maxBuffer: 1024 * 1024 * 256,
|
|
@@ -60,15 +61,11 @@ export function compileProjectInMemory(options: ITtscCompilerContext): {
|
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
function
|
|
64
|
+
function hasConfiguredPlugins(
|
|
64
65
|
options: ITtscCompilerContext,
|
|
65
66
|
project: ITtscParsedProjectConfig,
|
|
66
|
-
):
|
|
67
|
-
|
|
68
|
-
return [];
|
|
69
|
-
}
|
|
70
|
-
const entries = options.plugins ?? project.compilerOptions.plugins;
|
|
71
|
-
return entries.filter((entry) => entry.enabled !== false);
|
|
67
|
+
): boolean {
|
|
68
|
+
return hasProjectPluginEntries(project, options.plugins);
|
|
72
69
|
}
|
|
73
70
|
|
|
74
71
|
function compileProjectWithPlugins(
|
|
@@ -109,13 +106,21 @@ function outputKeyMapper(
|
|
|
109
106
|
return (relativePath) => relativePath;
|
|
110
107
|
}
|
|
111
108
|
const relativeOutDir = path.relative(project.root, outDir);
|
|
112
|
-
if (relativeOutDir !== "" && !relativeOutDir
|
|
109
|
+
if (relativeOutDir !== "" && !isOutsideRelativePath(relativeOutDir)) {
|
|
113
110
|
const prefix = pathToKey(relativeOutDir);
|
|
114
111
|
return (relativePath) => path.posix.join(prefix, relativePath);
|
|
115
112
|
}
|
|
116
113
|
return (relativePath) => pathToKey(path.join(outDir, relativePath));
|
|
117
114
|
}
|
|
118
115
|
|
|
116
|
+
function isOutsideRelativePath(relative: string): boolean {
|
|
117
|
+
return (
|
|
118
|
+
relative === ".." ||
|
|
119
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
120
|
+
path.isAbsolute(relative)
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
119
124
|
function readOutputDirectory(
|
|
120
125
|
directory: string,
|
|
121
126
|
keyOf: (relativePath: string) => string,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import type { ITtscProjectPluginConfig } from "../../../structures/ITtscProjectPluginConfig";
|
|
6
6
|
import type { ITtscParsedProjectConfig } from "../../../structures/internal/ITtscParsedProjectConfig";
|
|
@@ -8,12 +8,25 @@ import type { ITtscProjectLocatorOptions } from "../../../structures/internal/IT
|
|
|
8
8
|
|
|
9
9
|
import { resolveProjectConfig } from "./resolveProjectConfig";
|
|
10
10
|
|
|
11
|
+
const PATH_OPTIONS = new Set(["baseUrl", "declarationDir", "rootDir"]);
|
|
12
|
+
|
|
13
|
+
type ResolvedCompilerOptions = {
|
|
14
|
+
options: Record<string, unknown>;
|
|
15
|
+
optionBaseDirs: Record<string, string>;
|
|
16
|
+
outDir?: string;
|
|
17
|
+
pluginBaseDirs: string[];
|
|
18
|
+
pluginsDeclared: boolean;
|
|
19
|
+
plugins: ITtscProjectPluginConfig[];
|
|
20
|
+
};
|
|
21
|
+
|
|
11
22
|
/** Read the resolved project config subset used by ttsc. */
|
|
12
23
|
export function readProjectConfig(
|
|
13
24
|
opts: ITtscProjectLocatorOptions = {},
|
|
14
25
|
): ITtscParsedProjectConfig {
|
|
15
26
|
const tsconfig = resolveProjectConfig(opts);
|
|
16
|
-
const root =
|
|
27
|
+
const root = opts.projectRoot
|
|
28
|
+
? path.resolve(opts.cwd ?? process.cwd(), opts.projectRoot)
|
|
29
|
+
: path.dirname(tsconfig);
|
|
17
30
|
const compilerOptions = readResolvedCompilerOptions(tsconfig);
|
|
18
31
|
return {
|
|
19
32
|
compilerOptions: {
|
|
@@ -22,6 +35,7 @@ export function readProjectConfig(
|
|
|
22
35
|
plugins: compilerOptions.plugins,
|
|
23
36
|
},
|
|
24
37
|
path: tsconfig,
|
|
38
|
+
pluginBaseDirs: compilerOptions.pluginBaseDirs,
|
|
25
39
|
root,
|
|
26
40
|
};
|
|
27
41
|
}
|
|
@@ -47,46 +61,131 @@ function resolveAbsolutePath(cwd: string, target: string): string {
|
|
|
47
61
|
function readResolvedCompilerOptions(
|
|
48
62
|
tsconfig: string,
|
|
49
63
|
seen: Set<string> = new Set(),
|
|
50
|
-
): {
|
|
51
|
-
options: Record<string, unknown>;
|
|
52
|
-
outDir?: string;
|
|
53
|
-
plugins: ITtscProjectPluginConfig[];
|
|
54
|
-
} {
|
|
64
|
+
): ResolvedCompilerOptions {
|
|
55
65
|
const canonical = resolveRealPath(tsconfig);
|
|
56
66
|
if (seen.has(canonical)) {
|
|
57
67
|
throw new Error(`ttsc: circular tsconfig extends detected: ${canonical}`);
|
|
58
68
|
}
|
|
59
69
|
seen.add(canonical);
|
|
70
|
+
try {
|
|
71
|
+
const parsed = parseJsonc(fs.readFileSync(canonical, "utf8")) as {
|
|
72
|
+
extends?: unknown;
|
|
73
|
+
compilerOptions?: Record<string, unknown> & {
|
|
74
|
+
outDir?: unknown;
|
|
75
|
+
plugins?: unknown;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const own = parsed.compilerOptions;
|
|
79
|
+
const base = resolveBaseCompilerOptions(canonical, parsed.extends, seen);
|
|
80
|
+
const ownBaseDir = path.dirname(canonical);
|
|
81
|
+
const ownOptionBaseDirs =
|
|
82
|
+
own === undefined
|
|
83
|
+
? {}
|
|
84
|
+
: Object.fromEntries(
|
|
85
|
+
Object.keys(own).map((key) => [key, ownBaseDir] as const),
|
|
86
|
+
);
|
|
87
|
+
const optionBaseDirs = {
|
|
88
|
+
...base.optionBaseDirs,
|
|
89
|
+
...ownOptionBaseDirs,
|
|
90
|
+
};
|
|
91
|
+
const options = resolvePathOptions(
|
|
92
|
+
{
|
|
93
|
+
...base.options,
|
|
94
|
+
...(own ?? {}),
|
|
95
|
+
},
|
|
96
|
+
optionBaseDirs,
|
|
97
|
+
);
|
|
98
|
+
const ownPlugins = own?.plugins;
|
|
99
|
+
const pluginsDeclared = Array.isArray(ownPlugins);
|
|
100
|
+
const plugins = pluginsDeclared
|
|
101
|
+
? ownPlugins.filter(isProjectPluginConfig)
|
|
102
|
+
: base.plugins;
|
|
103
|
+
return {
|
|
104
|
+
optionBaseDirs,
|
|
105
|
+
options,
|
|
106
|
+
outDir:
|
|
107
|
+
typeof own?.outDir === "string"
|
|
108
|
+
? resolveAbsolutePath(ownBaseDir, own.outDir)
|
|
109
|
+
: base.outDir,
|
|
110
|
+
pluginBaseDirs: pluginsDeclared
|
|
111
|
+
? plugins.map(() => ownBaseDir)
|
|
112
|
+
: base.pluginBaseDirs,
|
|
113
|
+
pluginsDeclared: pluginsDeclared || base.pluginsDeclared,
|
|
114
|
+
plugins,
|
|
115
|
+
};
|
|
116
|
+
} finally {
|
|
117
|
+
seen.delete(canonical);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
60
120
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
121
|
+
function resolveBaseCompilerOptions(
|
|
122
|
+
tsconfig: string,
|
|
123
|
+
extended: unknown,
|
|
124
|
+
seen: Set<string>,
|
|
125
|
+
): ResolvedCompilerOptions {
|
|
126
|
+
if (typeof extended === "string") {
|
|
127
|
+
return readResolvedCompilerOptions(
|
|
128
|
+
resolveExtendsConfig(tsconfig, extended),
|
|
129
|
+
seen,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (!Array.isArray(extended)) {
|
|
133
|
+
return {
|
|
134
|
+
optionBaseDirs: {},
|
|
135
|
+
options: {},
|
|
136
|
+
pluginBaseDirs: [],
|
|
137
|
+
pluginsDeclared: false,
|
|
138
|
+
plugins: [],
|
|
66
139
|
};
|
|
140
|
+
}
|
|
141
|
+
let merged: ResolvedCompilerOptions = {
|
|
142
|
+
optionBaseDirs: {},
|
|
143
|
+
options: {},
|
|
144
|
+
pluginBaseDirs: [],
|
|
145
|
+
pluginsDeclared: false,
|
|
146
|
+
plugins: [],
|
|
67
147
|
};
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
148
|
+
for (const specifier of extended) {
|
|
149
|
+
if (typeof specifier !== "string") {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const current = readResolvedCompilerOptions(
|
|
153
|
+
resolveExtendsConfig(tsconfig, specifier),
|
|
154
|
+
seen,
|
|
155
|
+
);
|
|
156
|
+
merged = {
|
|
157
|
+
optionBaseDirs: {
|
|
158
|
+
...merged.optionBaseDirs,
|
|
159
|
+
...current.optionBaseDirs,
|
|
160
|
+
},
|
|
161
|
+
options: {
|
|
162
|
+
...merged.options,
|
|
163
|
+
...current.options,
|
|
164
|
+
},
|
|
165
|
+
outDir: current.outDir ?? merged.outDir,
|
|
166
|
+
pluginBaseDirs: current.pluginsDeclared
|
|
167
|
+
? current.pluginBaseDirs
|
|
168
|
+
: merged.pluginBaseDirs,
|
|
169
|
+
plugins: current.pluginsDeclared ? current.plugins : merged.plugins,
|
|
170
|
+
pluginsDeclared: merged.pluginsDeclared || current.pluginsDeclared,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return merged;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function resolvePathOptions(
|
|
177
|
+
options: Record<string, unknown>,
|
|
178
|
+
baseDirs: Record<string, string>,
|
|
179
|
+
): Record<string, unknown> {
|
|
180
|
+
const resolved = { ...options };
|
|
181
|
+
for (const key of PATH_OPTIONS) {
|
|
182
|
+
const value = resolved[key];
|
|
183
|
+
const baseDir = baseDirs[key];
|
|
184
|
+
if (typeof value === "string" && baseDir !== undefined) {
|
|
185
|
+
resolved[key] = resolveAbsolutePath(baseDir, value);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return resolved;
|
|
90
189
|
}
|
|
91
190
|
|
|
92
191
|
function resolveExtendsConfig(tsconfig: string, specifier: string): string {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
/** Locate the JavaScript file emitted for a TypeScript source file. */
|
|
5
5
|
export function resolveEmittedJavaScript(options: {
|
|
@@ -37,11 +37,7 @@ function resolveExactEmittedFile(
|
|
|
37
37
|
sourceFile: string,
|
|
38
38
|
): string | null {
|
|
39
39
|
const relative = path.relative(projectRoot, sourceFile);
|
|
40
|
-
if (
|
|
41
|
-
relative === "" ||
|
|
42
|
-
relative.startsWith("..") ||
|
|
43
|
-
path.isAbsolute(relative)
|
|
44
|
-
) {
|
|
40
|
+
if (relative === "" || isOutsideRelativePath(relative)) {
|
|
45
41
|
return null;
|
|
46
42
|
}
|
|
47
43
|
return path.resolve(
|
|
@@ -87,6 +83,14 @@ function sharedSourceStemSegments(outPath: string, srcPath: string): number {
|
|
|
87
83
|
return shared;
|
|
88
84
|
}
|
|
89
85
|
|
|
86
|
+
function isOutsideRelativePath(relative: string): boolean {
|
|
87
|
+
return (
|
|
88
|
+
relative === ".." ||
|
|
89
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
90
|
+
path.isAbsolute(relative)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
90
94
|
function emittedJavaScriptExtension(filename: string): string {
|
|
91
95
|
switch (path.extname(filename).toLowerCase()) {
|
|
92
96
|
case ".mts":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
/** Resolve the consumer project's TypeScript-Go preview binary. */
|
|
6
6
|
export function resolveTsgo(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
5
|
|
|
6
6
|
import { loadProjectPlugins } from "../../plugin/internal/loadProjectPlugins";
|
|
7
7
|
import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
|
|
@@ -112,10 +112,10 @@ export function runBuild(
|
|
|
112
112
|
buildWithNativeCompilerPlugins(options, execution, compilers),
|
|
113
113
|
);
|
|
114
114
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
return appendBuildOutput(
|
|
116
|
+
checked,
|
|
117
|
+
runTsgo(execution, ["--noEmit"], options),
|
|
118
|
+
);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
let result: TtscBuildResult;
|
|
@@ -126,14 +126,10 @@ export function runBuild(
|
|
|
126
126
|
buildWithNativeCompilerPlugins(options, execution, compilers),
|
|
127
127
|
);
|
|
128
128
|
} else {
|
|
129
|
-
if (
|
|
130
|
-
checked.stdout === "" &&
|
|
131
|
-
checked.stderr === "" &&
|
|
132
|
-
options.skipDiagnosticsCheck !== true
|
|
133
|
-
) {
|
|
129
|
+
if (options.skipDiagnosticsCheck !== true) {
|
|
134
130
|
const tsgoChecked = runTsgo(execution, ["--noEmit"], options);
|
|
135
131
|
if (tsgoChecked.status !== 0) {
|
|
136
|
-
return tsgoChecked;
|
|
132
|
+
return appendBuildOutput(checked, tsgoChecked);
|
|
137
133
|
}
|
|
138
134
|
}
|
|
139
135
|
const args = createTsgoBuildArgs(execution, options, {
|
|
@@ -201,7 +197,7 @@ function runTsgo(
|
|
|
201
197
|
res.error.message,
|
|
202
198
|
);
|
|
203
199
|
}
|
|
204
|
-
return
|
|
200
|
+
return normalizeBuildOutput(
|
|
205
201
|
{
|
|
206
202
|
status: res.status ?? 1,
|
|
207
203
|
stdout: outputText(res.stdout),
|
|
@@ -238,7 +234,7 @@ function runTsgoBuild(
|
|
|
238
234
|
if (emittedFiles.length !== 0) {
|
|
239
235
|
result.stdout = stripEmittedFileLines(result.stdout);
|
|
240
236
|
}
|
|
241
|
-
return
|
|
237
|
+
return normalizeBuildOutput(
|
|
242
238
|
{ ...result, emittedFiles },
|
|
243
239
|
execution.projectRoot,
|
|
244
240
|
);
|
|
@@ -374,7 +370,7 @@ function runNativePluginCommand(
|
|
|
374
370
|
`${label}: failed to spawn ${plugin.binary}: ${res.error.message}`,
|
|
375
371
|
);
|
|
376
372
|
}
|
|
377
|
-
return
|
|
373
|
+
return normalizeBuildOutput(
|
|
378
374
|
{
|
|
379
375
|
status: res.status ?? 1,
|
|
380
376
|
stdout: outputText(res.stdout),
|
|
@@ -384,11 +380,11 @@ function runNativePluginCommand(
|
|
|
384
380
|
);
|
|
385
381
|
}
|
|
386
382
|
|
|
387
|
-
function appendBuildOutput(
|
|
383
|
+
export function appendBuildOutput(
|
|
388
384
|
left: TtscBuildResult,
|
|
389
385
|
right: TtscBuildResult,
|
|
390
386
|
): TtscBuildResult {
|
|
391
|
-
return
|
|
387
|
+
return normalizeBuildOutput({
|
|
392
388
|
diagnostics: [...left.diagnostics, ...right.diagnostics],
|
|
393
389
|
emittedFiles:
|
|
394
390
|
right.emittedFiles !== undefined ? right.emittedFiles : left.emittedFiles,
|
|
@@ -461,7 +457,9 @@ function resolveExecutionContext(
|
|
|
461
457
|
cwd,
|
|
462
458
|
tsconfig: options.tsconfig,
|
|
463
459
|
});
|
|
464
|
-
const projectRoot =
|
|
460
|
+
const projectRoot = options.projectRoot
|
|
461
|
+
? path.resolve(cwd, options.projectRoot)
|
|
462
|
+
: path.dirname(tsconfig);
|
|
465
463
|
const tsgo = resolveTsgo({ ...options, cwd: projectRoot });
|
|
466
464
|
const fallbackBinary = resolveBinary(options);
|
|
467
465
|
const loaded = loadProjectPlugins({
|
|
@@ -469,6 +467,7 @@ function resolveExecutionContext(
|
|
|
469
467
|
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
470
468
|
cwd,
|
|
471
469
|
entries: options.plugins,
|
|
470
|
+
projectRoot,
|
|
472
471
|
tsconfig,
|
|
473
472
|
});
|
|
474
473
|
return {
|
|
@@ -503,7 +502,7 @@ type PartialBuildResult = Omit<TtscBuildResult, "diagnostics"> & {
|
|
|
503
502
|
diagnostics?: ITtscCompilerDiagnostic[];
|
|
504
503
|
};
|
|
505
504
|
|
|
506
|
-
function
|
|
505
|
+
export function normalizeBuildOutput(
|
|
507
506
|
result: PartialBuildResult,
|
|
508
507
|
cwd?: string,
|
|
509
508
|
): TtscBuildResult {
|
|
@@ -557,6 +556,20 @@ function parseDiagnosticLine(
|
|
|
557
556
|
line: string,
|
|
558
557
|
cwd: string | undefined,
|
|
559
558
|
): ITtscCompilerDiagnostic | null {
|
|
559
|
+
const colonMatch = line.match(
|
|
560
|
+
/^(.+):(\d+):(\d+)\s+-\s+(error|warning|suggestion|message)\s+([A-Z]+)?(\d+|[A-Z][A-Z0-9_-]*):\s+(.+)$/i,
|
|
561
|
+
);
|
|
562
|
+
if (colonMatch) {
|
|
563
|
+
return {
|
|
564
|
+
category: normalizeDiagnosticCategory(colonMatch[4]!),
|
|
565
|
+
character: Number(colonMatch[3]),
|
|
566
|
+
code: normalizeDiagnosticCode(colonMatch[6]!),
|
|
567
|
+
file: normalizeDiagnosticFile(colonMatch[1]!, cwd),
|
|
568
|
+
line: Number(colonMatch[2]),
|
|
569
|
+
messageText: colonMatch[7]!,
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
|
|
560
573
|
const fileMatch = line.match(
|
|
561
574
|
/^(.+?)\((\d+),(\d+)\):\s+(error|warning|suggestion|message)\s+([A-Z]+)?(\d+|[A-Z][A-Z0-9_-]*):\s+(.+)$/i,
|
|
562
575
|
);
|
|
@@ -611,5 +624,5 @@ function normalizeDiagnosticCode(value: string): number | string {
|
|
|
611
624
|
}
|
|
612
625
|
|
|
613
626
|
function stripAnsi(text: string): string {
|
|
614
|
-
return text.replace(/\x1b\[[0-9
|
|
627
|
+
return text.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, "");
|
|
615
628
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import type { TtscSingleFileEmitOptions } from "../../structures/internal/TtscSingleFileEmitOptions";
|
|
6
6
|
import { resolveProjectConfig } from "./project/resolveProjectConfig";
|