ttsc 0.3.0 → 0.4.0-dev.20260424

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 (112) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +216 -302
  3. package/cmd/ttsc/build.go +128 -0
  4. package/cmd/ttsc/main.go +222 -0
  5. package/cmd/ttsc/main_test.go +288 -0
  6. package/cmd/ttsc/transform.go +166 -0
  7. package/driver/host.go +31 -0
  8. package/driver/program.go +298 -0
  9. package/driver/rewrite.go +315 -0
  10. package/go.mod +48 -0
  11. package/go.sum +22 -0
  12. package/lib/api.d.ts +91 -0
  13. package/lib/api.js +325 -0
  14. package/lib/api.js.map +1 -0
  15. package/lib/cli.d.ts +1 -0
  16. package/lib/cli.js +481 -0
  17. package/lib/cli.js.map +1 -0
  18. package/lib/index.d.ts +17 -0
  19. package/lib/index.js +34 -0
  20. package/lib/index.js.map +1 -0
  21. package/lib/native.d.ts +15 -0
  22. package/lib/native.js +34 -0
  23. package/lib/native.js.map +1 -0
  24. package/lib/platform.d.ts +66 -0
  25. package/lib/platform.js +170 -0
  26. package/lib/platform.js.map +1 -0
  27. package/lib/plugin.d.ts +47 -0
  28. package/lib/plugin.js +150 -0
  29. package/lib/plugin.js.map +1 -0
  30. package/lib/project.d.ts +32 -0
  31. package/lib/project.js +303 -0
  32. package/lib/project.js.map +1 -0
  33. package/package.json +70 -63
  34. package/shim/ast/extra-shim.json +4 -0
  35. package/shim/ast/go.mod +5 -0
  36. package/shim/ast/shim.go +117 -0
  37. package/shim/bundled/extra-shim.json +1 -0
  38. package/shim/bundled/go.mod +5 -0
  39. package/shim/bundled/shim.go +19 -0
  40. package/shim/checker/extra-shim.json +31 -0
  41. package/shim/checker/go.mod +5 -0
  42. package/shim/checker/shim.go +146 -0
  43. package/shim/compiler/extra-shim.json +4 -0
  44. package/shim/compiler/go.mod +5 -0
  45. package/shim/compiler/shim.go +50 -0
  46. package/shim/core/extra-shim.json +4 -0
  47. package/shim/core/go.mod +5 -0
  48. package/shim/core/shim.go +11 -0
  49. package/shim/diagnosticwriter/go.mod +5 -0
  50. package/shim/diagnosticwriter/shim.go +29 -0
  51. package/shim/parser/extra-shim.json +4 -0
  52. package/shim/parser/go.mod +5 -0
  53. package/shim/parser/shim.go +55 -0
  54. package/shim/scanner/extra-shim.json +4 -0
  55. package/shim/scanner/go.mod +5 -0
  56. package/shim/scanner/shim.go +96 -0
  57. package/shim/tsoptions/extra-shim.json +4 -0
  58. package/shim/tsoptions/go.mod +5 -0
  59. package/shim/tsoptions/shim.go +123 -0
  60. package/shim/tspath/extra-shim.json +4 -0
  61. package/shim/tspath/go.mod +5 -0
  62. package/shim/tspath/shim.go +165 -0
  63. package/shim/vfs/cachedvfs/extra-shim.json +4 -0
  64. package/shim/vfs/cachedvfs/go.mod +5 -0
  65. package/shim/vfs/cachedvfs/shim.go +12 -0
  66. package/shim/vfs/extra-shim.json +4 -0
  67. package/shim/vfs/go.mod +5 -0
  68. package/shim/vfs/osvfs/extra-shim.json +4 -0
  69. package/shim/vfs/osvfs/go.mod +5 -0
  70. package/shim/vfs/osvfs/shim.go +13 -0
  71. package/shim/vfs/shim.go +19 -0
  72. package/src/api.ts +416 -0
  73. package/src/cli.ts +492 -0
  74. package/src/index.ts +18 -0
  75. package/src/launcher/ttsc-dev.js +42 -0
  76. package/src/launcher/ttsc.js +19 -0
  77. package/src/native.ts +60 -0
  78. package/src/platform.ts +163 -0
  79. package/src/plugin.ts +241 -0
  80. package/src/project.ts +330 -0
  81. package/test/native.test.ts +60 -0
  82. package/test/package.test.ts +123 -0
  83. package/test/platform.test.ts +58 -0
  84. package/test/project.test.ts +195 -0
  85. package/tools/gen_shims/go.mod +14 -0
  86. package/tools/gen_shims/go.sum +12 -0
  87. package/tools/gen_shims/main.go +446 -0
  88. package/CHANGELOG.md +0 -2
  89. package/bin/tsc +0 -2
  90. package/bin/tsserver +0 -2
  91. package/lib/PluginCreator.d.ts +0 -67
  92. package/lib/PluginCreator.js +0 -190
  93. package/lib/cancelationToken.d.ts +0 -0
  94. package/lib/cancelationToken.js +0 -2
  95. package/lib/loadTypescript.d.ts +0 -7
  96. package/lib/loadTypescript.js +0 -56
  97. package/lib/patchCreateProgram.d.ts +0 -21
  98. package/lib/patchCreateProgram.js +0 -184
  99. package/lib/tsc.d.ts +0 -1
  100. package/lib/tsc.js +0 -24
  101. package/lib/tsserver.d.ts +0 -0
  102. package/lib/tsserver.js +0 -2
  103. package/lib/tsserverlibrary.d.ts +0 -3
  104. package/lib/tsserverlibrary.js +0 -4
  105. package/lib/typescript.d.ts +0 -3
  106. package/lib/typescript.js +0 -4
  107. package/lib/typescriptServices.d.ts +0 -3
  108. package/lib/typescriptServices.js +0 -4
  109. package/lib/typingsInstaller.d.ts +0 -0
  110. package/lib/typingsInstaller.js +0 -2
  111. package/lib/watchGuard.d.ts +0 -0
  112. package/lib/watchGuard.js +0 -2
@@ -0,0 +1,165 @@
1
+
2
+ // Code generated by packages/ttsc/tools/gen_shims. DO NOT EDIT.
3
+
4
+ package tspath
5
+
6
+ import "github.com/microsoft/typescript-go/internal/tspath"
7
+ import _ "unsafe"
8
+
9
+ var AllSupportedExtensions = tspath.AllSupportedExtensions
10
+ var AllSupportedExtensionsWithJson = tspath.AllSupportedExtensionsWithJson
11
+ //go:linkname ChangeAnyExtension github.com/microsoft/typescript-go/internal/tspath.ChangeAnyExtension
12
+ func ChangeAnyExtension(path string, ext string, extensions []string, ignoreCase bool) string
13
+ //go:linkname ChangeExtension github.com/microsoft/typescript-go/internal/tspath.ChangeExtension
14
+ func ChangeExtension(path string, newExtension string) string
15
+ //go:linkname ChangeFullExtension github.com/microsoft/typescript-go/internal/tspath.ChangeFullExtension
16
+ func ChangeFullExtension(path string, newExtension string) string
17
+ //go:linkname CombinePaths github.com/microsoft/typescript-go/internal/tspath.CombinePaths
18
+ func CombinePaths(firstPath string, paths ...string) string
19
+ //go:linkname CompareNumberOfDirectorySeparators github.com/microsoft/typescript-go/internal/tspath.CompareNumberOfDirectorySeparators
20
+ func CompareNumberOfDirectorySeparators(path1 string, path2 string) int
21
+ //go:linkname ComparePaths github.com/microsoft/typescript-go/internal/tspath.ComparePaths
22
+ func ComparePaths(a string, b string, options tspath.ComparePathsOptions) int
23
+ //go:linkname ComparePathsCaseInsensitive github.com/microsoft/typescript-go/internal/tspath.ComparePathsCaseInsensitive
24
+ func ComparePathsCaseInsensitive(a string, b string, currentDirectory string) int
25
+ //go:linkname ComparePathsCaseSensitive github.com/microsoft/typescript-go/internal/tspath.ComparePathsCaseSensitive
26
+ func ComparePathsCaseSensitive(a string, b string, currentDirectory string) int
27
+ type ComparePathsOptions = tspath.ComparePathsOptions
28
+ //go:linkname ContainsIgnoredPath github.com/microsoft/typescript-go/internal/tspath.ContainsIgnoredPath
29
+ func ContainsIgnoredPath(path string) bool
30
+ //go:linkname ContainsPath github.com/microsoft/typescript-go/internal/tspath.ContainsPath
31
+ func ContainsPath(parent string, child string, options tspath.ComparePathsOptions) bool
32
+ //go:linkname ConvertToRelativePath github.com/microsoft/typescript-go/internal/tspath.ConvertToRelativePath
33
+ func ConvertToRelativePath(absoluteOrRelativePath string, options tspath.ComparePathsOptions) string
34
+ const DirectorySeparator = tspath.DirectorySeparator
35
+ //go:linkname EnsurePathIsNonModuleName github.com/microsoft/typescript-go/internal/tspath.EnsurePathIsNonModuleName
36
+ func EnsurePathIsNonModuleName(path string) string
37
+ //go:linkname EnsureTrailingDirectorySeparator github.com/microsoft/typescript-go/internal/tspath.EnsureTrailingDirectorySeparator
38
+ func EnsureTrailingDirectorySeparator(path string) string
39
+ const ExtensionCjs = tspath.ExtensionCjs
40
+ const ExtensionCts = tspath.ExtensionCts
41
+ const ExtensionDcts = tspath.ExtensionDcts
42
+ const ExtensionDmts = tspath.ExtensionDmts
43
+ const ExtensionDts = tspath.ExtensionDts
44
+ //go:linkname ExtensionIsOneOf github.com/microsoft/typescript-go/internal/tspath.ExtensionIsOneOf
45
+ func ExtensionIsOneOf(ext string, extensions []string) bool
46
+ //go:linkname ExtensionIsTs github.com/microsoft/typescript-go/internal/tspath.ExtensionIsTs
47
+ func ExtensionIsTs(ext string) bool
48
+ const ExtensionJs = tspath.ExtensionJs
49
+ const ExtensionJson = tspath.ExtensionJson
50
+ const ExtensionJsx = tspath.ExtensionJsx
51
+ const ExtensionMjs = tspath.ExtensionMjs
52
+ const ExtensionMts = tspath.ExtensionMts
53
+ const ExtensionTs = tspath.ExtensionTs
54
+ const ExtensionTsBuildInfo = tspath.ExtensionTsBuildInfo
55
+ const ExtensionTsx = tspath.ExtensionTsx
56
+ var ExtensionsNotSupportingExtensionlessResolution = tspath.ExtensionsNotSupportingExtensionlessResolution
57
+ //go:linkname FileExtensionIs github.com/microsoft/typescript-go/internal/tspath.FileExtensionIs
58
+ func FileExtensionIs(path string, extension string) bool
59
+ //go:linkname FileExtensionIsOneOf github.com/microsoft/typescript-go/internal/tspath.FileExtensionIsOneOf
60
+ func FileExtensionIsOneOf(path string, extensions []string) bool
61
+ //go:linkname GetAnyExtensionFromPath github.com/microsoft/typescript-go/internal/tspath.GetAnyExtensionFromPath
62
+ func GetAnyExtensionFromPath(path string, extensions []string, ignoreCase bool) string
63
+ //go:linkname GetBaseFileName github.com/microsoft/typescript-go/internal/tspath.GetBaseFileName
64
+ func GetBaseFileName(path string) string
65
+ //go:linkname GetCanonicalFileName github.com/microsoft/typescript-go/internal/tspath.GetCanonicalFileName
66
+ func GetCanonicalFileName(fileName string, useCaseSensitiveFileNames bool) string
67
+ //go:linkname GetCommonParents github.com/microsoft/typescript-go/internal/tspath.GetCommonParents
68
+ func GetCommonParents(paths []string, minComponents int, getPathComponents func(path string, currentDirectory string) []string, options tspath.ComparePathsOptions) (parents []string, ignored map[string]struct{})
69
+ //go:linkname GetDeclarationEmitExtensionForPath github.com/microsoft/typescript-go/internal/tspath.GetDeclarationEmitExtensionForPath
70
+ func GetDeclarationEmitExtensionForPath(path string) string
71
+ //go:linkname GetDeclarationFileExtension github.com/microsoft/typescript-go/internal/tspath.GetDeclarationFileExtension
72
+ func GetDeclarationFileExtension(fileName string) string
73
+ //go:linkname GetDirectoryPath github.com/microsoft/typescript-go/internal/tspath.GetDirectoryPath
74
+ func GetDirectoryPath(path string) string
75
+ //go:linkname GetEncodedRootLength github.com/microsoft/typescript-go/internal/tspath.GetEncodedRootLength
76
+ func GetEncodedRootLength(path string) int
77
+ //go:linkname GetNormalizedAbsolutePath github.com/microsoft/typescript-go/internal/tspath.GetNormalizedAbsolutePath
78
+ func GetNormalizedAbsolutePath(fileName string, currentDirectory string) string
79
+ //go:linkname GetNormalizedAbsolutePathWithoutRoot github.com/microsoft/typescript-go/internal/tspath.GetNormalizedAbsolutePathWithoutRoot
80
+ func GetNormalizedAbsolutePathWithoutRoot(fileName string, currentDirectory string) string
81
+ //go:linkname GetNormalizedPathComponents github.com/microsoft/typescript-go/internal/tspath.GetNormalizedPathComponents
82
+ func GetNormalizedPathComponents(path string, currentDirectory string) []string
83
+ //go:linkname GetPathComponents github.com/microsoft/typescript-go/internal/tspath.GetPathComponents
84
+ func GetPathComponents(path string, currentDirectory string) []string
85
+ //go:linkname GetPathComponentsRelativeTo github.com/microsoft/typescript-go/internal/tspath.GetPathComponentsRelativeTo
86
+ func GetPathComponentsRelativeTo(from string, to string, options tspath.ComparePathsOptions) []string
87
+ //go:linkname GetPathFromPathComponents github.com/microsoft/typescript-go/internal/tspath.GetPathFromPathComponents
88
+ func GetPathFromPathComponents(pathComponents []string) string
89
+ //go:linkname GetPossibleOriginalInputExtensionForExtension github.com/microsoft/typescript-go/internal/tspath.GetPossibleOriginalInputExtensionForExtension
90
+ func GetPossibleOriginalInputExtensionForExtension(path string) []string
91
+ //go:linkname GetRelativePathFromDirectory github.com/microsoft/typescript-go/internal/tspath.GetRelativePathFromDirectory
92
+ func GetRelativePathFromDirectory(fromDirectory string, to string, options tspath.ComparePathsOptions) string
93
+ //go:linkname GetRelativePathFromFile github.com/microsoft/typescript-go/internal/tspath.GetRelativePathFromFile
94
+ func GetRelativePathFromFile(from string, to string, options tspath.ComparePathsOptions) string
95
+ //go:linkname GetRelativePathToDirectoryOrUrl github.com/microsoft/typescript-go/internal/tspath.GetRelativePathToDirectoryOrUrl
96
+ func GetRelativePathToDirectoryOrUrl(directoryPathOrUrl string, relativeOrAbsolutePath string, isAbsolutePathAnUrl bool, options tspath.ComparePathsOptions) string
97
+ //go:linkname GetRootLength github.com/microsoft/typescript-go/internal/tspath.GetRootLength
98
+ func GetRootLength(path string) int
99
+ //go:linkname HasExtension github.com/microsoft/typescript-go/internal/tspath.HasExtension
100
+ func HasExtension(fileName string) bool
101
+ //go:linkname HasImplementationTSFileExtension github.com/microsoft/typescript-go/internal/tspath.HasImplementationTSFileExtension
102
+ func HasImplementationTSFileExtension(path string) bool
103
+ //go:linkname HasJSFileExtension github.com/microsoft/typescript-go/internal/tspath.HasJSFileExtension
104
+ func HasJSFileExtension(path string) bool
105
+ //go:linkname HasJSONFileExtension github.com/microsoft/typescript-go/internal/tspath.HasJSONFileExtension
106
+ func HasJSONFileExtension(path string) bool
107
+ //go:linkname HasTSFileExtension github.com/microsoft/typescript-go/internal/tspath.HasTSFileExtension
108
+ func HasTSFileExtension(path string) bool
109
+ //go:linkname HasTrailingDirectorySeparator github.com/microsoft/typescript-go/internal/tspath.HasTrailingDirectorySeparator
110
+ func HasTrailingDirectorySeparator(path string) bool
111
+ //go:linkname IsDeclarationFileName github.com/microsoft/typescript-go/internal/tspath.IsDeclarationFileName
112
+ func IsDeclarationFileName(fileName string) bool
113
+ //go:linkname IsDiskPathRoot github.com/microsoft/typescript-go/internal/tspath.IsDiskPathRoot
114
+ func IsDiskPathRoot(path string) bool
115
+ //go:linkname IsDynamicFileName github.com/microsoft/typescript-go/internal/tspath.IsDynamicFileName
116
+ func IsDynamicFileName(fileName string) bool
117
+ //go:linkname IsExternalModuleNameRelative github.com/microsoft/typescript-go/internal/tspath.IsExternalModuleNameRelative
118
+ func IsExternalModuleNameRelative(moduleName string) bool
119
+ //go:linkname IsRootedDiskPath github.com/microsoft/typescript-go/internal/tspath.IsRootedDiskPath
120
+ func IsRootedDiskPath(path string) bool
121
+ //go:linkname IsUrl github.com/microsoft/typescript-go/internal/tspath.IsUrl
122
+ func IsUrl(path string) bool
123
+ //go:linkname IsVolumeCharacter github.com/microsoft/typescript-go/internal/tspath.IsVolumeCharacter
124
+ func IsVolumeCharacter(char byte) bool
125
+ //go:linkname NormalizePath github.com/microsoft/typescript-go/internal/tspath.NormalizePath
126
+ func NormalizePath(path string) string
127
+ //go:linkname NormalizeSlashes github.com/microsoft/typescript-go/internal/tspath.NormalizeSlashes
128
+ func NormalizeSlashes(path string) string
129
+ type Path = tspath.Path
130
+ //go:linkname PathIsAbsolute github.com/microsoft/typescript-go/internal/tspath.PathIsAbsolute
131
+ func PathIsAbsolute(path string) bool
132
+ //go:linkname PathIsRelative github.com/microsoft/typescript-go/internal/tspath.PathIsRelative
133
+ func PathIsRelative(path string) bool
134
+ //go:linkname RemoveExtension github.com/microsoft/typescript-go/internal/tspath.RemoveExtension
135
+ func RemoveExtension(path string, extension string) string
136
+ //go:linkname RemoveFileExtension github.com/microsoft/typescript-go/internal/tspath.RemoveFileExtension
137
+ func RemoveFileExtension(path string) string
138
+ //go:linkname RemoveTrailingDirectorySeparator github.com/microsoft/typescript-go/internal/tspath.RemoveTrailingDirectorySeparator
139
+ func RemoveTrailingDirectorySeparator(path string) string
140
+ //go:linkname RemoveTrailingDirectorySeparators github.com/microsoft/typescript-go/internal/tspath.RemoveTrailingDirectorySeparators
141
+ func RemoveTrailingDirectorySeparators(path string) string
142
+ //go:linkname ResolvePath github.com/microsoft/typescript-go/internal/tspath.ResolvePath
143
+ func ResolvePath(path string, paths ...string) string
144
+ //go:linkname ResolveTripleslashReference github.com/microsoft/typescript-go/internal/tspath.ResolveTripleslashReference
145
+ func ResolveTripleslashReference(moduleName string, containingFile string) string
146
+ //go:linkname SplitVolumePath github.com/microsoft/typescript-go/internal/tspath.SplitVolumePath
147
+ func SplitVolumePath(path string) (volume string, rest string, ok bool)
148
+ //go:linkname StartsWithDirectory github.com/microsoft/typescript-go/internal/tspath.StartsWithDirectory
149
+ func StartsWithDirectory(fileName string, directoryName string, useCaseSensitiveFileNames bool) bool
150
+ var SupportedDeclarationExtensions = tspath.SupportedDeclarationExtensions
151
+ var SupportedJSExtensions = tspath.SupportedJSExtensions
152
+ var SupportedJSExtensionsFlat = tspath.SupportedJSExtensionsFlat
153
+ var SupportedTSExtensions = tspath.SupportedTSExtensions
154
+ var SupportedTSExtensionsFlat = tspath.SupportedTSExtensionsFlat
155
+ var SupportedTSExtensionsWithJson = tspath.SupportedTSExtensionsWithJson
156
+ var SupportedTSExtensionsWithJsonFlat = tspath.SupportedTSExtensionsWithJsonFlat
157
+ var SupportedTSImplementationExtensions = tspath.SupportedTSImplementationExtensions
158
+ //go:linkname ToFileNameLowerCase github.com/microsoft/typescript-go/internal/tspath.ToFileNameLowerCase
159
+ func ToFileNameLowerCase(fileName string) string
160
+ //go:linkname ToPath github.com/microsoft/typescript-go/internal/tspath.ToPath
161
+ func ToPath(fileName string, basePath string, useCaseSensitiveFileNames bool) tspath.Path
162
+ //go:linkname TryExtractTSExtension github.com/microsoft/typescript-go/internal/tspath.TryExtractTSExtension
163
+ func TryExtractTSExtension(fileName string) string
164
+ //go:linkname TryGetExtensionFromPath github.com/microsoft/typescript-go/internal/tspath.TryGetExtensionFromPath
165
+ func TryGetExtensionFromPath(p string) string
@@ -0,0 +1,4 @@
1
+ {
2
+ "ExtraMethods": {},
3
+ "ExtraFields": {}
4
+ }
@@ -0,0 +1,5 @@
1
+ module github.com/microsoft/typescript-go/shim/vfs/cachedvfs
2
+
3
+ go 1.26
4
+
5
+ require github.com/microsoft/typescript-go v0.0.0-20260408193441-2a5e1cf9fe22
@@ -0,0 +1,12 @@
1
+
2
+ // Code generated by packages/ttsc/tools/gen_shims. DO NOT EDIT.
3
+
4
+ package cachedvfs
5
+
6
+ import "github.com/microsoft/typescript-go/internal/vfs"
7
+ import "github.com/microsoft/typescript-go/internal/vfs/cachedvfs"
8
+ import _ "unsafe"
9
+
10
+ type FS = cachedvfs.FS
11
+ //go:linkname From github.com/microsoft/typescript-go/internal/vfs/cachedvfs.From
12
+ func From(fs vfs.FS) *cachedvfs.FS
@@ -0,0 +1,4 @@
1
+ {
2
+ "ExtraMethods": {},
3
+ "ExtraFields": {}
4
+ }
@@ -0,0 +1,5 @@
1
+ module github.com/microsoft/typescript-go/shim/vfs
2
+
3
+ go 1.26
4
+
5
+ require github.com/microsoft/typescript-go v0.0.0-20260408193441-2a5e1cf9fe22
@@ -0,0 +1,4 @@
1
+ {
2
+ "ExtraMethods": {},
3
+ "ExtraFields": {}
4
+ }
@@ -0,0 +1,5 @@
1
+ module github.com/microsoft/typescript-go/shim/vfs/osvfs
2
+
3
+ go 1.26
4
+
5
+ require github.com/microsoft/typescript-go v0.0.0-20260408193441-2a5e1cf9fe22
@@ -0,0 +1,13 @@
1
+
2
+ // Code generated by packages/ttsc/tools/gen_shims. DO NOT EDIT.
3
+
4
+ package osvfs
5
+
6
+ import "github.com/microsoft/typescript-go/internal/vfs"
7
+ import _ "github.com/microsoft/typescript-go/internal/vfs/osvfs"
8
+ import _ "unsafe"
9
+
10
+ //go:linkname FS github.com/microsoft/typescript-go/internal/vfs/osvfs.FS
11
+ func FS() vfs.FS
12
+ //go:linkname GetGlobalTypingsCacheLocation github.com/microsoft/typescript-go/internal/vfs/osvfs.GetGlobalTypingsCacheLocation
13
+ func GetGlobalTypingsCacheLocation() string
@@ -0,0 +1,19 @@
1
+
2
+ // Code generated by packages/ttsc/tools/gen_shims. DO NOT EDIT.
3
+
4
+ package vfs
5
+
6
+ import "github.com/microsoft/typescript-go/internal/vfs"
7
+
8
+ type DirEntry = vfs.DirEntry
9
+ type Entries = vfs.Entries
10
+ var ErrClosed = vfs.ErrClosed
11
+ var ErrExist = vfs.ErrExist
12
+ var ErrInvalid = vfs.ErrInvalid
13
+ var ErrNotExist = vfs.ErrNotExist
14
+ var ErrPermission = vfs.ErrPermission
15
+ type FS = vfs.FS
16
+ type FileInfo = vfs.FileInfo
17
+ var SkipAll = vfs.SkipAll
18
+ var SkipDir = vfs.SkipDir
19
+ type WalkDirFunc = vfs.WalkDirFunc
package/src/api.ts ADDED
@@ -0,0 +1,416 @@
1
+ /**
2
+ * Programmatic API for ttsc.
3
+ *
4
+ * This module is the TypeScript surface bundler adapters (unplugin, vite,
5
+ * webpack, rollup, esbuild, rspack, farm, next/swc, bun) consume. Everything
6
+ * here is a thin wrapper around the Go binary resolved by `platform.ts` —
7
+ * adapters never have to spawn the process themselves.
8
+ *
9
+ * Contract:
10
+ *
11
+ * - `transform()` emits one file's rewritten JS, returning the text.
12
+ * - `build()` runs the whole project (tsgo + ttsc rewrite + --emit).
13
+ * - `check()` runs the analysis pass without emitting (CI gate use).
14
+ * - `version()` returns the binary's version banner for user-agent logs.
15
+ *
16
+ * All helpers accept a `binary` override so tests can point at a specific
17
+ * executable without touching PATH or node_modules.
18
+ */
19
+ import { spawnSync } from "node:child_process";
20
+ import * as fs from "node:fs";
21
+ import * as os from "node:os";
22
+ import * as path from "node:path";
23
+
24
+ import { type ResolveOptions, installHint, resolveBinary } from "./platform";
25
+ import {
26
+ type TtscPlugin,
27
+ applyPluginTransforms,
28
+ loadProjectPlugins,
29
+ } from "./plugin";
30
+ import {
31
+ type ProjectPluginConfig,
32
+ resolveProjectConfig,
33
+ resolveProjectRoot,
34
+ } from "./project";
35
+
36
+ /**
37
+ * Options shared by every API call. `binary` takes precedence over platform
38
+ * resolution; `cwd` defaults to `process.cwd()`; `env` layers on top of the
39
+ * current process env.
40
+ */
41
+ export interface CommonOptions extends ResolveOptions {
42
+ /** Absolute path to an already-resolved ttsc binary. Skips resolution. */
43
+ binary?: string;
44
+ /** Working directory passed to the child process. */
45
+ cwd?: string;
46
+ /** Extra environment variables; merged onto `process.env`. */
47
+ env?: NodeJS.ProcessEnv;
48
+ /**
49
+ * Override project plugin loading. `false` disables tsconfig plugins; an
50
+ * array replaces the tsconfig `compilerOptions.plugins` list.
51
+ */
52
+ plugins?: readonly ProjectPluginConfig[] | false;
53
+ /**
54
+ * Override the native rewrite backend. Defaults to the loaded plugin mode.
55
+ *
56
+ * @deprecated Prefer plugin-declared `native.mode`; this override is for
57
+ * low-level tests and migration probes.
58
+ */
59
+ rewriteMode?: string;
60
+ }
61
+
62
+ /** Options for `transform()`. */
63
+ export interface TransformOptions extends CommonOptions {
64
+ /** Path to the .ts file to transform. Absolute or `cwd`-relative. */
65
+ file: string;
66
+ /** Path to the tsconfig owning `file`. Default: `tsconfig.json`. */
67
+ tsconfig?: string;
68
+ /**
69
+ * When provided, the binary writes JS directly to this path instead of piping
70
+ * stdout. Useful when the emitted text is large.
71
+ */
72
+ out?: string;
73
+ }
74
+
75
+ /** Options for `build()`. */
76
+ export interface BuildOptions extends CommonOptions {
77
+ /** Path to tsconfig.json. Default: `tsconfig.json`. */
78
+ tsconfig?: string;
79
+ /**
80
+ * Emit override. `true` forces emit, `false` forces noEmit, `undefined`
81
+ * follows tsconfig.
82
+ */
83
+ emit?: boolean;
84
+ /** Override compilerOptions.outDir for this invocation. */
85
+ outDir?: string;
86
+ /** Suppress the per-call summary banner. Default: `true`. */
87
+ quiet?: boolean;
88
+ }
89
+
90
+ /** Options for `check()`. */
91
+ export type CheckOptions = Omit<BuildOptions, "emit">;
92
+
93
+ /**
94
+ * Resolve the binary or throw a user-friendly error. Extracted so every API
95
+ * helper shares the same failure mode.
96
+ */
97
+ function resolveOrThrow(opts: CommonOptions): string {
98
+ if (
99
+ opts.binary &&
100
+ path.isAbsolute(opts.binary) &&
101
+ fs.existsSync(opts.binary)
102
+ ) {
103
+ return opts.binary;
104
+ }
105
+ const bin = resolveBinary(opts);
106
+ if (!bin) {
107
+ throw new Error(installHint(opts));
108
+ }
109
+ return bin;
110
+ }
111
+
112
+ /** Merge spawn env without clobbering unrelated vars. */
113
+ function mergeEnv(extra?: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
114
+ if (!extra) return process.env;
115
+ return { ...process.env, ...extra };
116
+ }
117
+
118
+ function spawnBinary(
119
+ binary: string,
120
+ args: readonly string[],
121
+ options: {
122
+ cwd?: string;
123
+ env?: NodeJS.ProcessEnv;
124
+ encoding?: BufferEncoding;
125
+ },
126
+ ) {
127
+ const viaNode = shouldSpawnViaNode(binary);
128
+ if (!viaNode) {
129
+ ensureExecutable(binary);
130
+ }
131
+ return spawnSync(
132
+ viaNode ? process.execPath : binary,
133
+ viaNode ? [binary, ...args] : [...args],
134
+ {
135
+ cwd: options.cwd,
136
+ env: options.env,
137
+ encoding: options.encoding,
138
+ maxBuffer: 1024 * 1024 * 256,
139
+ windowsHide: true,
140
+ },
141
+ );
142
+ }
143
+
144
+ function shouldSpawnViaNode(binary: string): boolean {
145
+ return /\.(?:[cm]?js|ts)$/i.test(binary);
146
+ }
147
+
148
+ function ensureExecutable(binary: string): void {
149
+ if (process.platform === "win32") {
150
+ return;
151
+ }
152
+ try {
153
+ const mode = fs.statSync(binary).mode & 0o777;
154
+ if ((mode & 0o111) !== 0) {
155
+ return;
156
+ }
157
+ fs.chmodSync(binary, mode | 0o755);
158
+ } catch {
159
+ /* keep the original spawn error path */
160
+ }
161
+ }
162
+
163
+ function outputText(value: string | Buffer | null | undefined): string {
164
+ if (value == null) {
165
+ return "";
166
+ }
167
+ return typeof value === "string" ? value : value.toString("utf8");
168
+ }
169
+
170
+ /**
171
+ * Transform a single .ts file and return the rewritten JS as a string.
172
+ *
173
+ * Intended for bundler per-file transforms (unplugin `transform()`). The caller
174
+ * passes the absolute path; ttsc loads the enclosing tsconfig, compiles with
175
+ * tsgo, and returns the rewritten JS.
176
+ *
177
+ * Throws when the binary exits non-zero — the error includes stderr so bundler
178
+ * error overlays surface the real cause.
179
+ */
180
+ export function transform(options: TransformOptions): string {
181
+ const execution = resolveExecutionContext(options);
182
+ const sourceFile = realpathIfExists(
183
+ path.isAbsolute(options.file)
184
+ ? options.file
185
+ : path.resolve(options.cwd ?? process.cwd(), options.file),
186
+ );
187
+ const args = [
188
+ "transform",
189
+ "--file=" + sourceFile,
190
+ "--tsconfig=" + execution.tsconfig,
191
+ "--rewrite-mode=" + execution.nativeMode,
192
+ ];
193
+
194
+ const res = spawnBinary(execution.bin, args, {
195
+ cwd: options.cwd,
196
+ env: mergeEnv(options.env),
197
+ encoding: "utf8",
198
+ });
199
+ if (res.error) {
200
+ throw new Error(
201
+ "ttsc.transform: failed to spawn " +
202
+ execution.bin +
203
+ ": " +
204
+ res.error.message,
205
+ );
206
+ }
207
+ if (res.status !== 0) {
208
+ throw new Error(
209
+ "ttsc.transform exited " + res.status + "\n" + (res.stderr || ""),
210
+ );
211
+ }
212
+ const transformed = finalizeTransformText(
213
+ execution.plugins,
214
+ {
215
+ command: "transform",
216
+ cwd: execution.cwd,
217
+ projectRoot: execution.projectRoot,
218
+ sourceFile,
219
+ tsconfig: execution.tsconfig,
220
+ },
221
+ outputText(res.stdout),
222
+ );
223
+ if (options.out) {
224
+ fs.mkdirSync(path.dirname(options.out), { recursive: true });
225
+ fs.writeFileSync(options.out, transformed, "utf8");
226
+ }
227
+ return transformed;
228
+ }
229
+
230
+ function realpathIfExists(file: string): string {
231
+ try {
232
+ return fs.realpathSync(file);
233
+ } catch {
234
+ return file;
235
+ }
236
+ }
237
+
238
+ /** Result of `build()`. Non-zero `status` means the build failed. */
239
+ export interface BuildResult {
240
+ status: number;
241
+ stdout: string;
242
+ stderr: string;
243
+ }
244
+
245
+ /**
246
+ * Run `ttsc` against a tsconfig. Returns once the binary exits so the caller
247
+ * can decide how to surface diagnostics. Does not throw on non-zero exit —
248
+ * bundler pipelines often want to continue and collect errors.
249
+ */
250
+ export function build(options: BuildOptions = {}): BuildResult {
251
+ const execution = resolveExecutionContext(options);
252
+ const args = [
253
+ "build",
254
+ "--tsconfig=" + execution.tsconfig,
255
+ "--rewrite-mode=" + execution.nativeMode,
256
+ ];
257
+ if (options.emit === true) args.push("--emit");
258
+ else if (options.emit === false) args.push("--noEmit");
259
+ if (options.outDir) args.push("--outDir=" + options.outDir);
260
+ if (options.quiet === false) args.push("--verbose");
261
+ else if (options.quiet === true) args.push("--quiet");
262
+ const needsManifest = options.emit !== false && execution.plugins.length > 0;
263
+ const manifest = needsManifest ? createTempManifestPath() : null;
264
+ if (manifest) args.push("--manifest=" + manifest);
265
+
266
+ const res = spawnBinary(execution.bin, args, {
267
+ cwd: options.cwd,
268
+ env: mergeEnv(options.env),
269
+ encoding: "utf8",
270
+ });
271
+ if (res.error) {
272
+ throw new Error(
273
+ "ttsc.build: failed to spawn " + execution.bin + ": " + res.error.message,
274
+ );
275
+ }
276
+ if ((res.status ?? 1) === 0 && manifest) {
277
+ try {
278
+ const emittedFiles = JSON.parse(
279
+ fs.readFileSync(manifest, "utf8"),
280
+ ) as string[];
281
+ applyBuildPlugins(execution.plugins, execution, emittedFiles);
282
+ } finally {
283
+ fs.rmSync(path.dirname(manifest), { recursive: true, force: true });
284
+ }
285
+ }
286
+ return {
287
+ status: res.status ?? 1,
288
+ stdout: outputText(res.stdout),
289
+ stderr: outputText(res.stderr),
290
+ };
291
+ }
292
+
293
+ /**
294
+ * Run `ttsc check` (build without emit) — CI gate / pre-commit hook use.
295
+ * Resolves with an exit-code record; does not throw.
296
+ */
297
+ export function check(options: CheckOptions = {}): BuildResult {
298
+ return build({ ...options, emit: false });
299
+ }
300
+
301
+ /** Ask the binary for its version banner. Handy for user-agent strings. */
302
+ export function version(options: CommonOptions = {}): string {
303
+ const bin = resolveOrThrow(options);
304
+ const res = spawnBinary(bin, ["version"], {
305
+ encoding: "utf8",
306
+ });
307
+ if (res.error || res.status !== 0) {
308
+ throw new Error(
309
+ "ttsc.version: failed: " + (outputText(res.stderr) || res.error?.message),
310
+ );
311
+ }
312
+ return outputText(res.stdout).trim();
313
+ }
314
+
315
+ /**
316
+ * Promise-facing variant of `transform()`. The plugin host keeps the transform
317
+ * pipeline synchronous so plugin modules can stay dependency-free, but many
318
+ * adapter surfaces still prefer a Promise-returning function.
319
+ */
320
+ export function transformAsync(options: TransformOptions): Promise<string> {
321
+ return Promise.resolve().then(() => transform(options));
322
+ }
323
+
324
+ interface ExecutionContext {
325
+ bin: string;
326
+ cwd: string;
327
+ nativeMode: string;
328
+ plugins: readonly TtscPlugin[];
329
+ projectRoot: string;
330
+ tsconfig: string;
331
+ }
332
+
333
+ function resolveExecutionContext(
334
+ options: CommonOptions & { tsconfig?: string },
335
+ ): ExecutionContext {
336
+ const cwd = path.resolve(options.cwd ?? process.cwd());
337
+ const fallbackBinary =
338
+ options.binary &&
339
+ path.isAbsolute(options.binary) &&
340
+ fs.existsSync(options.binary)
341
+ ? options.binary
342
+ : resolveBinary(options);
343
+ const tsconfig = resolveProjectConfig({
344
+ cwd,
345
+ tsconfig: options.tsconfig,
346
+ });
347
+ const projectRoot = resolveProjectRoot({ cwd, tsconfig });
348
+ const loaded = loadProjectPlugins({
349
+ binary: fallbackBinary ?? "",
350
+ cwd,
351
+ entries: options.plugins,
352
+ tsconfig,
353
+ });
354
+ const bin = options.binary ?? loaded.nativeBinary ?? fallbackBinary;
355
+ if (!bin) {
356
+ throw new Error(installHint(options));
357
+ }
358
+ return {
359
+ bin,
360
+ cwd,
361
+ nativeMode: options.rewriteMode ?? loaded.nativeMode,
362
+ plugins: loaded.plugins.filter((plugin) => plugin.transformOutput),
363
+ projectRoot,
364
+ tsconfig,
365
+ };
366
+ }
367
+
368
+ function finalizeTransformText(
369
+ plugins: readonly TtscPlugin[],
370
+ context: Omit<Parameters<typeof applyPluginTransforms>[1], "code">,
371
+ text: string,
372
+ ): string {
373
+ if (plugins.length === 0) {
374
+ return text;
375
+ }
376
+ return applyPluginTransforms(plugins, {
377
+ ...context,
378
+ code: text,
379
+ });
380
+ }
381
+
382
+ function applyBuildPlugins(
383
+ plugins: readonly TtscPlugin[],
384
+ execution: ExecutionContext,
385
+ emittedFiles: readonly string[],
386
+ ): void {
387
+ if (plugins.length === 0) {
388
+ return;
389
+ }
390
+ for (const file of emittedFiles) {
391
+ if (!isJavaScriptOutput(file) || !fs.existsSync(file)) {
392
+ continue;
393
+ }
394
+ const current = fs.readFileSync(file, "utf8");
395
+ const next = applyPluginTransforms(plugins, {
396
+ code: current,
397
+ command: "build",
398
+ cwd: execution.cwd,
399
+ outputFile: file,
400
+ projectRoot: execution.projectRoot,
401
+ tsconfig: execution.tsconfig,
402
+ });
403
+ if (next !== current) {
404
+ fs.writeFileSync(file, next, "utf8");
405
+ }
406
+ }
407
+ }
408
+
409
+ function isJavaScriptOutput(file: string): boolean {
410
+ return /\.(?:[cm]?js)$/i.test(file);
411
+ }
412
+
413
+ function createTempManifestPath(): string {
414
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-build-"));
415
+ return path.join(dir, "manifest.json");
416
+ }