ttsc 0.6.0 → 0.7.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.
Files changed (261) hide show
  1. package/cmd/ttsc/api_compile.go +134 -0
  2. package/cmd/ttsc/build.go +1 -7
  3. package/cmd/ttsc/main.go +2 -2
  4. package/cmd/ttsc/transform.go +0 -6
  5. package/driver/program.go +11 -1
  6. package/lib/TtscCompiler.d.ts +76 -0
  7. package/lib/TtscCompiler.js +245 -0
  8. package/lib/TtscCompiler.js.map +1 -0
  9. package/lib/compiler/internal/buildNativeCompiler.d.ts +6 -0
  10. package/lib/compiler/internal/buildNativeCompiler.js +72 -0
  11. package/lib/compiler/internal/buildNativeCompiler.js.map +1 -0
  12. package/lib/compiler/internal/compileProjectInMemory.d.ts +7 -0
  13. package/lib/compiler/internal/compileProjectInMemory.js +176 -0
  14. package/lib/compiler/internal/compileProjectInMemory.js.map +1 -0
  15. package/lib/compiler/internal/project/readProjectConfig.d.ts +4 -0
  16. package/lib/{project.js → compiler/internal/project/readProjectConfig.js} +12 -82
  17. package/lib/compiler/internal/project/readProjectConfig.js.map +1 -0
  18. package/lib/compiler/internal/project/resolveProjectConfig.d.ts +3 -0
  19. package/lib/compiler/internal/project/resolveProjectConfig.js +94 -0
  20. package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -0
  21. package/lib/compiler/internal/resolveBinary.d.ts +4 -0
  22. package/lib/compiler/internal/resolveBinary.js +65 -0
  23. package/lib/compiler/internal/resolveBinary.js.map +1 -0
  24. package/lib/compiler/internal/resolveEmittedJavaScript.d.ts +7 -0
  25. package/lib/compiler/internal/resolveEmittedJavaScript.js +118 -0
  26. package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -0
  27. package/lib/compiler/internal/resolveTsgo.d.ts +20 -0
  28. package/lib/{tsgo.js → compiler/internal/resolveTsgo.js} +5 -10
  29. package/lib/compiler/internal/resolveTsgo.js.map +1 -0
  30. package/lib/compiler/internal/runBuild.d.ts +10 -0
  31. package/lib/compiler/internal/runBuild.js +480 -0
  32. package/lib/compiler/internal/runBuild.js.map +1 -0
  33. package/lib/compiler/internal/runTransform.d.ts +3 -0
  34. package/lib/compiler/internal/runTransform.js +100 -0
  35. package/lib/compiler/internal/runTransform.js.map +1 -0
  36. package/lib/index.d.ts +6 -15
  37. package/lib/index.js +6 -15
  38. package/lib/index.js.map +1 -1
  39. package/lib/launcher/internal/getCompilerVersionText.d.ts +3 -0
  40. package/lib/launcher/internal/getCompilerVersionText.js +71 -0
  41. package/lib/launcher/internal/getCompilerVersionText.js.map +1 -0
  42. package/lib/launcher/internal/prepareExecution.d.ts +10 -0
  43. package/lib/launcher/internal/prepareExecution.js +120 -0
  44. package/lib/launcher/internal/prepareExecution.js.map +1 -0
  45. package/lib/launcher/internal/runTtsc.d.ts +1 -0
  46. package/lib/{cli.js → launcher/internal/runTtsc.js} +48 -47
  47. package/lib/launcher/internal/runTtsc.js.map +1 -0
  48. package/lib/launcher/internal/runTtsx.d.ts +1 -0
  49. package/lib/{runner/cli.js → launcher/internal/runTtsx.js} +13 -35
  50. package/lib/launcher/internal/runTtsx.js.map +1 -0
  51. package/lib/launcher/ttsc.js +2 -2
  52. package/lib/launcher/ttsc.js.map +1 -1
  53. package/lib/launcher/ttsx.js +2 -2
  54. package/lib/launcher/ttsx.js.map +1 -1
  55. package/lib/plugin/internal/buildSourcePlugin.d.ts +12 -0
  56. package/lib/{source-build.js → plugin/internal/buildSourcePlugin.js} +77 -84
  57. package/lib/plugin/internal/buildSourcePlugin.js.map +1 -0
  58. package/lib/plugin/internal/loadProjectPlugins.d.ts +14 -0
  59. package/lib/{plugin.js → plugin/internal/loadProjectPlugins.js} +38 -76
  60. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -0
  61. package/lib/structures/ITtscCompilerContext.d.ts +78 -0
  62. package/lib/structures/ITtscCompilerContext.js +3 -0
  63. package/lib/structures/ITtscCompilerContext.js.map +1 -0
  64. package/lib/structures/ITtscCompilerDiagnostic.d.ts +83 -0
  65. package/lib/structures/ITtscCompilerDiagnostic.js +3 -0
  66. package/lib/structures/ITtscCompilerDiagnostic.js.map +1 -0
  67. package/lib/structures/ITtscCompilerResult.d.ts +83 -0
  68. package/lib/structures/{ITtscCacheKeyInput.js → ITtscCompilerResult.js} +1 -1
  69. package/lib/structures/ITtscCompilerResult.js.map +1 -0
  70. package/lib/structures/ITtscPlugin.d.ts +52 -7
  71. package/lib/structures/ITtscPluginFactoryContext.d.ts +47 -0
  72. package/lib/structures/ITtscProjectPluginConfig.d.ts +41 -0
  73. package/lib/structures/TtscPluginStage.d.ts +15 -0
  74. package/lib/structures/{ITtscBuildResult.js → TtscPluginStage.js} +1 -1
  75. package/lib/structures/TtscPluginStage.js.map +1 -0
  76. package/lib/structures/index.d.ts +7 -0
  77. package/lib/structures/index.js +24 -0
  78. package/lib/structures/index.js.map +1 -0
  79. package/lib/structures/internal/ITtscLoadedNativePlugin.d.ts +13 -0
  80. package/lib/structures/internal/ITtscLoadedNativePlugin.js.map +1 -0
  81. package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +15 -0
  82. package/lib/structures/internal/ITtscParsedProjectConfig.js.map +1 -0
  83. package/lib/structures/internal/ITtscProjectLocatorOptions.d.ts +9 -0
  84. package/lib/structures/internal/ITtscProjectLocatorOptions.js.map +1 -0
  85. package/lib/structures/internal/TtscBuildOptions.d.ts +18 -0
  86. package/lib/structures/{ITtscBuildOptions.js → internal/TtscBuildOptions.js} +1 -1
  87. package/lib/structures/internal/TtscBuildOptions.js.map +1 -0
  88. package/lib/structures/internal/TtscBuildResult.d.ts +14 -0
  89. package/lib/structures/{ITtscCheckOptions.js → internal/TtscBuildResult.js} +1 -1
  90. package/lib/structures/internal/TtscBuildResult.js.map +1 -0
  91. package/lib/structures/internal/TtscCommonOptions.d.ts +27 -0
  92. package/lib/structures/{ITtscNativeSource.js → internal/TtscCommonOptions.js} +1 -1
  93. package/lib/structures/internal/TtscCommonOptions.js.map +1 -0
  94. package/lib/structures/internal/TtscTransformOptions.d.ts +14 -0
  95. package/lib/structures/internal/TtscTransformOptions.js +3 -0
  96. package/lib/structures/internal/TtscTransformOptions.js.map +1 -0
  97. package/package.json +9 -9
  98. package/src/TtscCompiler.ts +241 -0
  99. package/src/compiler/internal/buildNativeCompiler.ts +43 -0
  100. package/src/compiler/internal/compileProjectInMemory.ts +189 -0
  101. package/src/{project.ts → compiler/internal/project/readProjectConfig.ts} +36 -111
  102. package/src/compiler/internal/project/resolveProjectConfig.ts +67 -0
  103. package/src/compiler/internal/resolveBinary.ts +41 -0
  104. package/src/compiler/internal/resolveEmittedJavaScript.ts +102 -0
  105. package/src/{tsgo.ts → compiler/internal/resolveTsgo.ts} +20 -23
  106. package/src/compiler/internal/runBuild.ts +644 -0
  107. package/src/compiler/internal/runTransform.ts +69 -0
  108. package/src/index.ts +6 -15
  109. package/src/launcher/internal/getCompilerVersionText.ts +44 -0
  110. package/src/launcher/internal/prepareExecution.ts +115 -0
  111. package/src/{cli.ts → launcher/internal/runTtsc.ts} +61 -70
  112. package/src/{runner/cli.ts → launcher/internal/runTtsx.ts} +21 -49
  113. package/src/launcher/ttsc.ts +2 -2
  114. package/src/launcher/ttsx.ts +2 -2
  115. package/src/{source-build.ts → plugin/internal/buildSourcePlugin.ts} +121 -115
  116. package/src/plugin/internal/loadProjectPlugins.ts +214 -0
  117. package/src/structures/ITtscCompilerContext.ts +84 -0
  118. package/src/structures/ITtscCompilerDiagnostic.ts +91 -0
  119. package/src/structures/ITtscCompilerResult.ts +94 -0
  120. package/src/structures/ITtscPlugin.ts +54 -7
  121. package/src/structures/ITtscPluginFactoryContext.ts +51 -0
  122. package/src/structures/ITtscProjectPluginConfig.ts +43 -0
  123. package/src/structures/TtscPluginStage.ts +15 -0
  124. package/src/structures/index.ts +7 -0
  125. package/src/structures/internal/ITtscLoadedNativePlugin.ts +14 -0
  126. package/src/structures/internal/ITtscParsedProjectConfig.ts +16 -0
  127. package/src/structures/internal/ITtscProjectLocatorOptions.ts +9 -0
  128. package/src/structures/internal/TtscBuildOptions.ts +19 -0
  129. package/src/structures/internal/TtscBuildResult.ts +15 -0
  130. package/src/structures/internal/TtscCommonOptions.ts +28 -0
  131. package/src/structures/internal/TtscTransformOptions.ts +15 -0
  132. package/test/compiler.test.ts +234 -0
  133. package/test/platform.test.ts +1 -45
  134. package/test/project.test.ts +3 -1
  135. package/test/source-build.test.ts +33 -220
  136. package/test/tsgo.test.ts +1 -8
  137. package/lib/api.d.ts +0 -40
  138. package/lib/api.js +0 -680
  139. package/lib/api.js.map +0 -1
  140. package/lib/cli.d.ts +0 -1
  141. package/lib/cli.js.map +0 -1
  142. package/lib/native.d.ts +0 -8
  143. package/lib/native.js +0 -42
  144. package/lib/native.js.map +0 -1
  145. package/lib/platform.d.ts +0 -52
  146. package/lib/platform.js +0 -175
  147. package/lib/platform.js.map +0 -1
  148. package/lib/plugin.d.ts +0 -13
  149. package/lib/plugin.js.map +0 -1
  150. package/lib/project.d.ts +0 -14
  151. package/lib/project.js.map +0 -1
  152. package/lib/runner/cli.d.ts +0 -1
  153. package/lib/runner/cli.js.map +0 -1
  154. package/lib/runner/register.d.ts +0 -6
  155. package/lib/runner/register.js +0 -358
  156. package/lib/runner/register.js.map +0 -1
  157. package/lib/source-build.d.ts +0 -19
  158. package/lib/source-build.js.map +0 -1
  159. package/lib/structures/ITtscBuildOptions.d.ts +0 -14
  160. package/lib/structures/ITtscBuildOptions.js.map +0 -1
  161. package/lib/structures/ITtscBuildResult.d.ts +0 -6
  162. package/lib/structures/ITtscBuildResult.js.map +0 -1
  163. package/lib/structures/ITtscBuildSourcePluginOptions.d.ts +0 -8
  164. package/lib/structures/ITtscBuildSourcePluginOptions.js +0 -3
  165. package/lib/structures/ITtscBuildSourcePluginOptions.js.map +0 -1
  166. package/lib/structures/ITtscCacheKeyInput.d.ts +0 -7
  167. package/lib/structures/ITtscCacheKeyInput.js.map +0 -1
  168. package/lib/structures/ITtscCheckOptions.d.ts +0 -2
  169. package/lib/structures/ITtscCheckOptions.js.map +0 -1
  170. package/lib/structures/ITtscCommonOptions.d.ts +0 -22
  171. package/lib/structures/ITtscCommonOptions.js +0 -3
  172. package/lib/structures/ITtscCommonOptions.js.map +0 -1
  173. package/lib/structures/ITtscLoadPluginsOptions.d.ts +0 -8
  174. package/lib/structures/ITtscLoadPluginsOptions.js +0 -3
  175. package/lib/structures/ITtscLoadPluginsOptions.js.map +0 -1
  176. package/lib/structures/ITtscLoadedNativePlugin.d.ts +0 -7
  177. package/lib/structures/ITtscLoadedNativePlugin.js.map +0 -1
  178. package/lib/structures/ITtscLoadedPlugins.d.ts +0 -11
  179. package/lib/structures/ITtscLoadedPlugins.js +0 -3
  180. package/lib/structures/ITtscLoadedPlugins.js.map +0 -1
  181. package/lib/structures/ITtscNativeBackend.d.ts +0 -10
  182. package/lib/structures/ITtscNativeBackend.js +0 -3
  183. package/lib/structures/ITtscNativeBackend.js.map +0 -1
  184. package/lib/structures/ITtscNativePluginContractVersion.d.ts +0 -1
  185. package/lib/structures/ITtscNativePluginContractVersion.js +0 -3
  186. package/lib/structures/ITtscNativePluginContractVersion.js.map +0 -1
  187. package/lib/structures/ITtscNativePluginShape.d.ts +0 -8
  188. package/lib/structures/ITtscNativePluginShape.js +0 -3
  189. package/lib/structures/ITtscNativePluginShape.js.map +0 -1
  190. package/lib/structures/ITtscNativeRewriteMode.d.ts +0 -1
  191. package/lib/structures/ITtscNativeRewriteMode.js +0 -3
  192. package/lib/structures/ITtscNativeRewriteMode.js.map +0 -1
  193. package/lib/structures/ITtscNativeSource.d.ts +0 -4
  194. package/lib/structures/ITtscNativeSource.js.map +0 -1
  195. package/lib/structures/ITtscParsedProjectConfig.d.ts +0 -9
  196. package/lib/structures/ITtscParsedProjectConfig.js.map +0 -1
  197. package/lib/structures/ITtscPluginFactory.d.ts +0 -4
  198. package/lib/structures/ITtscPluginFactory.js +0 -3
  199. package/lib/structures/ITtscPluginFactory.js.map +0 -1
  200. package/lib/structures/ITtscPluginModule.d.ts +0 -3
  201. package/lib/structures/ITtscPluginModule.js +0 -3
  202. package/lib/structures/ITtscPluginModule.js.map +0 -1
  203. package/lib/structures/ITtscPreparedExecution.d.ts +0 -5
  204. package/lib/structures/ITtscPreparedExecution.js +0 -3
  205. package/lib/structures/ITtscPreparedExecution.js.map +0 -1
  206. package/lib/structures/ITtscProjectLocatorOptions.d.ts +0 -5
  207. package/lib/structures/ITtscProjectLocatorOptions.js.map +0 -1
  208. package/lib/structures/ITtscRegisterOptions.d.ts +0 -6
  209. package/lib/structures/ITtscRegisterOptions.js +0 -3
  210. package/lib/structures/ITtscRegisterOptions.js.map +0 -1
  211. package/lib/structures/ITtscResolveGoBinaryOptions.d.ts +0 -7
  212. package/lib/structures/ITtscResolveGoBinaryOptions.js +0 -3
  213. package/lib/structures/ITtscResolveGoBinaryOptions.js.map +0 -1
  214. package/lib/structures/ITtscResolveOptions.d.ts +0 -20
  215. package/lib/structures/ITtscResolveOptions.js +0 -3
  216. package/lib/structures/ITtscResolveOptions.js.map +0 -1
  217. package/lib/structures/ITtscResolvedTsgo.d.ts +0 -8
  218. package/lib/structures/ITtscResolvedTsgo.js +0 -3
  219. package/lib/structures/ITtscResolvedTsgo.js.map +0 -1
  220. package/lib/structures/ITtscTransformOptions.d.ts +0 -12
  221. package/lib/structures/ITtscTransformOptions.js +0 -3
  222. package/lib/structures/ITtscTransformOptions.js.map +0 -1
  223. package/lib/structures/ITtscTsgoResolveOptions.d.ts +0 -14
  224. package/lib/structures/ITtscTsgoResolveOptions.js +0 -3
  225. package/lib/structures/ITtscTsgoResolveOptions.js.map +0 -1
  226. package/lib/tsgo.d.ts +0 -6
  227. package/lib/tsgo.js.map +0 -1
  228. package/src/api.ts +0 -872
  229. package/src/native.ts +0 -64
  230. package/src/platform.ts +0 -151
  231. package/src/plugin.ts +0 -253
  232. package/src/runner/register.ts +0 -406
  233. package/src/structures/ITtscBuildOptions.ts +0 -19
  234. package/src/structures/ITtscBuildResult.ts +0 -6
  235. package/src/structures/ITtscBuildSourcePluginOptions.ts +0 -9
  236. package/src/structures/ITtscCacheKeyInput.ts +0 -7
  237. package/src/structures/ITtscCheckOptions.ts +0 -3
  238. package/src/structures/ITtscCommonOptions.ts +0 -23
  239. package/src/structures/ITtscLoadPluginsOptions.ts +0 -9
  240. package/src/structures/ITtscLoadedNativePlugin.ts +0 -8
  241. package/src/structures/ITtscLoadedPlugins.ts +0 -12
  242. package/src/structures/ITtscNativeBackend.ts +0 -11
  243. package/src/structures/ITtscNativePluginContractVersion.ts +0 -1
  244. package/src/structures/ITtscNativePluginShape.ts +0 -9
  245. package/src/structures/ITtscNativeRewriteMode.ts +0 -1
  246. package/src/structures/ITtscNativeSource.ts +0 -4
  247. package/src/structures/ITtscParsedProjectConfig.ts +0 -10
  248. package/src/structures/ITtscPluginFactory.ts +0 -7
  249. package/src/structures/ITtscPluginModule.ts +0 -4
  250. package/src/structures/ITtscPreparedExecution.ts +0 -5
  251. package/src/structures/ITtscProjectLocatorOptions.ts +0 -5
  252. package/src/structures/ITtscRegisterOptions.ts +0 -7
  253. package/src/structures/ITtscResolveGoBinaryOptions.ts +0 -7
  254. package/src/structures/ITtscResolveOptions.ts +0 -20
  255. package/src/structures/ITtscResolvedTsgo.ts +0 -8
  256. package/src/structures/ITtscTransformOptions.ts +0 -13
  257. package/src/structures/ITtscTsgoResolveOptions.ts +0 -14
  258. package/test/native.test.ts +0 -103
  259. /package/lib/structures/{ITtscLoadedNativePlugin.js → internal/ITtscLoadedNativePlugin.js} +0 -0
  260. /package/lib/structures/{ITtscParsedProjectConfig.js → internal/ITtscParsedProjectConfig.js} +0 -0
  261. /package/lib/structures/{ITtscProjectLocatorOptions.js → internal/ITtscProjectLocatorOptions.js} +0 -0
@@ -0,0 +1,189 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import * as fs from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+
6
+ import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
7
+ import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
8
+ import type { ITtscProjectPluginConfig } from "../../structures/ITtscProjectPluginConfig";
9
+ import type { ITtscParsedProjectConfig } from "../../structures/internal/ITtscParsedProjectConfig";
10
+ import type { TtscBuildResult } from "../../structures/internal/TtscBuildResult";
11
+ import { buildNativeCompiler } from "./buildNativeCompiler";
12
+ import { readProjectConfig } from "./project/readProjectConfig";
13
+ import { runBuild } from "./runBuild";
14
+
15
+ /** Compile a project and capture emitted files without writing to the project tree. */
16
+ export function compileProjectInMemory(options: ITtscCompilerContext): {
17
+ output: Record<string, string>;
18
+ result: TtscBuildResult;
19
+ } {
20
+ const cwd = path.resolve(options.cwd ?? process.cwd());
21
+ const project = readProjectConfig({
22
+ cwd,
23
+ tsconfig: options.tsconfig,
24
+ });
25
+ if (configuredPlugins(options, project).length !== 0) {
26
+ return compileProjectWithPlugins(options, cwd, project);
27
+ }
28
+ const tsconfig = project.path;
29
+ const binary = buildNativeCompiler({
30
+ cacheBaseDir: path.dirname(tsconfig),
31
+ cacheDir: options.cacheDir,
32
+ packageRoot: packageRootDir(),
33
+ });
34
+ const res = spawnSync(
35
+ binary,
36
+ ["api-compile", "--cwd", path.dirname(tsconfig), "--tsconfig", tsconfig],
37
+ {
38
+ cwd: path.dirname(tsconfig),
39
+ encoding: "utf8",
40
+ env: { ...process.env, ...options.env },
41
+ maxBuffer: 1024 * 1024 * 256,
42
+ windowsHide: true,
43
+ },
44
+ );
45
+ if (res.error) {
46
+ throw new Error(
47
+ `ttsc: failed to spawn native compiler host ${binary}: ${res.error.message}`,
48
+ );
49
+ }
50
+
51
+ const output = parseNativeCompileOutput(res.stdout, res.stderr);
52
+ return {
53
+ output: output.output,
54
+ result: {
55
+ diagnostics: output.diagnostics,
56
+ status: res.status ?? 1,
57
+ stdout: "",
58
+ stderr: res.stderr,
59
+ },
60
+ };
61
+ }
62
+
63
+ function configuredPlugins(
64
+ options: ITtscCompilerContext,
65
+ project: ITtscParsedProjectConfig,
66
+ ): ITtscProjectPluginConfig[] {
67
+ if (options.plugins === false) {
68
+ return [];
69
+ }
70
+ const entries = options.plugins ?? project.compilerOptions.plugins;
71
+ return entries.filter((entry) => entry.enabled !== false);
72
+ }
73
+
74
+ function compileProjectWithPlugins(
75
+ options: ITtscCompilerContext,
76
+ cwd: string,
77
+ project: ITtscParsedProjectConfig,
78
+ ): {
79
+ output: Record<string, string>;
80
+ result: TtscBuildResult;
81
+ } {
82
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-api-output-"));
83
+ const tempOutDir = path.join(tempRoot, "out");
84
+ try {
85
+ const result = runBuild({
86
+ ...options,
87
+ cwd,
88
+ emit: true,
89
+ forceListEmittedFiles: true,
90
+ outDir: tempOutDir,
91
+ quiet: true,
92
+ structuredDiagnostics: true,
93
+ tsconfig: project.path,
94
+ });
95
+ return {
96
+ output: readOutputDirectory(tempOutDir, outputKeyMapper(project)),
97
+ result,
98
+ };
99
+ } finally {
100
+ fs.rmSync(tempRoot, { force: true, recursive: true });
101
+ }
102
+ }
103
+
104
+ function outputKeyMapper(
105
+ project: ITtscParsedProjectConfig,
106
+ ): (relativePath: string) => string {
107
+ const outDir = project.compilerOptions.outDir;
108
+ if (!outDir) {
109
+ return (relativePath) => relativePath;
110
+ }
111
+ const relativeOutDir = path.relative(project.root, outDir);
112
+ if (relativeOutDir !== "" && !relativeOutDir.startsWith("..")) {
113
+ const prefix = pathToKey(relativeOutDir);
114
+ return (relativePath) => path.posix.join(prefix, relativePath);
115
+ }
116
+ return (relativePath) => pathToKey(path.join(outDir, relativePath));
117
+ }
118
+
119
+ function readOutputDirectory(
120
+ directory: string,
121
+ keyOf: (relativePath: string) => string,
122
+ ): Record<string, string> {
123
+ const output: Record<string, string> = {};
124
+ if (!fs.existsSync(directory)) {
125
+ return output;
126
+ }
127
+ for (const file of listFiles(directory)) {
128
+ output[keyOf(pathToKey(path.relative(directory, file)))] =
129
+ fs.readFileSync(file, "utf8");
130
+ }
131
+ return output;
132
+ }
133
+
134
+ function listFiles(directory: string): string[] {
135
+ const out: string[] = [];
136
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
137
+ const location = path.join(directory, entry.name);
138
+ if (entry.isDirectory()) {
139
+ out.push(...listFiles(location));
140
+ } else if (entry.isFile()) {
141
+ out.push(location);
142
+ }
143
+ }
144
+ return out.sort();
145
+ }
146
+
147
+ function pathToKey(file: string): string {
148
+ return file.replace(/\\/g, "/");
149
+ }
150
+
151
+ function parseNativeCompileOutput(
152
+ stdout: string,
153
+ stderr: string,
154
+ ): {
155
+ diagnostics: ITtscCompilerDiagnostic[];
156
+ output: Record<string, string>;
157
+ } {
158
+ try {
159
+ const parsed = JSON.parse(stdout) as {
160
+ diagnostics?: ITtscCompilerDiagnostic[];
161
+ output?: Record<string, string>;
162
+ };
163
+ return {
164
+ diagnostics: parsed.diagnostics ?? [],
165
+ output: parsed.output ?? {},
166
+ };
167
+ } catch {
168
+ throw new Error(
169
+ (stderr || stdout).trim() || "ttsc: native compiler host returned no output",
170
+ );
171
+ }
172
+ }
173
+
174
+ function packageRootDir(): string {
175
+ let current = path.resolve(__dirname);
176
+ while (true) {
177
+ if (
178
+ fs.existsSync(path.join(current, "package.json")) &&
179
+ fs.existsSync(path.join(current, "go.mod"))
180
+ ) {
181
+ return fs.realpathSync.native?.(current) ?? fs.realpathSync(current);
182
+ }
183
+ const parent = path.dirname(current);
184
+ if (parent === current) {
185
+ throw new Error("ttsc: package root not found for native compiler build");
186
+ }
187
+ current = parent;
188
+ }
189
+ }
@@ -1,58 +1,17 @@
1
- import * as crypto from "node:crypto";
2
1
  import * as fs from "node:fs";
3
2
  import { createRequire } from "node:module";
4
3
  import * as path from "node:path";
5
4
 
6
- import type { ITtscCacheKeyInput } from "./structures/ITtscCacheKeyInput";
7
- import type { ITtscParsedProjectConfig } from "./structures/ITtscParsedProjectConfig";
8
- import type { ITtscProjectLocatorOptions } from "./structures/ITtscProjectLocatorOptions";
9
- import type { ITtscProjectPluginConfig } from "./structures/ITtscProjectPluginConfig";
5
+ import type { ITtscProjectPluginConfig } from "../../../structures/ITtscProjectPluginConfig";
6
+ import type { ITtscParsedProjectConfig } from "../../../structures/internal/ITtscParsedProjectConfig";
7
+ import type { ITtscProjectLocatorOptions } from "../../../structures/internal/ITtscProjectLocatorOptions";
10
8
 
11
- export type { ITtscCacheKeyInput } from "./structures/ITtscCacheKeyInput";
12
- export type { ITtscParsedProjectConfig } from "./structures/ITtscParsedProjectConfig";
13
- export type { ITtscProjectLocatorOptions } from "./structures/ITtscProjectLocatorOptions";
14
- export type { ITtscProjectPluginConfig } from "./structures/ITtscProjectPluginConfig";
9
+ import { resolveProjectConfig } from "./resolveProjectConfig";
15
10
 
16
- export function resolveWorkingDirectory(cwd?: string): string {
17
- return path.resolve(cwd ?? process.cwd());
18
- }
19
-
20
- export function resolveAbsolutePath(cwd: string, target: string): string {
21
- return path.isAbsolute(target) ? target : path.resolve(cwd, target);
22
- }
23
-
24
- export function resolveProjectConfig(opts: ITtscProjectLocatorOptions = {}): string {
25
- const cwd = resolveWorkingDirectory(opts.cwd);
26
- if (opts.tsconfig) {
27
- const resolved = resolveAbsolutePath(cwd, opts.tsconfig);
28
- if (!fs.existsSync(resolved)) {
29
- throw new Error(`ttsc: tsconfig not found: ${resolved}`);
30
- }
31
- return resolveRealPath(resolved);
32
- }
33
-
34
- const start = opts.file
35
- ? resolveRealPath(resolveAbsolutePath(cwd, opts.file))
36
- : cwd;
37
- const from = isDirectory(start) ? start : path.dirname(start);
38
- const found = findUp(from, ["tsconfig.json", "jsconfig.json"]);
39
- if (!found) {
40
- throw new Error(
41
- `ttsc: could not find tsconfig.json or jsconfig.json starting from ${from}`,
42
- );
43
- }
44
- return resolveRealPath(found);
45
- }
46
-
47
- export function resolveProjectRoot(opts: ITtscProjectLocatorOptions = {}): string {
48
- return path.dirname(resolveProjectConfig(opts));
49
- }
50
-
51
- export function defaultCacheDirectory(projectRoot: string, tool: string): string {
52
- return path.join(projectRoot, "node_modules", ".cache", "ttsc", tool);
53
- }
54
-
55
- export function readProjectConfig(opts: ITtscProjectLocatorOptions = {}): ITtscParsedProjectConfig {
11
+ /** Read the resolved project config subset used by ttsc. */
12
+ export function readProjectConfig(
13
+ opts: ITtscProjectLocatorOptions = {},
14
+ ): ITtscParsedProjectConfig {
56
15
  const tsconfig = resolveProjectConfig(opts);
57
16
  const root = path.dirname(tsconfig);
58
17
  const compilerOptions = readResolvedCompilerOptions(tsconfig);
@@ -67,63 +26,12 @@ export function readProjectConfig(opts: ITtscProjectLocatorOptions = {}): ITtscP
67
26
  };
68
27
  }
69
28
 
70
- export function createTransformCacheKey(input: ITtscCacheKeyInput): string {
71
- const hash = crypto.createHash("sha256");
72
- hash.update("file\0");
73
- hash.update(fs.readFileSync(input.file));
74
- hash.update("\0tsconfig\0");
75
- hash.update(fs.readFileSync(input.tsconfig));
76
- hash.update(`\0version\0${input.version}`);
77
- hash.update(`\0mode\0${input.mode ?? ""}`);
78
- for (const item of input.extra ?? []) {
79
- hash.update(`\0extra\0${item}`);
80
- }
81
- return hash.digest("hex");
82
- }
83
-
84
- function findUp(from: string, names: readonly string[]): string | null {
85
- let current = path.resolve(from);
86
- while (true) {
87
- for (const name of names) {
88
- const candidate = path.join(current, name);
89
- if (fs.existsSync(candidate)) {
90
- return candidate;
91
- }
92
- }
93
- const parent = path.dirname(current);
94
- if (parent === current) {
95
- return null;
96
- }
97
- current = parent;
98
- }
99
- }
100
-
101
- function isDirectory(location: string): boolean {
102
- try {
103
- return fs.statSync(location).isDirectory();
104
- } catch {
105
- return false;
106
- }
107
- }
108
-
109
- function isProjectPluginConfig(value: unknown): value is ITtscProjectPluginConfig {
29
+ function isProjectPluginConfig(
30
+ value: unknown,
31
+ ): value is ITtscProjectPluginConfig {
110
32
  return typeof value === "object" && value !== null;
111
33
  }
112
34
 
113
- interface ITtscRawTsconfig {
114
- extends?: unknown;
115
- compilerOptions?: Record<string, unknown> & {
116
- outDir?: unknown;
117
- plugins?: unknown;
118
- };
119
- }
120
-
121
- interface ITtscResolvedCompilerOptions {
122
- options: Record<string, unknown>;
123
- outDir?: string;
124
- plugins: ITtscProjectPluginConfig[];
125
- }
126
-
127
35
  function resolveRealPath(location: string): string {
128
36
  try {
129
37
  return fs.realpathSync(location);
@@ -132,21 +40,38 @@ function resolveRealPath(location: string): string {
132
40
  }
133
41
  }
134
42
 
43
+ function resolveAbsolutePath(cwd: string, target: string): string {
44
+ return path.isAbsolute(target) ? target : path.resolve(cwd, target);
45
+ }
46
+
135
47
  function readResolvedCompilerOptions(
136
48
  tsconfig: string,
137
49
  seen: Set<string> = new Set(),
138
- ): ITtscResolvedCompilerOptions {
50
+ ): {
51
+ options: Record<string, unknown>;
52
+ outDir?: string;
53
+ plugins: ITtscProjectPluginConfig[];
54
+ } {
139
55
  const canonical = resolveRealPath(tsconfig);
140
56
  if (seen.has(canonical)) {
141
57
  throw new Error(`ttsc: circular tsconfig extends detected: ${canonical}`);
142
58
  }
143
59
  seen.add(canonical);
144
60
 
145
- const parsed = parseJsonc(fs.readFileSync(canonical, "utf8")) as ITtscRawTsconfig;
61
+ const parsed = parseJsonc(fs.readFileSync(canonical, "utf8")) as {
62
+ extends?: unknown;
63
+ compilerOptions?: Record<string, unknown> & {
64
+ outDir?: unknown;
65
+ plugins?: unknown;
66
+ };
67
+ };
146
68
  const own = parsed.compilerOptions;
147
69
  const base =
148
70
  typeof parsed.extends === "string"
149
- ? readResolvedCompilerOptions(resolveExtendsConfig(canonical, parsed.extends), seen)
71
+ ? readResolvedCompilerOptions(
72
+ resolveExtendsConfig(canonical, parsed.extends),
73
+ seen,
74
+ )
150
75
  : { options: {}, plugins: [] };
151
76
  const options = {
152
77
  ...base.options,
@@ -169,7 +94,7 @@ function resolveExtendsConfig(tsconfig: string, specifier: string): string {
169
94
  if (path.isAbsolute(specifier)) {
170
95
  return resolveExistingExtendsPath(specifier);
171
96
  }
172
- if (isRelativePluginSpecifier(specifier)) {
97
+ if (isRelativeSpecifier(specifier)) {
173
98
  return resolveExistingExtendsPath(path.resolve(baseDir, specifier));
174
99
  }
175
100
  const resolver = createRequire(tsconfig);
@@ -194,7 +119,7 @@ function resolveExistingExtendsPath(location: string): string {
194
119
  throw new Error(`ttsc: extended tsconfig not found: ${location}`);
195
120
  }
196
121
 
197
- function isRelativePluginSpecifier(specifier: string): boolean {
122
+ function isRelativeSpecifier(specifier: string): boolean {
198
123
  return (
199
124
  specifier === "." ||
200
125
  specifier === ".." ||
@@ -248,18 +173,18 @@ function stripComments(input: string): string {
248
173
  continue;
249
174
  }
250
175
 
251
- if ((current === '"' || current === "'") && !inString) {
176
+ if (current === '"' || current === "'") {
252
177
  inString = true;
253
178
  quote = current;
254
179
  output += current;
255
180
  continue;
256
181
  }
257
- if (current == "/" && next === "/") {
182
+ if (current === "/" && next === "/") {
258
183
  inLineComment = true;
259
184
  i += 1;
260
185
  continue;
261
186
  }
262
- if (current == "/" && next === "*") {
187
+ if (current === "/" && next === "*") {
263
188
  inBlockComment = true;
264
189
  i += 1;
265
190
  continue;
@@ -0,0 +1,67 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+
4
+ import type { ITtscProjectLocatorOptions } from "../../../structures/internal/ITtscProjectLocatorOptions";
5
+
6
+ /** Resolve the tsconfig/jsconfig that owns a ttsc invocation. */
7
+ export function resolveProjectConfig(
8
+ opts: ITtscProjectLocatorOptions = {},
9
+ ): string {
10
+ const cwd = path.resolve(opts.cwd ?? process.cwd());
11
+ if (opts.tsconfig) {
12
+ const resolved = resolveAbsolutePath(cwd, opts.tsconfig);
13
+ if (!fs.existsSync(resolved)) {
14
+ throw new Error(`ttsc: tsconfig not found: ${resolved}`);
15
+ }
16
+ return resolveRealPath(resolved);
17
+ }
18
+
19
+ const start = opts.file
20
+ ? resolveRealPath(resolveAbsolutePath(cwd, opts.file))
21
+ : cwd;
22
+ const from = isDirectory(start) ? start : path.dirname(start);
23
+ const found = findUp(from, ["tsconfig.json", "jsconfig.json"]);
24
+ if (!found) {
25
+ throw new Error(
26
+ `ttsc: could not find tsconfig.json or jsconfig.json starting from ${from}`,
27
+ );
28
+ }
29
+ return resolveRealPath(found);
30
+ }
31
+
32
+ function resolveAbsolutePath(cwd: string, target: string): string {
33
+ return path.isAbsolute(target) ? target : path.resolve(cwd, target);
34
+ }
35
+
36
+ function resolveRealPath(location: string): string {
37
+ try {
38
+ return fs.realpathSync(location);
39
+ } catch {
40
+ return location;
41
+ }
42
+ }
43
+
44
+ function findUp(from: string, names: readonly string[]): string | null {
45
+ let current = path.resolve(from);
46
+ while (true) {
47
+ for (const name of names) {
48
+ const candidate = path.join(current, name);
49
+ if (fs.existsSync(candidate)) {
50
+ return candidate;
51
+ }
52
+ }
53
+ const parent = path.dirname(current);
54
+ if (parent === current) {
55
+ return null;
56
+ }
57
+ current = parent;
58
+ }
59
+ }
60
+
61
+ function isDirectory(location: string): boolean {
62
+ try {
63
+ return fs.statSync(location).isDirectory();
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
@@ -0,0 +1,41 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+
4
+ /** Resolve the ttsc helper binary path, or null when unavailable. */
5
+ export function resolveBinary(
6
+ opts: { env?: NodeJS.ProcessEnv } = {},
7
+ ): string | null {
8
+ const env = opts.env ?? process.env;
9
+ if (env.TTSC_BINARY && path.isAbsolute(env.TTSC_BINARY)) {
10
+ return env.TTSC_BINARY;
11
+ }
12
+
13
+ try {
14
+ return require.resolve(
15
+ `@ttsc/${process.platform}-${process.arch}/bin/${process.platform === "win32" ? "ttsc.exe" : "ttsc"}`,
16
+ );
17
+ } catch {
18
+ /* fall through */
19
+ }
20
+
21
+ const local = defaultLocalBinaryPath();
22
+ if (local) return local;
23
+
24
+ return null;
25
+ }
26
+
27
+ function defaultLocalBinaryPath(): string | null {
28
+ const root = packageRootDir();
29
+ const candidate = path.resolve(
30
+ root,
31
+ "..",
32
+ "native",
33
+ process.platform === "win32" ? "ttsc-native.exe" : "ttsc-native",
34
+ );
35
+ return fs.existsSync(candidate) ? candidate : null;
36
+ }
37
+
38
+ function packageRootDir(): string {
39
+ const moduleDir = path.resolve(__dirname, "..", "..");
40
+ return fs.realpathSync.native?.(moduleDir) ?? fs.realpathSync(moduleDir);
41
+ }
@@ -0,0 +1,102 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+
4
+ /** Locate the JavaScript file emitted for a TypeScript source file. */
5
+ export function resolveEmittedJavaScript(options: {
6
+ emittedFiles?: readonly string[];
7
+ outDir: string;
8
+ projectRoot: string;
9
+ sourceFile: string;
10
+ }): string | null {
11
+ const exact = resolveExactEmittedFile(
12
+ options.outDir,
13
+ options.projectRoot,
14
+ options.sourceFile,
15
+ );
16
+ if (exact && fs.existsSync(exact)) {
17
+ return exact;
18
+ }
19
+
20
+ let best: string | null = null;
21
+ let bestScore = 0;
22
+ for (const file of options.emittedFiles ?? listJavaScriptFiles(options.outDir)) {
23
+ if (!isJavaScriptOutput(file)) continue;
24
+ const score = sharedSourceStemSegments(file, options.sourceFile);
25
+ if (score > bestScore) {
26
+ best = file;
27
+ bestScore = score;
28
+ }
29
+ }
30
+ return best && fs.existsSync(best) ? best : null;
31
+ }
32
+
33
+ function resolveExactEmittedFile(
34
+ outDir: string,
35
+ projectRoot: string,
36
+ sourceFile: string,
37
+ ): string | null {
38
+ const relative = path.relative(projectRoot, sourceFile);
39
+ if (
40
+ relative === "" ||
41
+ relative.startsWith("..") ||
42
+ path.isAbsolute(relative)
43
+ ) {
44
+ return null;
45
+ }
46
+ return path.resolve(
47
+ outDir,
48
+ relative.slice(0, relative.length - path.extname(relative).length) +
49
+ emittedJavaScriptExtension(sourceFile),
50
+ );
51
+ }
52
+
53
+ function listJavaScriptFiles(root: string): string[] {
54
+ const out: string[] = [];
55
+ const stack = [root];
56
+ while (stack.length !== 0) {
57
+ const current = stack.pop()!;
58
+ if (!fs.existsSync(current)) continue;
59
+ for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
60
+ const next = path.join(current, entry.name);
61
+ if (entry.isDirectory()) {
62
+ stack.push(next);
63
+ } else if (entry.isFile() && isJavaScriptOutput(next)) {
64
+ out.push(path.resolve(next));
65
+ }
66
+ }
67
+ }
68
+ return out;
69
+ }
70
+
71
+ function sharedSourceStemSegments(outPath: string, srcPath: string): number {
72
+ const trim = (location: string): string[] => {
73
+ const normalized = location.replace(/\\/g, "/");
74
+ return normalized
75
+ .slice(0, normalized.length - path.extname(normalized).length)
76
+ .split("/");
77
+ };
78
+ const a = trim(outPath);
79
+ const b = trim(srcPath);
80
+ const count = Math.min(a.length, b.length);
81
+ let shared = 0;
82
+ for (let i = 1; i <= count; i += 1) {
83
+ if (a[a.length - i] !== b[b.length - i]) break;
84
+ shared += 1;
85
+ }
86
+ return shared;
87
+ }
88
+
89
+ function emittedJavaScriptExtension(filename: string): string {
90
+ switch (path.extname(filename).toLowerCase()) {
91
+ case ".mts":
92
+ return ".mjs";
93
+ case ".cts":
94
+ return ".cjs";
95
+ default:
96
+ return ".js";
97
+ }
98
+ }
99
+
100
+ function isJavaScriptOutput(filename: string): boolean {
101
+ return /\.(?:[cm]?js)$/i.test(filename);
102
+ }
@@ -2,21 +2,15 @@ import * as fs from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import * as path from "node:path";
4
4
 
5
- import type { ITtscResolvedTsgo } from "./structures/ITtscResolvedTsgo";
6
- import type { ITtscTsgoResolveOptions } from "./structures/ITtscTsgoResolveOptions";
7
5
 
8
- export type { ITtscResolvedTsgo } from "./structures/ITtscResolvedTsgo";
9
- export type { ITtscTsgoResolveOptions } from "./structures/ITtscTsgoResolveOptions";
10
-
11
- export function nativePreviewPlatformPackage(
12
- opts: ITtscTsgoResolveOptions = {},
13
- ): string {
14
- return `@typescript/native-preview-${opts.platform ?? process.platform}-${
15
- opts.arch ?? process.arch
16
- }`;
17
- }
18
-
19
- export function resolveTsgo(opts: ITtscTsgoResolveOptions = {}): ITtscResolvedTsgo {
6
+ /** Resolve the consumer project's TypeScript-Go preview binary. */
7
+ export function resolveTsgo(
8
+ opts: {
9
+ binary?: string;
10
+ cwd?: string;
11
+ env?: NodeJS.ProcessEnv;
12
+ } = {},
13
+ ) {
20
14
  const env = opts.env ?? process.env;
21
15
  const explicit = opts.binary ?? env.TTSC_TSGO_BINARY;
22
16
  if (explicit) {
@@ -34,12 +28,11 @@ export function resolveTsgo(opts: ITtscTsgoResolveOptions = {}): ITtscResolvedTs
34
28
  }
35
29
 
36
30
  const cwd = path.resolve(opts.cwd ?? process.cwd());
37
- const resolver =
38
- opts.resolver ??
39
- ((request: string) => createRequire(path.join(cwd, "package.json")).resolve(request));
40
31
  let packageJson: string;
41
32
  try {
42
- packageJson = resolver("@typescript/native-preview/package.json");
33
+ packageJson = createRequire(path.join(cwd, "package.json")).resolve(
34
+ "@typescript/native-preview/package.json",
35
+ );
43
36
  } catch {
44
37
  throw new Error(
45
38
  [
@@ -52,11 +45,13 @@ export function resolveTsgo(opts: ITtscTsgoResolveOptions = {}): ITtscResolvedTs
52
45
 
53
46
  const manifest = readPackageJson(packageJson);
54
47
  const packageRoot = path.dirname(packageJson);
55
- const platformPackage = nativePreviewPlatformPackage(opts);
48
+ const platformPackage = `@typescript/native-preview-${process.platform}-${process.arch}`;
56
49
  const platformResolver = createRequire(packageJson);
57
50
  let platformPackageJson: string;
58
51
  try {
59
- platformPackageJson = platformResolver.resolve(`${platformPackage}/package.json`);
52
+ platformPackageJson = platformResolver.resolve(
53
+ `${platformPackage}/package.json`,
54
+ );
60
55
  } catch {
61
56
  throw new Error(
62
57
  [
@@ -70,18 +65,20 @@ export function resolveTsgo(opts: ITtscTsgoResolveOptions = {}): ITtscResolvedTs
70
65
  const binary = path.join(
71
66
  platformRoot,
72
67
  "lib",
73
- (opts.platform ?? process.platform) === "win32" ? "tsgo.exe" : "tsgo",
68
+ process.platform === "win32" ? "tsgo.exe" : "tsgo",
74
69
  );
75
70
  if (!fs.existsSync(binary)) {
76
71
  throw new Error(`ttsc: TypeScript-Go executable not found: ${binary}`);
77
72
  }
78
73
  return {
79
74
  binary,
80
- gitHead: typeof manifest.gitHead === "string" ? manifest.gitHead : undefined,
75
+ gitHead:
76
+ typeof manifest.gitHead === "string" ? manifest.gitHead : undefined,
81
77
  packageJson,
82
78
  packageRoot,
83
79
  platformPackageJson,
84
- version: typeof manifest.version === "string" ? manifest.version : "unknown",
80
+ version:
81
+ typeof manifest.version === "string" ? manifest.version : "unknown",
85
82
  };
86
83
  }
87
84