ttsc 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -68
- package/cmd/ttsc/api_compile.go +109 -115
- package/cmd/ttsc/api_transform.go +54 -51
- package/cmd/ttsc/main.go +103 -121
- package/driver/program.go +30 -2
- package/driver/rewrite.go +126 -9
- package/go.mod +2 -0
- package/lib/TtscCompiler.js +28 -46
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.js +8 -38
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.js +36 -63
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/project/readProjectConfig.js +108 -60
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +15 -45
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.js +10 -40
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +21 -48
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.js +14 -44
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +7 -0
- package/lib/compiler/internal/runBuild.js +47 -66
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.js +18 -48
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +41 -75
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +7 -37
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +48 -69
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +53 -64
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +328 -57
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +8 -0
- package/lib/plugin/internal/buildSourcePlugin.js +287 -139
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +2 -0
- package/lib/plugin/internal/loadProjectPlugins.js +197 -9
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerContext.d.ts +16 -3
- package/lib/structures/ITtscCompilerResult.d.ts +4 -0
- package/lib/structures/ITtscCompilerTransformation.d.ts +2 -0
- package/lib/structures/ITtscPluginFactoryContext.d.ts +6 -3
- package/lib/structures/ITtscProjectPluginConfig.d.ts +8 -7
- package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +2 -0
- package/lib/structures/internal/ITtscProjectLocatorOptions.d.ts +2 -0
- package/lib/structures/internal/TtscCommonOptions.d.ts +2 -0
- package/package.json +9 -14
- package/shim/diagnosticwriter/lint.go +8 -0
- package/shim/printer/go.mod +5 -0
- package/shim/printer/shim.go +23 -0
- package/src/TtscCompiler.ts +20 -5
- package/src/compiler/internal/buildNativeCompiler.ts +2 -2
- package/src/compiler/internal/compileProjectInMemory.ts +21 -16
- package/src/compiler/internal/project/readProjectConfig.ts +134 -35
- package/src/compiler/internal/project/resolveProjectConfig.ts +2 -2
- package/src/compiler/internal/resolveBinary.ts +2 -2
- package/src/compiler/internal/resolveEmittedJavaScript.ts +11 -7
- package/src/compiler/internal/resolveTsgo.ts +2 -2
- package/src/compiler/internal/runBuild.ts +34 -21
- package/src/compiler/internal/runSingleFileEmit.ts +3 -3
- package/src/compiler/internal/transformProjectInMemory.ts +37 -37
- package/src/launcher/internal/getCompilerVersionText.ts +2 -2
- package/src/launcher/internal/prepareExecution.ts +14 -4
- package/src/launcher/internal/runTtsc.ts +30 -4
- package/src/launcher/internal/runTtsx.ts +377 -26
- package/src/plugin/internal/buildSourcePlugin.ts +321 -50
- package/src/plugin/internal/loadProjectPlugins.ts +266 -10
- package/src/structures/ITtscCompilerContext.ts +17 -3
- package/src/structures/ITtscCompilerResult.ts +5 -0
- package/src/structures/ITtscCompilerTransformation.ts +3 -0
- package/src/structures/ITtscPluginFactoryContext.ts +6 -3
- package/src/structures/ITtscProjectPluginConfig.ts +8 -7
- package/src/structures/internal/ITtscParsedProjectConfig.ts +2 -0
- package/src/structures/internal/ITtscProjectLocatorOptions.ts +2 -0
- package/src/structures/internal/TtscCommonOptions.ts +2 -0
- package/utility/host.go +622 -20
- package/cmd/ttsc/main_test.go +0 -288
- package/test/compiler.test.ts +0 -422
- package/test/platform.test.ts +0 -12
- package/test/project.test.ts +0 -197
- package/test/source-build.test.ts +0 -45
- package/test/tsgo.test.ts +0 -69
package/README.md
CHANGED
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
[](https://github.com/samchon/ttsc/tree/master/docs)
|
|
10
10
|
[](https://discord.gg/E94XhzrUCZ)
|
|
11
11
|
|
|
12
|
-
A `typescript-go` toolchain for compiler-powered
|
|
12
|
+
A `typescript-go` toolchain for compiler-powered plugins and type-safe execution.
|
|
13
13
|
|
|
14
14
|
- **`ttsc`**: build, check, and transform.
|
|
15
15
|
- **`ttsx`**: execute TypeScript with type checking.
|
|
16
|
-
-
|
|
16
|
+
- native TypeScript-Go execution instead of transpile-only runners.
|
|
17
17
|
- type checking that `tsx` does not provide.
|
|
18
|
-
- **
|
|
18
|
+
- **plugin support**: compiler-powered libraries, such as `typia`.
|
|
19
19
|
- `@ttsc/lint`: lint violations as TS compile errors.
|
|
20
20
|
|
|
21
21
|
## Setup
|
|
@@ -25,7 +25,7 @@ A `typescript-go` toolchain for compiler-powered transforms and type-safe execut
|
|
|
25
25
|
Install the native TypeScript preview package with `ttsc`:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
npm
|
|
28
|
+
npm install -D ttsc @typescript/native-preview
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
### Commands
|
|
@@ -48,11 +48,11 @@ npx ttsc --watch
|
|
|
48
48
|
|
|
49
49
|
Use `@ttsc/unplugin` when a bundler owns your build.
|
|
50
50
|
|
|
51
|
-
It runs
|
|
51
|
+
It runs `ttsc` plugins inside supported bundlers.
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
npm
|
|
55
|
-
npm
|
|
54
|
+
npm install -D ttsc @typescript/native-preview
|
|
55
|
+
npm install -D @ttsc/unplugin
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Minimal Vite setup:
|
|
@@ -83,30 +83,7 @@ See [`@ttsc/unplugin`](https://github.com/samchon/ttsc/tree/master/packages/unpl
|
|
|
83
83
|
|
|
84
84
|
## Plugins
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
Add plugin entries under `compilerOptions.plugins` in your `tsconfig.json`.
|
|
89
|
-
|
|
90
|
-
```json
|
|
91
|
-
{
|
|
92
|
-
"compilerOptions": {
|
|
93
|
-
"plugins": [
|
|
94
|
-
{
|
|
95
|
-
"transform": "@ttsc/lint",
|
|
96
|
-
"config": {
|
|
97
|
-
"no-var": "error",
|
|
98
|
-
"no-explicit-any": "warning",
|
|
99
|
-
"no-non-null-assertion": "off"
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
{ "transform": "@ttsc/paths" },
|
|
103
|
-
{ "transform": "typia/lib/transform" }
|
|
104
|
-
]
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
The same configuration is used by both `ttsc` and `ttsx` commands.
|
|
86
|
+
Plugins let libraries add compile-time checks, transforms, and type-driven code generation to normal `ttsc` and `ttsx` runs.
|
|
110
87
|
|
|
111
88
|
```bash
|
|
112
89
|
# compile
|
|
@@ -116,9 +93,7 @@ npx ttsc
|
|
|
116
93
|
npx ttsx src/index.ts
|
|
117
94
|
```
|
|
118
95
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
### What Is a Transform?
|
|
96
|
+
### Transform Example
|
|
122
97
|
|
|
123
98
|
A transform uses TypeScript types to generate JavaScript before runtime.
|
|
124
99
|
|
|
@@ -143,52 +118,48 @@ interface IMember {
|
|
|
143
118
|
}
|
|
144
119
|
```
|
|
145
120
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
> console.log(matched); // true
|
|
173
|
-
> ```
|
|
174
|
-
|
|
175
|
-
`ttsc` applies this transform at build time; `ttsx` applies the same transform when running the file.
|
|
121
|
+
The transform replaces `typia.is<IMember>()` with dedicated JavaScript checks at build time:
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid";
|
|
125
|
+
import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail";
|
|
126
|
+
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32";
|
|
127
|
+
import typia from "typia";
|
|
128
|
+
import { v4 } from "uuid";
|
|
129
|
+
const matched = (() => {
|
|
130
|
+
const _io0 = (input) =>
|
|
131
|
+
"string" === typeof input.id &&
|
|
132
|
+
__typia_transform__isFormatUuid._isFormatUuid(input.id) &&
|
|
133
|
+
"string" === typeof input.email &&
|
|
134
|
+
__typia_transform__isFormatEmail._isFormatEmail(input.email) &&
|
|
135
|
+
"number" === typeof input.age &&
|
|
136
|
+
__typia_transform__isTypeUint32._isTypeUint32(input.age) &&
|
|
137
|
+
19 < input.age &&
|
|
138
|
+
input.age <= 100;
|
|
139
|
+
return (input) => "object" === typeof input && null !== input && _io0(input);
|
|
140
|
+
})()({
|
|
141
|
+
id: v4(),
|
|
142
|
+
email: "samchon.github@gmail.com",
|
|
143
|
+
age: 30,
|
|
144
|
+
});
|
|
145
|
+
console.log(matched); // true
|
|
146
|
+
```
|
|
176
147
|
|
|
177
148
|
### List of Plugins
|
|
178
149
|
|
|
179
150
|
`ttsc` ships a few small utility plugins in this repository.
|
|
180
151
|
|
|
181
|
-
- [`@ttsc/banner`](https://github.com/samchon/ttsc/tree/master/packages/banner): adds `@packageDocumentation` JSDoc banners
|
|
182
|
-
- [`@ttsc/lint`](https://github.com/samchon/ttsc/tree/master/packages/lint):
|
|
152
|
+
- [`@ttsc/banner`](https://github.com/samchon/ttsc/tree/master/packages/banner): adds `@packageDocumentation` JSDoc banners.
|
|
153
|
+
- [`@ttsc/lint`](https://github.com/samchon/ttsc/tree/master/packages/lint): reports lint violations as TypeScript compile errors.
|
|
183
154
|
- [`@ttsc/paths`](https://github.com/samchon/ttsc/tree/master/packages/paths): rewrites source path aliases so JS and declaration emit receive relative imports.
|
|
184
155
|
- [`@ttsc/strip`](https://github.com/samchon/ttsc/tree/master/packages/strip): removes configured calls and `debugger` statements.
|
|
185
|
-
- [`@ttsc/unplugin`](https://github.com/samchon/ttsc/tree/master/packages/unplugin): runs
|
|
156
|
+
- [`@ttsc/unplugin`](https://github.com/samchon/ttsc/tree/master/packages/unplugin): runs `ttsc` plugins inside bundlers supported by `unplugin`.
|
|
186
157
|
|
|
187
158
|
Plugin authors should start from the [`Guide Documents`](https://github.com/samchon/ttsc/tree/master/docs).
|
|
188
159
|
|
|
189
160
|
Ecosystem plugins are listed below; PRs adding `ttsc` plugins are welcome.
|
|
190
161
|
|
|
191
|
-
- [
|
|
162
|
+
- [`nestia`](https://github.com/samchon/nestia): generates NestJS routes, OpenAPI, and SDKs.
|
|
192
163
|
- [`typia`](https://github.com/samchon/typia): generates validators, serializers, and type-driven runtime code.
|
|
193
164
|
|
|
194
165
|
## References
|
package/cmd/ttsc/api_compile.go
CHANGED
|
@@ -7,24 +7,25 @@
|
|
|
7
7
|
package main
|
|
8
8
|
|
|
9
9
|
import (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
"encoding/json"
|
|
11
|
+
"flag"
|
|
12
|
+
"fmt"
|
|
13
|
+
"os"
|
|
14
|
+
"path/filepath"
|
|
15
|
+
"strings"
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
20
|
+
cwdutil "github.com/samchon/ttsc/packages/ttsc/internal/cwd"
|
|
20
21
|
)
|
|
21
22
|
|
|
22
23
|
type apiCompileResult struct {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
// Diagnostics is omitted only when the compiler produced no diagnostics.
|
|
25
|
+
// Output is still returned in diagnostic cases because TypeScript-Go may
|
|
26
|
+
// produce partial emit text before a build-failing error is reported.
|
|
27
|
+
Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
|
|
28
|
+
Output map[string]string `json:"output"`
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
// apiCompileDiagnostic mirrors the public TypeScript-side diagnostic DTO.
|
|
@@ -32,120 +33,113 @@ type apiCompileResult struct {
|
|
|
32
33
|
// `character`) instead of Go naming so callers can pass the data through
|
|
33
34
|
// without remapping.
|
|
34
35
|
type apiCompileDiagnostic struct {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
File *string `json:"file"`
|
|
37
|
+
Category string `json:"category"`
|
|
38
|
+
Code int32 `json:"code"`
|
|
39
|
+
Start *int `json:"start,omitempty"`
|
|
40
|
+
Length *int `json:"length,omitempty"`
|
|
41
|
+
Line int `json:"line,omitempty"`
|
|
42
|
+
Character int `json:"character,omitempty"`
|
|
43
|
+
MessageText string `json:"messageText"`
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
func runAPICompile(args []string) int {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
fs := flag.NewFlagSet("api-compile", flag.ContinueOnError)
|
|
48
|
+
fs.SetOutput(stderr)
|
|
49
|
+
tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
|
|
50
|
+
cwdOverride := fs.String("cwd", "", "override the working directory")
|
|
51
|
+
if err := fs.Parse(args); err != nil {
|
|
52
|
+
return 2
|
|
53
|
+
}
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
cwd, err := cwdutil.Resolve(*cwdOverride, os.Getwd)
|
|
56
|
+
if err != nil {
|
|
57
|
+
fmt.Fprintf(stderr, "ttsc: %v\n", err)
|
|
58
|
+
return 2
|
|
59
|
+
}
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
|
|
62
|
+
ForceEmit: true,
|
|
63
|
+
})
|
|
64
|
+
if err != nil {
|
|
65
|
+
fmt.Fprintf(stderr, "ttsc api-compile: %v\n", err)
|
|
66
|
+
return 2
|
|
67
|
+
}
|
|
68
|
+
if prog != nil {
|
|
69
|
+
defer prog.Close()
|
|
70
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
71
|
+
}
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
73
|
+
output := map[string]string{}
|
|
74
|
+
if prog != nil {
|
|
75
|
+
rewrites := driver.NewRewriteSet()
|
|
76
|
+
// Capture WriteFile output in a map keyed by project-relative paths. This
|
|
77
|
+
// gives the JS API a deterministic object and avoids touching outDir.
|
|
78
|
+
writeFile := shimcompiler.WriteFile(
|
|
79
|
+
func(fileName, text string, _ *shimcompiler.WriteFileData) error {
|
|
80
|
+
output[apiOutputKey(cwd, fileName)] = text
|
|
81
|
+
return nil
|
|
82
|
+
},
|
|
83
|
+
)
|
|
84
|
+
_, emitDiags, err := prog.EmitAll(rewrites, writeFile)
|
|
85
|
+
if err != nil {
|
|
86
|
+
fmt.Fprintf(stderr, "ttsc api-compile: emit failed: %v\n", err)
|
|
87
|
+
return 3
|
|
88
|
+
}
|
|
89
|
+
diags = append(diags, emitDiags...)
|
|
90
|
+
}
|
|
89
91
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
result := apiCompileResult{
|
|
93
|
+
Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
|
|
94
|
+
Output: output,
|
|
95
|
+
}
|
|
96
|
+
for _, diag := range diags {
|
|
97
|
+
result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
|
|
98
|
+
}
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
func resolveBuildCwd(cwdOverride string) (string, bool) {
|
|
111
|
-
if cwdOverride != "" {
|
|
112
|
-
return cwdOverride, true
|
|
113
|
-
}
|
|
114
|
-
cwd, err := os.Getwd()
|
|
115
|
-
if err != nil {
|
|
116
|
-
fmt.Fprintf(stderr, "ttsc: could not get working directory: %v\n", err)
|
|
117
|
-
return "", false
|
|
118
|
-
}
|
|
119
|
-
return cwd, true
|
|
100
|
+
data, err := json.Marshal(result)
|
|
101
|
+
if err != nil {
|
|
102
|
+
fmt.Fprintf(stderr, "ttsc api-compile: result marshal failed: %v\n", err)
|
|
103
|
+
return 3
|
|
104
|
+
}
|
|
105
|
+
fmt.Fprintln(stdout, string(data))
|
|
106
|
+
if driver.CountErrors(diags) > 0 {
|
|
107
|
+
return 2
|
|
108
|
+
}
|
|
109
|
+
return 0
|
|
120
110
|
}
|
|
121
111
|
|
|
122
112
|
func toAPICompileDiagnostic(diag driver.Diagnostic) apiCompileDiagnostic {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
113
|
+
var file *string
|
|
114
|
+
if diag.File != "" {
|
|
115
|
+
value := diag.File
|
|
116
|
+
file = &value
|
|
117
|
+
}
|
|
118
|
+
category := "error"
|
|
119
|
+
if diag.Severity == driver.SeverityWarning {
|
|
120
|
+
category = "warning"
|
|
121
|
+
}
|
|
122
|
+
return apiCompileDiagnostic{
|
|
123
|
+
File: file,
|
|
124
|
+
Category: category,
|
|
125
|
+
Code: diag.Code,
|
|
126
|
+
Start: diag.Start,
|
|
127
|
+
Length: diag.Length,
|
|
128
|
+
Line: diag.Line,
|
|
129
|
+
Character: diag.Column,
|
|
130
|
+
MessageText: diag.Message,
|
|
131
|
+
}
|
|
142
132
|
}
|
|
143
133
|
|
|
144
134
|
func apiOutputKey(cwd, fileName string) string {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
135
|
+
// Relative keys are the API contract for files inside the project. Absolute
|
|
136
|
+
// keys are preserved for uncommon compiler outputs outside cwd.
|
|
137
|
+
if rel, err := filepath.Rel(cwd, fileName); err == nil && !isOutsideRelativePath(rel) {
|
|
138
|
+
return filepath.ToSlash(rel)
|
|
139
|
+
}
|
|
140
|
+
return filepath.ToSlash(fileName)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
func isOutsideRelativePath(rel string) bool {
|
|
144
|
+
return rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator))
|
|
151
145
|
}
|
|
@@ -7,66 +7,69 @@
|
|
|
7
7
|
package main
|
|
8
8
|
|
|
9
9
|
import (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
"encoding/json"
|
|
11
|
+
"flag"
|
|
12
|
+
"fmt"
|
|
13
|
+
"os"
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
16
|
+
cwdutil "github.com/samchon/ttsc/packages/ttsc/internal/cwd"
|
|
15
17
|
)
|
|
16
18
|
|
|
17
19
|
type apiTransformResult struct {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
// TypeScript contains every non-library source file visible through the
|
|
21
|
+
// Program facade, keyed the same way api-compile keys emitted files.
|
|
22
|
+
Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
|
|
23
|
+
TypeScript map[string]string `json:"typescript"`
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
func runAPITransform(args []string) int {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
fs := flag.NewFlagSet("api-transform", flag.ContinueOnError)
|
|
28
|
+
fs.SetOutput(stderr)
|
|
29
|
+
tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
|
|
30
|
+
cwdOverride := fs.String("cwd", "", "override the working directory")
|
|
31
|
+
if err := fs.Parse(args); err != nil {
|
|
32
|
+
return 2
|
|
33
|
+
}
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
cwd, err := cwdutil.Resolve(*cwdOverride, os.Getwd)
|
|
36
|
+
if err != nil {
|
|
37
|
+
fmt.Fprintf(stderr, "ttsc: %v\n", err)
|
|
38
|
+
return 2
|
|
39
|
+
}
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
|
|
42
|
+
ForceNoEmit: true,
|
|
43
|
+
})
|
|
44
|
+
if err != nil {
|
|
45
|
+
fmt.Fprintf(stderr, "ttsc api-transform: %v\n", err)
|
|
46
|
+
return 2
|
|
47
|
+
}
|
|
48
|
+
typescript := map[string]string{}
|
|
49
|
+
if prog != nil {
|
|
50
|
+
defer prog.Close()
|
|
51
|
+
for _, file := range prog.SourceFiles() {
|
|
52
|
+
typescript[apiOutputKey(cwd, file.FileName())] = file.Text()
|
|
53
|
+
}
|
|
54
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
55
|
+
}
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
result := apiTransformResult{
|
|
58
|
+
Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
|
|
59
|
+
TypeScript: typescript,
|
|
60
|
+
}
|
|
61
|
+
for _, diag := range diags {
|
|
62
|
+
result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
|
|
63
|
+
}
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
data, err := json.Marshal(result)
|
|
66
|
+
if err != nil {
|
|
67
|
+
fmt.Fprintf(stderr, "ttsc api-transform: result marshal failed: %v\n", err)
|
|
68
|
+
return 3
|
|
69
|
+
}
|
|
70
|
+
fmt.Fprintln(stdout, string(data))
|
|
71
|
+
if driver.CountErrors(diags) > 0 {
|
|
72
|
+
return 2
|
|
73
|
+
}
|
|
74
|
+
return 0
|
|
72
75
|
}
|