ttsc 0.4.4 → 0.5.0-dev.20260429
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -3
- package/cmd/ttsc/main.go +2 -2
- package/driver/program.go +120 -15
- package/go.mod +3 -3
- package/go.sum +6 -6
- package/lib/api.d.ts +3 -3
- package/lib/api.js +275 -624
- package/lib/api.js.map +1 -1
- package/lib/cli.js +78 -2
- package/lib/cli.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.js +3 -3
- package/lib/native.d.ts +5 -0
- package/lib/native.js +8 -0
- package/lib/native.js.map +1 -1
- package/lib/plugin.d.ts +8 -48
- package/lib/plugin.js +79 -132
- package/lib/plugin.js.map +1 -1
- package/lib/runner/cli.js +1 -0
- package/lib/runner/cli.js.map +1 -1
- package/lib/source-build.d.ts +30 -0
- package/lib/source-build.js +365 -0
- package/lib/source-build.js.map +1 -0
- package/package.json +9 -9
- package/shim/ast/go.mod +1 -1
- package/shim/ast/lint.go +328 -0
- package/shim/bundled/go.mod +1 -1
- package/shim/checker/go.mod +1 -1
- package/shim/compiler/go.mod +1 -1
- package/shim/core/go.mod +1 -1
- package/shim/core/shim.go +15 -0
- package/shim/diagnosticwriter/go.mod +1 -1
- package/shim/diagnosticwriter/lint.go +137 -0
- package/shim/parser/go.mod +1 -1
- package/shim/scanner/go.mod +1 -1
- package/shim/tsoptions/go.mod +1 -1
- package/shim/tspath/go.mod +1 -1
- package/shim/vfs/cachedvfs/go.mod +1 -1
- package/shim/vfs/go.mod +1 -1
- package/shim/vfs/osvfs/go.mod +1 -1
- package/src/api.ts +413 -771
- package/src/cli.ts +82 -2
- package/src/index.ts +3 -3
- package/src/native.ts +18 -0
- package/src/plugin.ts +107 -213
- package/src/runner/cli.ts +5 -0
- package/src/source-build.ts +383 -0
- package/test/native.test.ts +43 -0
- package/test/source-build.test.ts +219 -0
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/ttsc)
|
|
7
7
|
[](https://www.npmjs.com/package/ttsc)
|
|
8
8
|
[](https://github.com/samchon/ttsc/actions?query=workflow%3Atest)
|
|
9
|
+
[](https://discord.gg/E94XhzrUCZ)
|
|
9
10
|
|
|
10
11
|
A `typescript-go` toolchain for compiler-powered transforms and type-safe execution.
|
|
11
12
|
|
|
@@ -39,21 +40,38 @@ npx ttsc --noEmit
|
|
|
39
40
|
npx ttsc --watch
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
Clear cached transformer binaries when developing or debugging a plugin:
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
```bash
|
|
46
|
+
npx ttsc clean
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Plugin Configuration
|
|
50
|
+
|
|
51
|
+
Open your project's `tsconfig.json`, then add plugin entries under `compilerOptions.plugins`. If the file already has `compilerOptions`, merge the `plugins` array into the existing object.
|
|
52
|
+
|
|
53
|
+
Each plugin module is a JavaScript descriptor for an ordered native transformer backend; the transform implementation itself runs in Go.
|
|
45
54
|
|
|
46
55
|
```json
|
|
47
56
|
{
|
|
48
57
|
"compilerOptions": {
|
|
49
58
|
"plugins": [
|
|
59
|
+
{
|
|
60
|
+
"transform": "@ttsc/lint",
|
|
61
|
+
"rules": {
|
|
62
|
+
"no-var": "error",
|
|
63
|
+
"no-explicit-any": "warning",
|
|
64
|
+
"no-non-null-assertion": "off"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{ "transform": "@ttsc/paths" },
|
|
50
68
|
{ "transform": "typia/lib/transform" }
|
|
51
69
|
]
|
|
52
70
|
}
|
|
53
71
|
}
|
|
54
72
|
```
|
|
55
73
|
|
|
56
|
-
The same configuration is used by both `ttsc` commands.
|
|
74
|
+
The same configuration is used by both `ttsc` and `ttsx` commands.
|
|
57
75
|
|
|
58
76
|
```bash
|
|
59
77
|
# compile
|
|
@@ -120,6 +138,20 @@ It is transformed into dedicated JavaScript:
|
|
|
120
138
|
|
|
121
139
|
`ttsc` runs this transform during build, and `ttsx` runs through the same transform path during execution.
|
|
122
140
|
|
|
141
|
+
## List of Plugins
|
|
142
|
+
|
|
143
|
+
`ttsc` ships a few small utility plugins in this repository.
|
|
144
|
+
|
|
145
|
+
- [`{ "transform": "@ttsc/banner", ... }`](https://github.com/samchon/ttsc/tree/master/packages/banner)
|
|
146
|
+
- [`{ "transform": "@ttsc/lint", ... }`](https://github.com/samchon/ttsc/tree/master/packages/lint)
|
|
147
|
+
- [`{ "transform": "@ttsc/paths" }`](https://github.com/samchon/ttsc/tree/master/packages/paths)
|
|
148
|
+
- [`{ "transform": "@ttsc/strip", ... }`](https://github.com/samchon/ttsc/tree/master/packages/strip)
|
|
149
|
+
|
|
150
|
+
Ecosystem plugins are listed below; PRs adding `ttsc` plugins are welcome.
|
|
151
|
+
|
|
152
|
+
- [`{ "transform": "@nestia/core/lib/transform" }`](https://github.com/samchon/nestia)
|
|
153
|
+
- [`{ "transform": "typia/lib/transform" }`](https://github.com/samchon/typia)
|
|
154
|
+
|
|
123
155
|
## References
|
|
124
156
|
|
|
125
157
|
- TypeScript runners: [`ts-node`](https://github.com/TypeStrong/ts-node) and [`tsx`](https://github.com/privatenumber/tsx)
|
package/cmd/ttsc/main.go
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// - Report version and platform (`ttsc --version`).
|
|
5
5
|
// - Exercise a native rewrite backend end-to-end (`ttsc demo --type=string`)
|
|
6
6
|
// so smoke tests can verify the Go binary really runs.
|
|
7
|
-
// -
|
|
8
|
-
//
|
|
7
|
+
// - Host the native project build, check, and single-file transform paths used
|
|
8
|
+
// by plugin-selected sidecars and smoke tests.
|
|
9
9
|
//
|
|
10
10
|
// Everything below is deliberately dependency-free so that the standalone binary
|
|
11
11
|
// stays small and its behavior is trivial to audit.
|
package/driver/program.go
CHANGED
|
@@ -20,12 +20,71 @@ import (
|
|
|
20
20
|
|
|
21
21
|
// Diagnostic is the compilation diagnostic shape ttsc passes around. Kept
|
|
22
22
|
// dependency-free (no shim types) so callers can render or inspect freely.
|
|
23
|
+
//
|
|
24
|
+
// `raw` carries the original tsgo diagnostic for full color/context
|
|
25
|
+
// rendering. `lint` carries a plugin-emitted lint diagnostic when the
|
|
26
|
+
// diagnostic was produced outside the typecheck pipeline (e.g. by
|
|
27
|
+
// `@ttsc/lint`). At most one of `raw` / `lint` is non-nil; both nil falls
|
|
28
|
+
// back to the legacy single-line form.
|
|
23
29
|
type Diagnostic struct {
|
|
24
|
-
File
|
|
25
|
-
Line
|
|
26
|
-
Column
|
|
27
|
-
Message
|
|
28
|
-
|
|
30
|
+
File string
|
|
31
|
+
Line int
|
|
32
|
+
Column int
|
|
33
|
+
Message string
|
|
34
|
+
Severity Severity
|
|
35
|
+
raw *ast.Diagnostic
|
|
36
|
+
lint *shimdiagnosticwriter.LintDiagnostic
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Severity classifies a diagnostic's blast radius. ttsc treats Error as a
|
|
40
|
+
// build-failing condition; Warning prints but does not flip the exit code.
|
|
41
|
+
type Severity int
|
|
42
|
+
|
|
43
|
+
const (
|
|
44
|
+
// SeverityError is the default for tsgo typecheck output and any
|
|
45
|
+
// plugin-emitted finding that should fail the build.
|
|
46
|
+
SeverityError Severity = iota
|
|
47
|
+
// SeverityWarning prints with warning coloring but keeps the build
|
|
48
|
+
// status at zero.
|
|
49
|
+
SeverityWarning
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
// IsError reports whether the diagnostic counts toward the build's error
|
|
53
|
+
// total. Useful when plugins want to gate emit on the lint outcome without
|
|
54
|
+
// re-walking the diagnostic list.
|
|
55
|
+
func (d Diagnostic) IsError() bool { return d.Severity == SeverityError }
|
|
56
|
+
|
|
57
|
+
// NewLintDiagnostic shapes a plugin finding so it renders alongside tsgo
|
|
58
|
+
// diagnostics with full color / source context. `pos` and `end` are byte
|
|
59
|
+
// offsets into the source file; `code` is a stable rule identifier (e.g. the
|
|
60
|
+
// rule's enum index). Severity controls both the rendered banner color and
|
|
61
|
+
// the exit-code outcome.
|
|
62
|
+
func NewLintDiagnostic(
|
|
63
|
+
file *ast.SourceFile,
|
|
64
|
+
pos, end int,
|
|
65
|
+
code int32,
|
|
66
|
+
severity Severity,
|
|
67
|
+
message string,
|
|
68
|
+
) Diagnostic {
|
|
69
|
+
cat := shimdiagnosticwriter.LintCategoryError
|
|
70
|
+
if severity == SeverityWarning {
|
|
71
|
+
cat = shimdiagnosticwriter.LintCategoryWarning
|
|
72
|
+
}
|
|
73
|
+
lint := shimdiagnosticwriter.NewLintDiagnostic(file, pos, end, code, cat, message)
|
|
74
|
+
d := Diagnostic{
|
|
75
|
+
Message: message,
|
|
76
|
+
Severity: severity,
|
|
77
|
+
lint: lint,
|
|
78
|
+
}
|
|
79
|
+
if file != nil {
|
|
80
|
+
d.File = file.FileName()
|
|
81
|
+
if pos >= 0 {
|
|
82
|
+
line, col := shimscanner.GetECMALineAndByteOffsetOfPosition(file, pos)
|
|
83
|
+
d.Line = line + 1
|
|
84
|
+
d.Column = col + 1
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return d
|
|
29
88
|
}
|
|
30
89
|
|
|
31
90
|
// SourceFile returns the program source file matching filename.
|
|
@@ -54,21 +113,67 @@ func (d Diagnostic) String() string {
|
|
|
54
113
|
}
|
|
55
114
|
|
|
56
115
|
// WritePrettyDiagnostics renders diagnostics with TypeScript-style colors,
|
|
57
|
-
// source snippets and the trailing error summary when raw tsgo
|
|
58
|
-
// objects are available.
|
|
59
|
-
//
|
|
116
|
+
// source snippets and the trailing error summary when raw tsgo or lint
|
|
117
|
+
// diagnostic objects are available. Mixed batches (e.g. typecheck + lint)
|
|
118
|
+
// are rendered through the same color/context pipeline; entries without
|
|
119
|
+
// either anchor fall back to the legacy `path:line:col: message` form.
|
|
60
120
|
func WritePrettyDiagnostics(w io.Writer, diagnostics []Diagnostic, cwd string) {
|
|
61
|
-
|
|
121
|
+
if len(diagnostics) == 0 {
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
rich := make([]Diagnostic, 0, len(diagnostics))
|
|
125
|
+
plain := make([]Diagnostic, 0)
|
|
62
126
|
for _, d := range diagnostics {
|
|
63
|
-
if d.raw
|
|
64
|
-
|
|
65
|
-
|
|
127
|
+
if d.raw != nil || d.lint != nil {
|
|
128
|
+
rich = append(rich, d)
|
|
129
|
+
} else {
|
|
130
|
+
plain = append(plain, d)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if len(rich) > 0 {
|
|
134
|
+
astDiags := make([]*ast.Diagnostic, 0, len(rich))
|
|
135
|
+
lintDiags := make([]*shimdiagnosticwriter.LintDiagnostic, 0, len(rich))
|
|
136
|
+
for _, d := range rich {
|
|
137
|
+
if d.raw != nil {
|
|
138
|
+
astDiags = append(astDiags, d.raw)
|
|
139
|
+
}
|
|
140
|
+
if d.lint != nil {
|
|
141
|
+
lintDiags = append(lintDiags, d.lint)
|
|
66
142
|
}
|
|
67
|
-
return
|
|
68
143
|
}
|
|
69
|
-
|
|
144
|
+
shimdiagnosticwriter.FormatMixedDiagnostics(w, astDiags, lintDiags, cwd)
|
|
145
|
+
}
|
|
146
|
+
for _, d := range plain {
|
|
147
|
+
fmt.Fprintln(w, " -", d.String())
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// CountErrors returns the number of diagnostics that should fail the build.
|
|
152
|
+
// tsgo diagnostics carry their own `Error` category; lint diagnostics carry a
|
|
153
|
+
// caller-set Severity. Anything that isn't an explicit warning counts.
|
|
154
|
+
func CountErrors(diagnostics []Diagnostic) int {
|
|
155
|
+
n := 0
|
|
156
|
+
for _, d := range diagnostics {
|
|
157
|
+
if d.lint != nil {
|
|
158
|
+
if d.lint.IsError() {
|
|
159
|
+
n++
|
|
160
|
+
}
|
|
161
|
+
continue
|
|
162
|
+
}
|
|
163
|
+
if d.raw != nil {
|
|
164
|
+
// tsgo diagnostics use the diagnostics package category. The
|
|
165
|
+
// renderer shim already mirrors the same Error/Warning split, so
|
|
166
|
+
// re-categorize via the public IsError shortcut.
|
|
167
|
+
if d.Severity != SeverityWarning {
|
|
168
|
+
n++
|
|
169
|
+
}
|
|
170
|
+
continue
|
|
171
|
+
}
|
|
172
|
+
// Plain text diagnostics (manually assembled): treat as errors so
|
|
173
|
+
// "ttsc: tsconfig not found"-style failures still flip the exit code.
|
|
174
|
+
n++
|
|
70
175
|
}
|
|
71
|
-
|
|
176
|
+
return n
|
|
72
177
|
}
|
|
73
178
|
|
|
74
179
|
// Program is the shim-agnostic facade the rest of the engine sees.
|
package/go.mod
CHANGED
|
@@ -40,9 +40,9 @@ require (
|
|
|
40
40
|
require (
|
|
41
41
|
github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 // indirect
|
|
42
42
|
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
|
43
|
-
github.com/microsoft/typescript-go v0.0.0-
|
|
43
|
+
github.com/microsoft/typescript-go v0.0.0-20260424234512-515d036f927a // indirect
|
|
44
44
|
github.com/zeebo/xxh3 v1.1.0 // indirect
|
|
45
45
|
golang.org/x/sync v0.20.0 // indirect
|
|
46
|
-
golang.org/x/sys v0.
|
|
47
|
-
golang.org/x/text v0.
|
|
46
|
+
golang.org/x/sys v0.43.0 // indirect
|
|
47
|
+
golang.org/x/text v0.36.0 // indirect
|
|
48
48
|
)
|
package/go.sum
CHANGED
|
@@ -4,8 +4,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
|
|
4
4
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
|
5
5
|
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
|
6
6
|
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
|
7
|
-
github.com/microsoft/typescript-go v0.0.0-
|
|
8
|
-
github.com/microsoft/typescript-go v0.0.0-
|
|
7
|
+
github.com/microsoft/typescript-go v0.0.0-20260424234512-515d036f927a h1:3ItFA7V3ZwhdbM1LAW+r3pS/+znGJVKbWTFoiQILuhU=
|
|
8
|
+
github.com/microsoft/typescript-go v0.0.0-20260424234512-515d036f927a/go.mod h1:m8YA0PMC7ti0GW0RI05D6fEcjQeu98XVS+FWF+VDW2k=
|
|
9
9
|
github.com/peter-evans/patience v0.3.0 h1:rX0JdJeepqdQl1Sk9c9uvorjYYzL2TfgLX1adqYm9cA=
|
|
10
10
|
github.com/peter-evans/patience v0.3.0/go.mod h1:Kmxu5sY1NmBLFSStvXjX1wS9mIv7wMcP/ubucyMOAu0=
|
|
11
11
|
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
|
@@ -14,9 +14,9 @@ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
|
|
|
14
14
|
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
|
|
15
15
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
|
16
16
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
|
17
|
-
golang.org/x/sys v0.
|
|
18
|
-
golang.org/x/sys v0.
|
|
19
|
-
golang.org/x/text v0.
|
|
20
|
-
golang.org/x/text v0.
|
|
17
|
+
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
|
18
|
+
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
|
19
|
+
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
|
20
|
+
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
|
21
21
|
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
|
22
22
|
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
package/lib/api.d.ts
CHANGED
|
@@ -85,8 +85,8 @@ export declare function check(options?: CheckOptions): BuildResult;
|
|
|
85
85
|
/** Ask the binary for its version banner. Handy for user-agent strings. */
|
|
86
86
|
export declare function version(options?: CommonOptions): string;
|
|
87
87
|
/**
|
|
88
|
-
* Promise-facing variant of `transform()`. The
|
|
89
|
-
*
|
|
90
|
-
*
|
|
88
|
+
* Promise-facing variant of `transform()`. The host path stays synchronous so
|
|
89
|
+
* plugin descriptors can stay dependency-free, but many adapter surfaces still
|
|
90
|
+
* prefer a Promise-returning function.
|
|
91
91
|
*/
|
|
92
92
|
export declare function transformAsync(options: TransformOptions): Promise<string>;
|