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
package/src/index.ts CHANGED
@@ -1,20 +1,11 @@
1
1
  /**
2
2
  * ttsc — public TypeScript entry.
3
3
  *
4
- * Exports:
5
- * - tsgo helpers (`resolveTsgo`, …) — resolve the consuming project's
6
- * `@typescript/native-preview` compiler binary.
7
- * - platform helpers (`resolveBinary`, `installHint`, …) — compatibility
8
- * helper resolution for commands such as `ttsc demo`.
9
- * - programmatic API (`transform`, `build`, `check`, `version`) — a thin
10
- * TS wrapper around the consumer `tsgo` binary and native plugin
11
- * descriptors. Adapters never have to shell out themselves; they call
12
- * these helpers and get back a string or a result record.
4
+ * The package root intentionally exposes only the programmatic compiler class
5
+ * and the plugin-author contracts. CLI launcher functions, binary resolution,
6
+ * project parsing helpers, and native build helpers stay internal so the
7
+ * public package surface remains small and stable.
13
8
  */
14
9
 
15
- export * from "./platform";
16
- export * from "./api";
17
- export * from "./project";
18
- export * from "./plugin";
19
- export * from "./tsgo";
20
- export * from "./runner/register";
10
+ export * from "./TtscCompiler";
11
+ export * from "./structures/index";
@@ -0,0 +1,44 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+
5
+ import { resolveTsgo } from "../../compiler/internal/resolveTsgo";
6
+ import type { TtscCommonOptions } from "../../structures/internal/TtscCommonOptions";
7
+
8
+ /** Format the CLI version banner from the wrapper package and resolved tsgo. */
9
+ export function getCompilerVersionText(
10
+ options: TtscCommonOptions = {},
11
+ ): string {
12
+ const tsgo = resolveTsgo(options);
13
+ const res = spawnSync(tsgo.binary, ["--version"], {
14
+ encoding: "utf8",
15
+ maxBuffer: 1024 * 1024 * 16,
16
+ windowsHide: true,
17
+ });
18
+ if (res.error || res.status !== 0) {
19
+ throw new Error(
20
+ "ttsc.version: failed: " +
21
+ (outputText(res.stderr) || res.error?.message),
22
+ );
23
+ }
24
+ return `ttsc ${readOwnPackageVersion()} (${outputText(res.stdout).trim()})`;
25
+ }
26
+
27
+ function outputText(value: string | Buffer | null | undefined): string {
28
+ if (value == null) {
29
+ return "";
30
+ }
31
+ return typeof value === "string" ? value : value.toString("utf8");
32
+ }
33
+
34
+ function readOwnPackageVersion(): string {
35
+ try {
36
+ const file = path.resolve(__dirname, "..", "..", "..", "package.json");
37
+ const pkg = JSON.parse(fs.readFileSync(file, "utf8")) as {
38
+ version?: string;
39
+ };
40
+ return pkg.version ?? "0.0.0";
41
+ } catch {
42
+ return "0.0.0";
43
+ }
44
+ }
@@ -0,0 +1,115 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+
4
+ import { resolveEmittedJavaScript } from "../../compiler/internal/resolveEmittedJavaScript";
5
+ import { runBuild } from "../../compiler/internal/runBuild";
6
+ import { resolveProjectConfig } from "../../compiler/internal/project/resolveProjectConfig";
7
+ import type { TtscCommonOptions } from "../../structures/internal/TtscCommonOptions";
8
+
9
+ const PROCESS_CACHE_KEY = String(process.pid);
10
+
11
+ /** Build the owning project and locate the emitted JavaScript entry for `ttsx`. */
12
+ export function prepareExecution(
13
+ entryFile: string,
14
+ options: TtscCommonOptions & {
15
+ cacheDir?: string;
16
+ project?: string;
17
+ } = {},
18
+ ): {
19
+ emitDir: string;
20
+ entryFile: string;
21
+ moduleKind: "cjs" | "esm";
22
+ } {
23
+ const context = createProjectContext(
24
+ path.resolve(options.cwd ?? process.cwd()),
25
+ entryFile,
26
+ options,
27
+ );
28
+ buildProject(context, options);
29
+ const emittedEntry = resolveEmittedJavaScript({
30
+ emittedFiles: context.emittedFiles ?? undefined,
31
+ outDir: context.emitDir,
32
+ projectRoot: context.root,
33
+ sourceFile: entryFile,
34
+ });
35
+ if (emittedEntry === null) {
36
+ throw new Error(`ttsx: emitted entry not found for ${entryFile}`);
37
+ }
38
+ const output = fs.readFileSync(emittedEntry, "utf8");
39
+ return {
40
+ emitDir: context.emitDir,
41
+ entryFile: emittedEntry,
42
+ moduleKind: looksLikeESM(output) ? "esm" : "cjs",
43
+ };
44
+ }
45
+
46
+ function createProjectContext(
47
+ cwd: string,
48
+ filename: string,
49
+ options: NonNullable<Parameters<typeof prepareExecution>[1]>,
50
+ ) {
51
+ const tsconfig = options.project
52
+ ? resolveProjectConfig({ cwd, tsconfig: path.resolve(cwd, options.project) })
53
+ : resolveProjectConfig({ cwd, file: filename });
54
+ const root = path.dirname(tsconfig);
55
+ const cacheDir =
56
+ options.cacheDir ?? path.join(root, "node_modules", ".cache", "ttsc", "ttsx");
57
+ return {
58
+ tsconfig,
59
+ root,
60
+ cacheDir,
61
+ emitDir: path.join(cacheDir, "project", PROCESS_CACHE_KEY),
62
+ built: false,
63
+ emittedFiles: undefined as string[] | undefined,
64
+ };
65
+ }
66
+
67
+ function buildProject(
68
+ context: ReturnType<typeof createProjectContext>,
69
+ options: NonNullable<Parameters<typeof prepareExecution>[1]>,
70
+ ): void {
71
+ if (context.built) return;
72
+
73
+ fs.mkdirSync(context.cacheDir, { recursive: true });
74
+ fs.rmSync(context.emitDir, { recursive: true, force: true });
75
+ const result = runBuild({
76
+ binary: options.binary,
77
+ cwd: context.root,
78
+ emit: true,
79
+ env: options.env,
80
+ forceListEmittedFiles: true,
81
+ outDir: context.emitDir,
82
+ plugins: options.plugins,
83
+ quiet: true,
84
+ tsconfig: context.tsconfig,
85
+ });
86
+ if (result.status === 0) {
87
+ context.built = true;
88
+ context.emittedFiles =
89
+ result.emittedFiles && result.emittedFiles.length !== 0
90
+ ? result.emittedFiles
91
+ : undefined;
92
+ return;
93
+ }
94
+
95
+ fs.rmSync(context.emitDir, { recursive: true, force: true });
96
+ const detail = [
97
+ `ttsx: project check failed for ${context.tsconfig}`,
98
+ result.stderr || result.stdout,
99
+ ]
100
+ .filter((line) => line.trim().length !== 0)
101
+ .join("\n");
102
+ throw new Error(detail);
103
+ }
104
+
105
+ function looksLikeESM(output: string): boolean {
106
+ if (
107
+ /\bObject\.defineProperty\(exports\b/.test(output) ||
108
+ /\bmodule\.exports\b/.test(output) ||
109
+ /\brequire\(/.test(output) ||
110
+ /\bexports\./.test(output)
111
+ ) {
112
+ return false;
113
+ }
114
+ return /^\s*(import|export)\s/m.test(output);
115
+ }
@@ -2,19 +2,15 @@ import { spawnSync } from "node:child_process";
2
2
  import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
4
 
5
- import {
6
- type ITtscBuildOptions,
7
- type ITtscTransformOptions,
8
- build,
9
- check,
10
- transform,
11
- version,
12
- } from "./api";
13
- import { installHint, resolveBinary } from "./platform";
14
- import { resolveProjectConfig, resolveProjectRoot } from "./project";
15
- import { pluginCacheCleanupTargets } from "./source-build";
5
+ import { resolveBinary } from "../../compiler/internal/resolveBinary";
6
+ import { runBuild } from "../../compiler/internal/runBuild";
7
+ import { runTransform } from "../../compiler/internal/runTransform";
8
+ import { resolveProjectConfig } from "../../compiler/internal/project/resolveProjectConfig";
9
+ import type { TtscBuildOptions } from "../../structures/internal/TtscBuildOptions";
10
+ import type { TtscTransformOptions } from "../../structures/internal/TtscTransformOptions";
11
+ import { getCompilerVersionText } from "./getCompilerVersionText";
16
12
 
17
- export function main(argv: readonly string[] = process.argv.slice(2)): number {
13
+ export function runTtsc(argv: readonly string[] = process.argv.slice(2)): number {
18
14
  try {
19
15
  if (argv.length === 0) {
20
16
  return runCompatibleBuild([], false);
@@ -30,7 +26,7 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
30
26
  case "-v":
31
27
  case "--version":
32
28
  case "version":
33
- process.stdout.write(`${version()}\n`);
29
+ process.stdout.write(`${getCompilerVersionText()}\n`);
34
30
  return 0;
35
31
  case "build":
36
32
  return runCompatibleBuild(rest, false);
@@ -39,7 +35,7 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
39
35
  case "clean":
40
36
  return runClean(rest);
41
37
  case "transform":
42
- return runTransform(rest);
38
+ return runTransformCommand(rest);
43
39
  case "demo":
44
40
  return delegateToNative(argv);
45
41
  case "-p":
@@ -70,12 +66,6 @@ function isBuildAlias(command: string): boolean {
70
66
  );
71
67
  }
72
68
 
73
- interface ITtscBuildInvocation extends ITtscBuildOptions {
74
- files: string[];
75
- preserveWatchOutput: boolean;
76
- watch: boolean;
77
- }
78
-
79
69
  function runCompatibleBuild(
80
70
  argv: readonly string[],
81
71
  checkOnly: boolean,
@@ -87,31 +77,32 @@ function runCompatibleBuild(
87
77
  if (options.files.length !== 0) {
88
78
  return runSingleFile(options);
89
79
  }
90
- const result = checkOnly ? check(options) : build(options);
80
+ const result = runBuild(checkOnly ? { ...options, emit: false } : options);
91
81
  if (result.stdout) process.stdout.write(result.stdout);
92
82
  if (result.stderr) process.stderr.write(result.stderr);
93
83
  return result.status;
94
84
  }
95
85
 
96
- function runTransform(argv: readonly string[]): number {
86
+ function runTransformCommand(argv: readonly string[]): number {
97
87
  const options = parseTransformArgs(argv);
98
- const text = transform(options);
88
+ const text = runTransform(options);
99
89
  if (!options.out) {
100
90
  process.stdout.write(text);
101
91
  }
102
92
  return 0;
103
93
  }
104
94
 
105
- interface ITtscCleanInvocation {
106
- cwd?: string;
107
- tsconfig?: string;
108
- }
109
-
110
95
  function runClean(argv: readonly string[]): number {
111
96
  const options = parseCleanArgs(argv);
112
97
  const cwd = path.resolve(options.cwd ?? process.cwd());
113
98
  const projectRoot = resolveCleanProjectRoot(cwd, options.tsconfig);
114
- const targets = pluginCacheCleanupTargets(projectRoot);
99
+ const targets = [
100
+ path.join(projectRoot, "node_modules", ".ttsc"),
101
+ path.join(projectRoot, ".ttsc"),
102
+ ...(process.env.TTSC_CACHE_DIR
103
+ ? [path.resolve(process.env.TTSC_CACHE_DIR, "plugins")]
104
+ : []),
105
+ ];
115
106
  const removed: string[] = [];
116
107
  for (const target of targets) {
117
108
  if (!fs.existsSync(target)) continue;
@@ -119,7 +110,9 @@ function runClean(argv: readonly string[]): number {
119
110
  removed.push(target);
120
111
  }
121
112
  if (removed.length === 0) {
122
- process.stdout.write(`ttsc: no cache directories found under ${projectRoot}\n`);
113
+ process.stdout.write(
114
+ `ttsc: no cache directories found under ${projectRoot}\n`,
115
+ );
123
116
  return 0;
124
117
  }
125
118
  for (const target of removed) {
@@ -148,10 +141,18 @@ function formatCleanPath(cwd: string, target: string): string {
148
141
  function delegateToNative(argv: readonly string[]): number {
149
142
  const bin = resolveBinary();
150
143
  if (!bin) {
151
- process.stderr.write(`${installHint()}\n`);
144
+ process.stderr.write(
145
+ [
146
+ `ttsc: platform-specific helper binary not found (@ttsc/${process.platform}-${process.arch}).`,
147
+ `Set TTSC_BINARY to an absolute helper path or reinstall with optional dependencies enabled.`,
148
+ ].join("\n") + "\n",
149
+ );
152
150
  return 1;
153
151
  }
154
152
  const viaNode = /\.(?:[cm]?js|ts)$/i.test(bin);
153
+ if (!viaNode) {
154
+ ensureExecutable(bin);
155
+ }
155
156
  const result = spawnSync(
156
157
  viaNode ? process.execPath : bin,
157
158
  viaNode ? [bin, ...argv] : [...argv],
@@ -168,7 +169,22 @@ function delegateToNative(argv: readonly string[]): number {
168
169
  return result.status ?? 1;
169
170
  }
170
171
 
171
- function parseCleanArgs(argv: readonly string[]): ITtscCleanInvocation {
172
+ function ensureExecutable(binary: string): void {
173
+ if (process.platform === "win32") {
174
+ return;
175
+ }
176
+ try {
177
+ const mode = fs.statSync(binary).mode & 0o777;
178
+ if ((mode & 0o111) !== 0) {
179
+ return;
180
+ }
181
+ fs.chmodSync(binary, mode | 0o755);
182
+ } catch {
183
+ /* keep the original spawn error path */
184
+ }
185
+ }
186
+
187
+ function parseCleanArgs(argv: readonly string[]) {
172
188
  let cwd: string | undefined;
173
189
  let tsconfig: string | undefined;
174
190
 
@@ -203,7 +219,7 @@ function parseCleanArgs(argv: readonly string[]): ITtscCleanInvocation {
203
219
  function parseBuildArgs(
204
220
  argv: readonly string[],
205
221
  checkOnly: boolean,
206
- ): ITtscBuildInvocation {
222
+ ) {
207
223
  let binary: string | undefined;
208
224
  let cwd: string | undefined;
209
225
  let emit: boolean | undefined = checkOnly ? false : undefined;
@@ -211,7 +227,6 @@ function parseBuildArgs(
211
227
  let outDir: string | undefined;
212
228
  let preserveWatchOutput = false;
213
229
  let quiet = true;
214
- let rewriteMode: string | undefined;
215
230
  let tsconfig: string | undefined;
216
231
  let watch = false;
217
232
 
@@ -238,9 +253,6 @@ function parseBuildArgs(
238
253
  case "--preserveWatchOutput":
239
254
  preserveWatchOutput = true;
240
255
  break;
241
- case "--rewrite-mode":
242
- rewriteMode = takeRewriteMode(takeValue(current, rest));
243
- break;
244
256
  case "--cwd":
245
257
  cwd = takeValue(current, rest);
246
258
  break;
@@ -262,10 +274,6 @@ function parseBuildArgs(
262
274
  outDir = current.slice("--outDir=".length);
263
275
  } else if (current === "-w") {
264
276
  watch = true;
265
- } else if (current.startsWith("--rewrite-mode=")) {
266
- rewriteMode = takeRewriteMode(
267
- current.slice("--rewrite-mode=".length),
268
- );
269
277
  } else if (current.startsWith("--tsconfig=")) {
270
278
  tsconfig = current.slice("--tsconfig=".length);
271
279
  } else if (current.startsWith("--project=")) {
@@ -293,18 +301,16 @@ function parseBuildArgs(
293
301
  outDir,
294
302
  preserveWatchOutput,
295
303
  quiet,
296
- rewriteMode,
297
304
  tsconfig,
298
305
  watch,
299
306
  };
300
307
  }
301
308
 
302
- function parseTransformArgs(argv: readonly string[]): ITtscTransformOptions {
309
+ function parseTransformArgs(argv: readonly string[]): TtscTransformOptions {
303
310
  let binary: string | undefined;
304
311
  let cwd: string | undefined;
305
312
  let file: string | undefined;
306
313
  let out: string | undefined;
307
- let rewriteMode: string | undefined;
308
314
  let tsconfig: string | undefined;
309
315
 
310
316
  const rest = [...argv];
@@ -323,9 +329,6 @@ function parseTransformArgs(argv: readonly string[]): ITtscTransformOptions {
323
329
  case "--out":
324
330
  out = takeValue(current, rest);
325
331
  break;
326
- case "--rewrite-mode":
327
- rewriteMode = takeRewriteMode(takeValue(current, rest));
328
- break;
329
332
  case "--tsconfig":
330
333
  case "--project":
331
334
  tsconfig = takeValue(current, rest);
@@ -339,10 +342,6 @@ function parseTransformArgs(argv: readonly string[]): ITtscTransformOptions {
339
342
  file = current.slice("--file=".length);
340
343
  } else if (current.startsWith("--out=")) {
341
344
  out = current.slice("--out=".length);
342
- } else if (current.startsWith("--rewrite-mode=")) {
343
- rewriteMode = takeRewriteMode(
344
- current.slice("--rewrite-mode=".length),
345
- );
346
345
  } else if (current.startsWith("--tsconfig=")) {
347
346
  tsconfig = current.slice("--tsconfig=".length);
348
347
  } else if (current.startsWith("--project=")) {
@@ -361,7 +360,6 @@ function parseTransformArgs(argv: readonly string[]): ITtscTransformOptions {
361
360
  cwd,
362
361
  file,
363
362
  out,
364
- rewriteMode,
365
363
  tsconfig,
366
364
  };
367
365
  }
@@ -390,7 +388,6 @@ function printHelp(): void {
390
388
  " -w, --watch Rebuild when project files change",
391
389
  " --preserveWatchOutput Do not clear the screen between watch rebuilds",
392
390
  " --outDir <dir> Override compilerOptions.outDir for this invocation",
393
- " --rewrite-mode <mode> Plugin-selected native rewrite backend id",
394
391
  " --quiet Keep build output quiet (default)",
395
392
  " --verbose Print the build summary and emitted files",
396
393
  " --out <path> Write transform output to a file instead of stdout",
@@ -410,7 +407,7 @@ function printHelp(): void {
410
407
  process.stdout.write("\n");
411
408
  }
412
409
 
413
- function runSingleFile(options: ITtscBuildInvocation): number {
410
+ function runSingleFile(options: ReturnType<typeof parseBuildArgs>): number {
414
411
  if (options.files.length !== 1) {
415
412
  throw new Error(
416
413
  "ttsc: single-file mode currently accepts exactly one input file",
@@ -419,12 +416,11 @@ function runSingleFile(options: ITtscBuildInvocation): number {
419
416
  const cwd = path.resolve(options.cwd ?? process.cwd());
420
417
  const file = path.resolve(cwd, options.files[0]!);
421
418
  const out = resolveSingleFileOut(file, cwd, options.outDir);
422
- const text = transform({
419
+ const text = runTransform({
423
420
  binary: options.binary,
424
421
  cwd,
425
422
  file,
426
423
  out,
427
- rewriteMode: options.rewriteMode,
428
424
  tsconfig: options.tsconfig,
429
425
  });
430
426
  if (!fs.existsSync(out)) {
@@ -448,9 +444,12 @@ function resolveSingleFileOut(
448
444
  return file.replace(/\.[cm]?tsx?$/i, ".js");
449
445
  }
450
446
 
451
- function runWatch(options: ITtscBuildInvocation, checkOnly: boolean): number {
447
+ function runWatch(
448
+ options: ReturnType<typeof parseBuildArgs>,
449
+ checkOnly: boolean,
450
+ ): number {
452
451
  const cwd = path.resolve(options.cwd ?? process.cwd());
453
- const invocation: ITtscBuildInvocation = {
452
+ const invocation = {
454
453
  ...options,
455
454
  cwd,
456
455
  quiet: true,
@@ -461,10 +460,7 @@ function runWatch(options: ITtscBuildInvocation, checkOnly: boolean): number {
461
460
  tsconfig: options.tsconfig,
462
461
  }),
463
462
  );
464
- const watchRoot = resolveProjectRoot({
465
- cwd,
466
- tsconfig: options.tsconfig,
467
- });
463
+ const watchRoot = root;
468
464
  const directories = collectWatchDirectories(watchRoot);
469
465
  const watchers = directories.map((dir) =>
470
466
  fs.watch(dir, { persistent: true }, () => trigger()),
@@ -485,7 +481,9 @@ function runWatch(options: ITtscBuildInvocation, checkOnly: boolean): number {
485
481
  invocation.files.length !== 0
486
482
  ? runSingleFile(invocation)
487
483
  : (() => {
488
- const result = checkOnly ? check(invocation) : build(invocation);
484
+ const result = runBuild(
485
+ checkOnly ? { ...invocation, emit: false } : invocation,
486
+ );
489
487
  if (result.stdout) process.stdout.write(result.stdout);
490
488
  if (result.stderr) process.stderr.write(result.stderr);
491
489
  return result.status;
@@ -557,13 +555,6 @@ function takeValue(flag: string, rest: string[]): string {
557
555
  return value;
558
556
  }
559
557
 
560
- function takeRewriteMode(value: string): string {
561
- if (value.length === 0) {
562
- throw new Error("ttsc: rewrite mode must not be empty");
563
- }
564
- return value;
565
- }
566
-
567
558
  function formatError(error: unknown): string {
568
559
  if (error instanceof Error) {
569
560
  return error.message;
@@ -1,23 +1,11 @@
1
1
  import * as fs from "node:fs";
2
- import Module = require("node:module");
3
2
  import { spawnSync } from "node:child_process";
4
3
  import * as path from "node:path";
5
4
 
6
- import { version } from "../api";
7
- import {
8
- prepareExecution,
9
- register,
10
- type ITtscPreparedExecution,
11
- type ITtscRegisterOptions,
12
- } from "./register";
5
+ import { getCompilerVersionText } from "./getCompilerVersionText";
6
+ import { prepareExecution } from "./prepareExecution";
13
7
 
14
- interface ITtscParsedCLI extends ITtscRegisterOptions {
15
- entry: string;
16
- passthrough: string[];
17
- preload: string[];
18
- }
19
-
20
- export function main(argv: readonly string[] = process.argv.slice(2)): number {
8
+ export function runTtsx(argv: readonly string[] = process.argv.slice(2)): number {
21
9
  try {
22
10
  return run(argv);
23
11
  } catch (error) {
@@ -33,7 +21,9 @@ function run(argv: readonly string[]): number {
33
21
  return 0;
34
22
  }
35
23
  if (parsed === "version") {
36
- process.stdout.write(`${version().replace(/^ttsc\b/, "ttsx")}\n`);
24
+ process.stdout.write(
25
+ `${getCompilerVersionText().replace(/^ttsc\b/, "ttsx")}\n`,
26
+ );
37
27
  return 0;
38
28
  }
39
29
 
@@ -48,29 +38,9 @@ function run(argv: readonly string[]): number {
48
38
  binary: parsed.binary,
49
39
  cacheDir: parsed.cacheDir,
50
40
  cwd,
51
- env: parsed.env,
52
- extensions: parsed.extensions,
53
41
  project: parsed.project,
54
42
  });
55
- if (prepared.moduleKind === "esm") {
56
- return runEsmEntry(parsed, prepared, cwd);
57
- }
58
-
59
- const unregister = register({
60
- binary: parsed.binary,
61
- cacheDir: parsed.cacheDir,
62
- cwd,
63
- env: parsed.env,
64
- extensions: parsed.extensions,
65
- project: parsed.project,
66
- });
67
- process.once("exit", unregister);
68
- for (const preload of parsed.preload) {
69
- require(resolvePreload(cwd, preload));
70
- }
71
- process.argv = [process.execPath, entry, ...parsed.passthrough];
72
- Module.runMain();
73
- return 0;
43
+ return runPreparedEntry(parsed, prepared, cwd);
74
44
  }
75
45
 
76
46
  function formatError(error: unknown): string {
@@ -80,7 +50,7 @@ function formatError(error: unknown): string {
80
50
  return String(error);
81
51
  }
82
52
 
83
- function parseCLI(argv: readonly string[]): ITtscParsedCLI | "help" | "version" {
53
+ function parseCLI(argv: readonly string[]) {
84
54
  const preload: string[] = [];
85
55
  const passthroughIndex = argv.indexOf("--");
86
56
  const head = passthroughIndex === -1 ? [...argv] : [...argv.slice(0, passthroughIndex)];
@@ -172,10 +142,6 @@ function printHelp(): void {
172
142
  " -h, --help Show this help",
173
143
  " -v, --version Print the runner version",
174
144
  "",
175
- "Runtime:",
176
- " CommonJS projects execute in-process via the require hook.",
177
- " ESM projects execute the cached emitted entry in a child Node process.",
178
- "",
179
145
  "Examples:",
180
146
  " ttsx src/index.ts",
181
147
  " ttsx --project tsconfig.json src/index.ts -- --port 3000",
@@ -199,14 +165,20 @@ function takeValue(flag: string, rest: string[]): string {
199
165
  return value;
200
166
  }
201
167
 
202
- function runEsmEntry(parsed: ITtscParsedCLI, execution: ITtscPreparedExecution, cwd: string): number {
168
+ function runPreparedEntry(
169
+ parsed: Exclude<ReturnType<typeof parseCLI>, "help" | "version">,
170
+ execution: ReturnType<typeof prepareExecution>,
171
+ cwd: string,
172
+ ): number {
203
173
  fs.mkdirSync(execution.emitDir, { recursive: true });
204
- rewriteEsmSpecifiers(execution.emitDir);
205
- fs.writeFileSync(
206
- path.join(execution.emitDir, "package.json"),
207
- JSON.stringify({ type: "module" }),
208
- "utf8",
209
- );
174
+ if (execution.moduleKind === "esm") {
175
+ rewriteEsmSpecifiers(execution.emitDir);
176
+ fs.writeFileSync(
177
+ path.join(execution.emitDir, "package.json"),
178
+ JSON.stringify({ type: "module" }),
179
+ "utf8",
180
+ );
181
+ }
210
182
  const args = [
211
183
  ...parsed.preload.flatMap((preload) => ["-r", resolvePreload(cwd, preload)]),
212
184
  execution.entryFile,
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { main } from "../cli";
3
+ import { runTtsc } from "./internal/runTtsc";
4
4
 
5
- const code = main(process.argv.slice(2));
5
+ const code = runTtsc(process.argv.slice(2));
6
6
  if (typeof code === "number") {
7
7
  process.exitCode = code;
8
8
  }
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { main } from "../runner/cli";
3
+ import { runTtsx } from "./internal/runTtsx";
4
4
 
5
- const code = main(process.argv.slice(2));
5
+ const code = runTtsx(process.argv.slice(2));
6
6
  if (typeof code === "number") {
7
7
  process.exitCode = code;
8
8
  }