ttsc 0.12.3 → 0.13.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/cmd/platform/main.go +9 -0
- package/cmd/ttsc/api_compile.go +122 -101
- package/cmd/ttsc/api_compile_branches_test.go +55 -57
- package/cmd/ttsc/api_transform.go +67 -49
- package/cmd/ttsc/api_transform_branches_test.go +30 -32
- package/cmd/ttsc/build.go +141 -108
- package/cmd/ttsc/build_branches_test.go +95 -97
- package/cmd/ttsc/filter.go +70 -0
- package/cmd/ttsc/filter_strips_unknown_forwarded_flag_test.go +61 -0
- package/cmd/ttsc/flags_gen.go +30 -0
- package/cmd/ttsc/helpers_test.go +39 -28
- package/cmd/ttsc/main.go +111 -104
- package/cmd/ttsc/main_alias_branches_test.go +21 -23
- package/cmd/ttscserver/main.go +96 -90
- package/cmd/ttscserver/run_lsp_prefers_tsgo_flag_test.go +22 -22
- package/cmd/ttscserver/run_lsp_reports_server_error_test.go +22 -22
- package/cmd/ttscserver/run_lsp_uses_tsgo_environment_test.go +23 -23
- package/cmd/utility-host/main.go +30 -23
- package/driver/lsp.go +53 -7
- package/driver/plugins.go +88 -72
- package/driver/program.go +464 -340
- package/driver/rewrite.go +477 -380
- package/internal/lspserver/lsp_envelope.go +64 -64
- package/internal/lspserver/lsp_frame.go +60 -60
- package/internal/lspserver/lsp_plugin.go +57 -57
- package/internal/lspserver/lsp_proxy.go +265 -251
- package/internal/lspserver/lsp_server.go +155 -144
- package/lib/TtscCompiler.d.ts +7 -0
- package/lib/TtscCompiler.js +7 -0
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.d.ts +11 -1
- package/lib/compiler/internal/buildNativeCompiler.js +23 -3
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.d.ts +9 -0
- package/lib/compiler/internal/compileProjectInMemory.js +36 -21
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/paths.d.ts +27 -0
- package/lib/compiler/internal/paths.js +70 -0
- package/lib/compiler/internal/paths.js.map +1 -0
- package/lib/compiler/internal/project/readProjectConfig.d.ts +9 -1
- package/lib/compiler/internal/project/readProjectConfig.js +80 -1
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.d.ts +13 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +42 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.d.ts +9 -1
- package/lib/compiler/internal/resolveBinary.js +17 -1
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.d.ts +16 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +42 -10
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.d.ts +21 -1
- package/lib/compiler/internal/resolveTsgo.js +23 -1
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +24 -4
- package/lib/compiler/internal/runBuild.js +355 -93
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.d.ts +10 -1
- package/lib/compiler/internal/runSingleFileEmit.js +14 -1
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/sharedHostHelpers.d.ts +5 -0
- package/lib/compiler/internal/sharedHostHelpers.js +6 -2
- package/lib/compiler/internal/sharedHostHelpers.js.map +1 -1
- package/lib/compiler/internal/spawnNative.d.ts +21 -0
- package/lib/compiler/internal/spawnNative.js +59 -0
- package/lib/compiler/internal/spawnNative.js.map +1 -0
- package/lib/compiler/internal/transformProjectInMemory.d.ts +15 -1
- package/lib/compiler/internal/transformProjectInMemory.js +57 -61
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/flags/parser.d.ts +63 -0
- package/lib/flags/parser.js +254 -0
- package/lib/flags/parser.js.map +1 -0
- package/lib/flags/schema.d.ts +147 -0
- package/lib/flags/schema.js +405 -0
- package/lib/flags/schema.js.map +1 -0
- package/lib/launcher/internal/getCompilerVersionText.js +7 -0
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +35 -0
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/resolveCacheDir.d.ts +9 -0
- package/lib/launcher/internal/resolveCacheDir.js +22 -0
- package/lib/launcher/internal/resolveCacheDir.js.map +1 -0
- package/lib/launcher/internal/resolveTtscserverBinary.js +2 -0
- package/lib/launcher/internal/resolveTtscserverBinary.js.map +1 -1
- package/lib/launcher/internal/runTtsc.d.ts +10 -0
- package/lib/launcher/internal/runTtsc.js +90 -153
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtscserver.js +10 -35
- package/lib/launcher/internal/runTtscserver.js.map +1 -1
- package/lib/launcher/internal/runTtsx.d.ts +8 -0
- package/lib/launcher/internal/runTtsx.js +137 -79
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +38 -0
- package/lib/plugin/internal/buildSourcePlugin.js +40 -17
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +26 -0
- package/lib/plugin/internal/loadProjectPlugins.js +90 -41
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerTransformation.d.ts +15 -2
- package/lib/structures/ITtscPlugin.d.ts +24 -0
- package/lib/structures/ITtscPluginCapabilities.d.ts +29 -0
- package/lib/structures/ITtscPluginCapabilities.js +3 -0
- package/lib/structures/ITtscPluginCapabilities.js.map +1 -0
- package/lib/structures/index.d.ts +1 -0
- package/lib/structures/index.js +1 -0
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/internal/ITtscLoadedNativePlugin.d.ts +5 -0
- package/lib/structures/internal/TtscCommonOptions.d.ts +19 -0
- package/lib/structures/internal/TtscSingleFileEmitOptions.d.ts +0 -2
- package/package.json +9 -9
- package/shim/ast/shim.go +24 -0
- package/shim/checker/shim.go +35 -0
- package/shim/core/shim.go +17 -0
- package/shim/diagnosticwriter/shim.go +4 -0
- package/shim/lsp/shim.go +3 -3
- package/shim/printer/shim.go +20 -0
- package/src/TtscCompiler.ts +7 -0
- package/src/compiler/internal/buildNativeCompiler.ts +23 -3
- package/src/compiler/internal/compileProjectInMemory.ts +34 -25
- package/src/compiler/internal/paths.ts +68 -0
- package/src/compiler/internal/project/readProjectConfig.ts +86 -1
- package/src/compiler/internal/project/resolveProjectConfig.ts +44 -1
- package/src/compiler/internal/resolveBinary.ts +17 -1
- package/src/compiler/internal/resolveEmittedJavaScript.ts +43 -12
- package/src/compiler/internal/resolveTsgo.ts +29 -1
- package/src/compiler/internal/runBuild.ts +398 -112
- package/src/compiler/internal/runSingleFileEmit.ts +14 -1
- package/src/compiler/internal/sharedHostHelpers.ts +7 -7
- package/src/compiler/internal/spawnNative.ts +64 -0
- package/src/compiler/internal/transformProjectInMemory.ts +47 -67
- package/src/flags/parser.ts +367 -0
- package/src/flags/schema.ts +570 -0
- package/src/launcher/internal/getCompilerVersionText.ts +7 -0
- package/src/launcher/internal/prepareExecution.ts +35 -0
- package/src/launcher/internal/resolveCacheDir.ts +19 -0
- package/src/launcher/internal/resolveTtscserverBinary.ts +2 -0
- package/src/launcher/internal/runTtsc.ts +97 -143
- package/src/launcher/internal/runTtscserver.ts +9 -1
- package/src/launcher/internal/runTtsx.ts +149 -82
- package/src/plugin/internal/buildSourcePlugin.ts +40 -14
- package/src/plugin/internal/loadProjectPlugins.ts +116 -45
- package/src/structures/ITtscCompilerTransformation.ts +15 -2
- package/src/structures/ITtscPlugin.ts +26 -1
- package/src/structures/ITtscPluginCapabilities.ts +29 -0
- package/src/structures/index.ts +1 -0
- package/src/structures/internal/ITtscLoadedNativePlugin.ts +5 -0
- package/src/structures/internal/TtscCommonOptions.ts +19 -0
- package/src/structures/internal/TtscSingleFileEmitOptions.ts +0 -2
- package/tools/gen_shims/main.go +43 -8
- package/utility/flags_gen.go +30 -0
- package/utility/host.go +304 -245
|
@@ -7,18 +7,36 @@ import type { ITtscParsedProjectConfig } from "../../../structures/internal/ITts
|
|
|
7
7
|
import type { ITtscProjectLocatorOptions } from "../../../structures/internal/ITtscProjectLocatorOptions";
|
|
8
8
|
import { resolveProjectConfig } from "./resolveProjectConfig";
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Compiler option keys whose values are file-system paths that must be resolved
|
|
12
|
+
* relative to the tsconfig that declares them, not the project root.
|
|
13
|
+
*/
|
|
10
14
|
const PATH_OPTIONS = new Set(["baseUrl", "declarationDir", "rootDir"]);
|
|
11
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Intermediate type used during `extends`-chain resolution before the result is
|
|
18
|
+
* projected into `ITtscParsedProjectConfig`.
|
|
19
|
+
*/
|
|
12
20
|
type ResolvedCompilerOptions = {
|
|
13
21
|
options: Record<string, unknown>;
|
|
22
|
+
/** Directory of the tsconfig that last declared each option key. */
|
|
14
23
|
optionBaseDirs: Record<string, string>;
|
|
15
24
|
outDir?: string;
|
|
16
25
|
pluginBaseDirs: string[];
|
|
26
|
+
/** True when any tsconfig in the chain explicitly declared `plugins`. */
|
|
17
27
|
pluginsDeclared: boolean;
|
|
18
28
|
plugins: ITtscProjectPluginConfig[];
|
|
19
29
|
};
|
|
20
30
|
|
|
21
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Read and resolve the project config subset used by ttsc.
|
|
33
|
+
*
|
|
34
|
+
* Follows `extends` chains (including arrays) and merges compiler options with
|
|
35
|
+
* later configs taking precedence. Path-typed options (`baseUrl`,
|
|
36
|
+
* `declarationDir`, `rootDir`) are resolved relative to the config that
|
|
37
|
+
* declares them. The `outDir` is resolved to an absolute path. Plugins are
|
|
38
|
+
* inherited from the nearest ancestor that declares them.
|
|
39
|
+
*/
|
|
22
40
|
export function readProjectConfig(
|
|
23
41
|
opts: ITtscProjectLocatorOptions = {},
|
|
24
42
|
): ITtscParsedProjectConfig {
|
|
@@ -39,12 +57,20 @@ export function readProjectConfig(
|
|
|
39
57
|
};
|
|
40
58
|
}
|
|
41
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Type guard: accept any non-null object as a plugin config entry. This is
|
|
62
|
+
* intentionally loose because the shape is validated later by plugin loaders.
|
|
63
|
+
*/
|
|
42
64
|
function isProjectPluginConfig(
|
|
43
65
|
value: unknown,
|
|
44
66
|
): value is ITtscProjectPluginConfig {
|
|
45
67
|
return typeof value === "object" && value !== null;
|
|
46
68
|
}
|
|
47
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Resolve symlinks on `location`, returning the original path when
|
|
72
|
+
* `realpathSync` fails (e.g. when the file does not yet exist).
|
|
73
|
+
*/
|
|
48
74
|
function resolveRealPath(location: string): string {
|
|
49
75
|
try {
|
|
50
76
|
return fs.realpathSync(location);
|
|
@@ -53,10 +79,18 @@ function resolveRealPath(location: string): string {
|
|
|
53
79
|
}
|
|
54
80
|
}
|
|
55
81
|
|
|
82
|
+
/** Resolve `target` against `cwd` when it is not already absolute. */
|
|
56
83
|
function resolveAbsolutePath(cwd: string, target: string): string {
|
|
57
84
|
return path.isAbsolute(target) ? target : path.resolve(cwd, target);
|
|
58
85
|
}
|
|
59
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Recursively read and merge `compilerOptions` from `tsconfig` and all configs
|
|
89
|
+
* in its `extends` chain. `seen` tracks canonical paths to detect circular
|
|
90
|
+
* `extends` references; the current config is removed from `seen` in the
|
|
91
|
+
* `finally` block so sibling-referenced configs can be visited again via a
|
|
92
|
+
* different parent.
|
|
93
|
+
*/
|
|
60
94
|
function readResolvedCompilerOptions(
|
|
61
95
|
tsconfig: string,
|
|
62
96
|
seen: Set<string> = new Set(),
|
|
@@ -117,6 +151,16 @@ function readResolvedCompilerOptions(
|
|
|
117
151
|
}
|
|
118
152
|
}
|
|
119
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Resolve the base compiler options from the `extends` field of a tsconfig.
|
|
156
|
+
*
|
|
157
|
+
* - String: a single base config; options are returned directly.
|
|
158
|
+
* - Array: multiple base configs merged left-to-right (later entries win).
|
|
159
|
+
* - Absent / non-string non-array: returns empty options.
|
|
160
|
+
*
|
|
161
|
+
* Plugin inheritance: when the current config in an array chain explicitly
|
|
162
|
+
* declares `plugins`, subsequent configs in the array do not override them.
|
|
163
|
+
*/
|
|
120
164
|
function resolveBaseCompilerOptions(
|
|
121
165
|
tsconfig: string,
|
|
122
166
|
extended: unknown,
|
|
@@ -172,6 +216,10 @@ function resolveBaseCompilerOptions(
|
|
|
172
216
|
return merged;
|
|
173
217
|
}
|
|
174
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Resolve path-typed compiler options to absolute paths using the directory of
|
|
221
|
+
* the tsconfig that declared each option (`baseDirs`).
|
|
222
|
+
*/
|
|
175
223
|
function resolvePathOptions(
|
|
176
224
|
options: Record<string, unknown>,
|
|
177
225
|
baseDirs: Record<string, string>,
|
|
@@ -187,6 +235,16 @@ function resolvePathOptions(
|
|
|
187
235
|
return resolved;
|
|
188
236
|
}
|
|
189
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Resolve an `extends` specifier to an absolute path using the same rules as
|
|
240
|
+
* TypeScript's config resolution:
|
|
241
|
+
*
|
|
242
|
+
* - Absolute path: used directly.
|
|
243
|
+
* - Relative specifier (`./`, `../`, `.`, `..`): resolved against the declaring
|
|
244
|
+
* tsconfig's directory with fallback extension candidates.
|
|
245
|
+
* - Bare package specifier: resolved through Node's module resolver (the resolver
|
|
246
|
+
* also tries appending `.json` when the first attempt fails).
|
|
247
|
+
*/
|
|
190
248
|
function resolveExtendsConfig(tsconfig: string, specifier: string): string {
|
|
191
249
|
const baseDir = path.dirname(tsconfig);
|
|
192
250
|
if (path.isAbsolute(specifier)) {
|
|
@@ -203,6 +261,10 @@ function resolveExtendsConfig(tsconfig: string, specifier: string): string {
|
|
|
203
261
|
}
|
|
204
262
|
}
|
|
205
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Given an on-disk location, try the path as-is, with `.json` appended, and as
|
|
266
|
+
* a directory containing `tsconfig.json`. Returns the first match or throws.
|
|
267
|
+
*/
|
|
206
268
|
function resolveExistingExtendsPath(location: string): string {
|
|
207
269
|
const candidates = new Set<string>([
|
|
208
270
|
location,
|
|
@@ -217,6 +279,10 @@ function resolveExistingExtendsPath(location: string): string {
|
|
|
217
279
|
throw new Error(`ttsc: extended tsconfig not found: ${location}`);
|
|
218
280
|
}
|
|
219
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Return true when `specifier` is a relative path reference: `.`, `..`, or a
|
|
284
|
+
* string starting with `./`, `../`, `.\\`, or `..\\`.
|
|
285
|
+
*/
|
|
220
286
|
function isRelativeSpecifier(specifier: string): boolean {
|
|
221
287
|
return (
|
|
222
288
|
specifier === "." ||
|
|
@@ -228,10 +294,19 @@ function isRelativeSpecifier(specifier: string): boolean {
|
|
|
228
294
|
);
|
|
229
295
|
}
|
|
230
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Parse a JSONC (JSON with Comments) string by stripping comments and trailing
|
|
299
|
+
* commas before handing off to `JSON.parse`.
|
|
300
|
+
*/
|
|
231
301
|
function parseJsonc(input: string): unknown {
|
|
232
302
|
return JSON.parse(stripTrailingCommas(stripComments(input)));
|
|
233
303
|
}
|
|
234
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Remove `//` line comments and `/* block comments *\/` from a JSONC string.
|
|
307
|
+
* Correctly handles strings that contain comment-like character sequences by
|
|
308
|
+
* tracking string boundaries and escape characters.
|
|
309
|
+
*/
|
|
235
310
|
function stripComments(input: string): string {
|
|
236
311
|
let output = "";
|
|
237
312
|
let inBlockComment = false;
|
|
@@ -292,6 +367,11 @@ function stripComments(input: string): string {
|
|
|
292
367
|
return output;
|
|
293
368
|
}
|
|
294
369
|
|
|
370
|
+
/**
|
|
371
|
+
* Remove trailing commas before `}` or `]` from a JSON string (after comments
|
|
372
|
+
* have already been stripped). Handles string boundaries and escape characters
|
|
373
|
+
* to avoid removing commas inside string values.
|
|
374
|
+
*/
|
|
295
375
|
function stripTrailingCommas(input: string): string {
|
|
296
376
|
let output = "";
|
|
297
377
|
let inString = false;
|
|
@@ -330,6 +410,11 @@ function stripTrailingCommas(input: string): string {
|
|
|
330
410
|
return output;
|
|
331
411
|
}
|
|
332
412
|
|
|
413
|
+
/**
|
|
414
|
+
* Return the first non-whitespace character at or after position `from` in
|
|
415
|
+
* `input`, or `undefined` when only whitespace remains. Used by
|
|
416
|
+
* `stripTrailingCommas` to detect whether a comma is trailing.
|
|
417
|
+
*/
|
|
333
418
|
function nextNonWhitespace(input: string, from: number): string | undefined {
|
|
334
419
|
for (let i = from; i < input.length; i += 1) {
|
|
335
420
|
const current = input[i]!;
|
|
@@ -3,7 +3,19 @@ import path from "node:path";
|
|
|
3
3
|
|
|
4
4
|
import type { ITtscProjectLocatorOptions } from "../../../structures/internal/ITtscProjectLocatorOptions";
|
|
5
5
|
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the tsconfig/jsconfig that owns a ttsc invocation.
|
|
8
|
+
*
|
|
9
|
+
* Resolution order:
|
|
10
|
+
*
|
|
11
|
+
* 1. `opts.tsconfig` — resolved absolute and checked for existence.
|
|
12
|
+
* 2. `opts.file` — the nearest ancestor config that contains the file is found by
|
|
13
|
+
* walking up from the file's directory.
|
|
14
|
+
* 3. `opts.cwd` — the nearest ancestor config walking up from cwd.
|
|
15
|
+
*
|
|
16
|
+
* Always returns a real (symlink-resolved) absolute path. Throws when no config
|
|
17
|
+
* is found or the explicitly supplied path does not exist.
|
|
18
|
+
*/
|
|
7
19
|
export function resolveProjectConfig(
|
|
8
20
|
opts: ITtscProjectLocatorOptions = {},
|
|
9
21
|
): string {
|
|
@@ -13,6 +25,26 @@ export function resolveProjectConfig(
|
|
|
13
25
|
if (!fs.existsSync(resolved)) {
|
|
14
26
|
throw new Error(`ttsc: tsconfig not found: ${resolved}`);
|
|
15
27
|
}
|
|
28
|
+
// `-p <directory>` is the documented tsgo shorthand for the
|
|
29
|
+
// directory that contains a `tsconfig.json`. Mirror that — without
|
|
30
|
+
// this branch a forwarded `--tsconfig=sub` would feed the directory
|
|
31
|
+
// path into `readResolvedCompilerOptions`, which calls
|
|
32
|
+
// `fs.readFileSync` and throws `EISDIR` (the RCA's predicted
|
|
33
|
+
// RC-3 §5 #2 bug, pinned by
|
|
34
|
+
// `test_ttsc_dash_p_directory_path_is_accepted`).
|
|
35
|
+
if (isDirectory(resolved)) {
|
|
36
|
+
const tsconfigInDir = path.join(resolved, "tsconfig.json");
|
|
37
|
+
if (fs.existsSync(tsconfigInDir)) {
|
|
38
|
+
return resolveRealPath(tsconfigInDir);
|
|
39
|
+
}
|
|
40
|
+
const jsconfigInDir = path.join(resolved, "jsconfig.json");
|
|
41
|
+
if (fs.existsSync(jsconfigInDir)) {
|
|
42
|
+
return resolveRealPath(jsconfigInDir);
|
|
43
|
+
}
|
|
44
|
+
throw new Error(
|
|
45
|
+
`ttsc: directory has no tsconfig.json / jsconfig.json: ${resolved}`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
16
48
|
return resolveRealPath(resolved);
|
|
17
49
|
}
|
|
18
50
|
|
|
@@ -29,10 +61,15 @@ export function resolveProjectConfig(
|
|
|
29
61
|
return resolveRealPath(found);
|
|
30
62
|
}
|
|
31
63
|
|
|
64
|
+
/** Resolve `target` against `cwd` when it is not already absolute. */
|
|
32
65
|
function resolveAbsolutePath(cwd: string, target: string): string {
|
|
33
66
|
return path.isAbsolute(target) ? target : path.resolve(cwd, target);
|
|
34
67
|
}
|
|
35
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Resolve symlinks on `location`, returning the original path when
|
|
71
|
+
* `realpathSync` fails (e.g. when the file does not yet exist).
|
|
72
|
+
*/
|
|
36
73
|
function resolveRealPath(location: string): string {
|
|
37
74
|
try {
|
|
38
75
|
return fs.realpathSync(location);
|
|
@@ -41,6 +78,11 @@ function resolveRealPath(location: string): string {
|
|
|
41
78
|
}
|
|
42
79
|
}
|
|
43
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Walk up the directory tree from `from`, returning the first directory that
|
|
83
|
+
* contains a file whose name is in `names`. Returns `null` when the filesystem
|
|
84
|
+
* root is reached without finding a match.
|
|
85
|
+
*/
|
|
44
86
|
function findUp(from: string, names: readonly string[]): string | null {
|
|
45
87
|
let current = path.resolve(from);
|
|
46
88
|
while (true) {
|
|
@@ -58,6 +100,7 @@ function findUp(from: string, names: readonly string[]): string | null {
|
|
|
58
100
|
}
|
|
59
101
|
}
|
|
60
102
|
|
|
103
|
+
/** Return true when `location` exists and is a directory. */
|
|
61
104
|
function isDirectory(location: string): boolean {
|
|
62
105
|
try {
|
|
63
106
|
return fs.statSync(location).isDirectory();
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the ttsc helper binary path, or null when unavailable.
|
|
6
|
+
*
|
|
7
|
+
* Resolution order:
|
|
8
|
+
*
|
|
9
|
+
* 1. `TTSC_BINARY` env var — must be an absolute path when set.
|
|
10
|
+
* 2. The per-platform npm package `@ttsc/<platform>-<arch>/bin/ttsc[.exe]`.
|
|
11
|
+
* 3. A `ttsc-native[.exe]` sibling of this package's root (dev/CI layout).
|
|
12
|
+
*/
|
|
5
13
|
export function resolveBinary(
|
|
6
14
|
opts: { env?: NodeJS.ProcessEnv } = {},
|
|
7
15
|
): string | null {
|
|
@@ -24,6 +32,10 @@ export function resolveBinary(
|
|
|
24
32
|
return null;
|
|
25
33
|
}
|
|
26
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Return the path to the dev-layout `ttsc-native[.exe]` binary adjacent to the
|
|
37
|
+
* package root, or null when the file does not exist.
|
|
38
|
+
*/
|
|
27
39
|
function defaultLocalBinaryPath(): string | null {
|
|
28
40
|
const root = packageRootDir();
|
|
29
41
|
const candidate = path.resolve(
|
|
@@ -35,6 +47,10 @@ function defaultLocalBinaryPath(): string | null {
|
|
|
35
47
|
return fs.existsSync(candidate) ? candidate : null;
|
|
36
48
|
}
|
|
37
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Return the real, absolute path of the `packages/ttsc` package root by walking
|
|
52
|
+
* two levels up from `__dirname` (which lives in `src/compiler/internal`).
|
|
53
|
+
*/
|
|
38
54
|
function packageRootDir(): string {
|
|
39
55
|
const moduleDir = path.resolve(__dirname, "..", "..");
|
|
40
56
|
return fs.realpathSync.native?.(moduleDir) ?? fs.realpathSync(moduleDir);
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import { isOutsideRelativePath } from "./paths";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Locate the JavaScript file emitted for a TypeScript source file.
|
|
8
|
+
*
|
|
9
|
+
* Resolution strategy:
|
|
10
|
+
*
|
|
11
|
+
* 1. Try to derive the exact output path by mirroring the source's relative
|
|
12
|
+
* position inside `projectRoot` into `outDir`, applying the correct JS
|
|
13
|
+
* extension (`.js` / `.mjs` / `.cjs`). Use this path if it exists on disk.
|
|
14
|
+
* 2. Fall back to scoring each candidate in `emittedFiles` (or a recursive
|
|
15
|
+
* directory scan of `outDir`) by the number of trailing path-stem segments
|
|
16
|
+
* shared with the source file name, and pick the highest-scoring existing
|
|
17
|
+
* file.
|
|
18
|
+
*
|
|
19
|
+
* Returns `null` when no matching output file is found on disk.
|
|
20
|
+
*/
|
|
5
21
|
export function resolveEmittedJavaScript(options: {
|
|
22
|
+
/** Pre-computed list of emitted paths; when absent `outDir` is scanned. */
|
|
6
23
|
emittedFiles?: readonly string[];
|
|
7
24
|
outDir: string;
|
|
8
25
|
projectRoot: string;
|
|
@@ -31,6 +48,11 @@ export function resolveEmittedJavaScript(options: {
|
|
|
31
48
|
return best && fs.existsSync(best) ? best : null;
|
|
32
49
|
}
|
|
33
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Derive the exact output path for `sourceFile` by mirroring its position
|
|
53
|
+
* relative to `projectRoot` into `outDir`. Returns `null` when the source is
|
|
54
|
+
* not inside the project root or when the path cannot be determined.
|
|
55
|
+
*/
|
|
34
56
|
function resolveExactEmittedFile(
|
|
35
57
|
outDir: string,
|
|
36
58
|
projectRoot: string,
|
|
@@ -47,6 +69,11 @@ function resolveExactEmittedFile(
|
|
|
47
69
|
);
|
|
48
70
|
}
|
|
49
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Recursively enumerate every JavaScript output file under `root`. Uses an
|
|
74
|
+
* explicit stack instead of recursion to avoid call-stack overflow on deep
|
|
75
|
+
* directory trees. Non-existent roots are silently skipped.
|
|
76
|
+
*/
|
|
50
77
|
function listJavaScriptFiles(root: string): string[] {
|
|
51
78
|
const out: string[] = [];
|
|
52
79
|
const stack = [root];
|
|
@@ -65,15 +92,22 @@ function listJavaScriptFiles(root: string): string[] {
|
|
|
65
92
|
return out;
|
|
66
93
|
}
|
|
67
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Count the number of consecutive trailing path-stem segments that `outPath`
|
|
97
|
+
* and `srcPath` share when both are stripped of their extensions and normalised
|
|
98
|
+
* to forward slashes.
|
|
99
|
+
*
|
|
100
|
+
* Example: `dist/lib/foo.js` vs `src/lib/foo.ts` → 2 (`lib`, `foo`).
|
|
101
|
+
*/
|
|
68
102
|
function sharedSourceStemSegments(outPath: string, srcPath: string): number {
|
|
69
|
-
const
|
|
103
|
+
const stripExtAndSplit = (location: string): string[] => {
|
|
70
104
|
const normalized = location.replace(/\\/g, "/");
|
|
71
105
|
return normalized
|
|
72
106
|
.slice(0, normalized.length - path.extname(normalized).length)
|
|
73
107
|
.split("/");
|
|
74
108
|
};
|
|
75
|
-
const a =
|
|
76
|
-
const b =
|
|
109
|
+
const a = stripExtAndSplit(outPath);
|
|
110
|
+
const b = stripExtAndSplit(srcPath);
|
|
77
111
|
const count = Math.min(a.length, b.length);
|
|
78
112
|
let shared = 0;
|
|
79
113
|
for (let i = 1; i <= count; i += 1) {
|
|
@@ -83,14 +117,10 @@ function sharedSourceStemSegments(outPath: string, srcPath: string): number {
|
|
|
83
117
|
return shared;
|
|
84
118
|
}
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
path.isAbsolute(relative)
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Map a TypeScript source extension to its JavaScript output counterpart.
|
|
122
|
+
* `.mts` → `.mjs`, `.cts` → `.cjs`, everything else → `.js`.
|
|
123
|
+
*/
|
|
94
124
|
function emittedJavaScriptExtension(filename: string): string {
|
|
95
125
|
switch (path.extname(filename).toLowerCase()) {
|
|
96
126
|
case ".mts":
|
|
@@ -102,6 +132,7 @@ function emittedJavaScriptExtension(filename: string): string {
|
|
|
102
132
|
}
|
|
103
133
|
}
|
|
104
134
|
|
|
135
|
+
/** Return true when `filename` has a `.js`, `.mjs`, or `.cjs` extension. */
|
|
105
136
|
function isJavaScriptOutput(filename: string): boolean {
|
|
106
137
|
return /\.(?:[cm]?js)$/i.test(filename);
|
|
107
138
|
}
|
|
@@ -2,12 +2,32 @@ import fs from "node:fs";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the consumer project's TypeScript-Go preview binary and metadata.
|
|
7
|
+
*
|
|
8
|
+
* Resolution order:
|
|
9
|
+
*
|
|
10
|
+
* 1. `opts.binary` or `TTSC_TSGO_BINARY` env var — must be an existing absolute
|
|
11
|
+
* path; returns `{ binary, packageJson: "", packageRoot, version: "custom"
|
|
12
|
+
* }`.
|
|
13
|
+
* 2. `@typescript/native-preview` resolved from the project `cwd`.
|
|
14
|
+
* 3. `@typescript/native-preview` resolved from `opts.resolveFrom` (for test
|
|
15
|
+
* harnesses and embedders that anchor to a different directory).
|
|
16
|
+
*
|
|
17
|
+
* Throws a descriptive error when the package or platform binary is missing so
|
|
18
|
+
* callers never have to reason about undefined binary paths.
|
|
19
|
+
*/
|
|
6
20
|
export function resolveTsgo(
|
|
7
21
|
opts: {
|
|
22
|
+
/** Explicit path to a tsgo binary; bypasses package resolution. */
|
|
8
23
|
binary?: string;
|
|
24
|
+
/** Directory from which to discover `@typescript/native-preview`. */
|
|
9
25
|
cwd?: string;
|
|
10
26
|
env?: NodeJS.ProcessEnv;
|
|
27
|
+
/**
|
|
28
|
+
* Fallback resolution anchor used when the package is not found at `cwd`.
|
|
29
|
+
* Useful in test harnesses that install the package into a different tree.
|
|
30
|
+
*/
|
|
11
31
|
resolveFrom?: string;
|
|
12
32
|
} = {},
|
|
13
33
|
) {
|
|
@@ -28,6 +48,8 @@ export function resolveTsgo(
|
|
|
28
48
|
}
|
|
29
49
|
|
|
30
50
|
const cwd = path.resolve(opts.cwd ?? process.cwd());
|
|
51
|
+
// Resolve the package.json of @typescript/native-preview.
|
|
52
|
+
// Try cwd first, then the optional resolveFrom anchor.
|
|
31
53
|
let packageJson: string;
|
|
32
54
|
packageJson =
|
|
33
55
|
resolveNativePreviewPackageJson(path.join(cwd, "package.json")) ??
|
|
@@ -84,6 +106,11 @@ export function resolveTsgo(
|
|
|
84
106
|
};
|
|
85
107
|
}
|
|
86
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Attempt to resolve the `package.json` of `@typescript/native-preview`
|
|
111
|
+
* starting from `from` (a package.json path or directory). Returns `undefined`
|
|
112
|
+
* when the package is not resolvable from that location.
|
|
113
|
+
*/
|
|
87
114
|
function resolveNativePreviewPackageJson(from: string): string | undefined {
|
|
88
115
|
try {
|
|
89
116
|
return createRequire(from).resolve(
|
|
@@ -94,6 +121,7 @@ function resolveNativePreviewPackageJson(from: string): string | undefined {
|
|
|
94
121
|
}
|
|
95
122
|
}
|
|
96
123
|
|
|
124
|
+
/** Parse a JSON file and return the result as a plain object. */
|
|
97
125
|
function readPackageJson(file: string): Record<string, unknown> {
|
|
98
126
|
return JSON.parse(fs.readFileSync(file, "utf8")) as Record<string, unknown>;
|
|
99
127
|
}
|