@ttsc/wasm 0.12.2 → 0.12.4
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/cmd/ttsc-wasm/main.go +101 -89
- package/cmd/ttsc-wasm/main_wasm.go +6 -4
- package/dist/ttsc.wasm +0 -0
- package/host/api.go +154 -145
- package/host/doc.go +12 -12
- package/host/host.go +236 -225
- package/host/host_native.go +5 -2
- package/host/plugin.go +31 -31
- package/lib/src/MemFS.d.ts +35 -0
- package/lib/src/MemFS.js +57 -4
- package/lib/src/MemFS.js.map +1 -1
- package/lib/src/api.d.ts +46 -13
- package/lib/src/api.js +7 -4
- package/lib/src/api.js.map +1 -1
- package/lib/src/index.d.ts +1 -1
- package/lib/src/index.js +10 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/instantiate.d.ts +10 -7
- package/lib/src/instantiate.js +20 -3
- package/lib/src/instantiate.js.map +1 -1
- package/package.json +2 -2
- package/shim-vendor/shim/ast/go.mod +9 -0
- package/shim-vendor/shim/ast/go.sum +20 -0
- package/shim-vendor/shim/ast/safe_text.go +86 -0
- package/shim-vendor/shim/ast/shim.go +24 -0
- package/shim-vendor/shim/ast/test/node_text_joins_multi_hop_qualified_name_test.go +32 -0
- package/shim-vendor/shim/ast/test/node_text_joins_one_hop_qualified_name_test.go +31 -0
- package/shim-vendor/shim/ast/test/node_text_returns_empty_for_nil_test.go +23 -0
- package/shim-vendor/shim/ast/test/node_text_returns_identifier_text_test.go +27 -0
- package/shim-vendor/shim/ast/test/node_text_skips_empty_qualified_left_test.go +30 -0
- package/shim-vendor/shim/checker/shim.go +35 -0
- package/shim-vendor/shim/core/shim.go +17 -0
- package/shim-vendor/shim/diagnosticwriter/shim.go +4 -0
- package/shim-vendor/shim/lsp/shim.go +3 -3
- package/shim-vendor/shim/printer/shim.go +20 -0
- package/src/MemFS.ts +92 -7
- package/src/api.ts +46 -13
- package/src/index.ts +1 -5
- package/src/instantiate.ts +37 -14
package/cmd/ttsc-wasm/main.go
CHANGED
|
@@ -9,122 +9,134 @@
|
|
|
9
9
|
package main
|
|
10
10
|
|
|
11
11
|
import (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
"fmt"
|
|
13
|
+
"io"
|
|
14
|
+
"os"
|
|
15
|
+
"runtime"
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
"github.com/samchon/ttsc/packages/wasm/host"
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
// Build metadata. Overridden via -ldflags from build/build-wasm.cjs.
|
|
21
21
|
var (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
version = "0.0.0-dev"
|
|
23
|
+
commit = "dev"
|
|
24
|
+
date = "unknown"
|
|
25
25
|
)
|
|
26
26
|
|
|
27
27
|
func main() {
|
|
28
|
-
|
|
28
|
+
os.Exit(run(os.Args[1:]))
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
// run is the testable core of main. It dispatches the first argument as a
|
|
32
|
+
// subcommand and returns the OS exit code.
|
|
31
33
|
func run(args []string) int {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
if len(args) == 0 {
|
|
35
|
+
printHelp(os.Stdout)
|
|
36
|
+
return 0
|
|
37
|
+
}
|
|
38
|
+
switch args[0] {
|
|
39
|
+
case "-h", "--help", "help":
|
|
40
|
+
printHelp(os.Stdout)
|
|
41
|
+
return 0
|
|
42
|
+
case "-v", "--version", "version":
|
|
43
|
+
printVersion(os.Stdout)
|
|
44
|
+
return 0
|
|
45
|
+
case "build":
|
|
46
|
+
return runBuild(args[1:])
|
|
47
|
+
case "check":
|
|
48
|
+
return runCheck(args[1:])
|
|
49
|
+
case "transform":
|
|
50
|
+
return runTransform(args[1:])
|
|
51
|
+
default:
|
|
52
|
+
fmt.Fprintf(os.Stderr, "ttsc-wasm: unknown command %q\n", args[0])
|
|
53
|
+
printHelp(os.Stderr)
|
|
54
|
+
return 2
|
|
55
|
+
}
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
// runBuild invokes host.Build and writes the JSON result to stdout.
|
|
56
59
|
func runBuild(args []string) int {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
cwd, tsconfig := parseProject(args)
|
|
61
|
+
data, code, err := host.Build(cwd, tsconfig)
|
|
62
|
+
if err != nil {
|
|
63
|
+
fmt.Fprintf(os.Stderr, "ttsc-wasm build: %v\n", err)
|
|
64
|
+
return 2
|
|
65
|
+
}
|
|
66
|
+
_, _ = os.Stdout.Write(append(data, '\n'))
|
|
67
|
+
return code
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
// runCheck invokes host.Check and writes the JSON result to stdout.
|
|
67
71
|
func runCheck(args []string) int {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
cwd, tsconfig := parseProject(args)
|
|
73
|
+
data, code, err := host.Check(cwd, tsconfig)
|
|
74
|
+
if err != nil {
|
|
75
|
+
fmt.Fprintf(os.Stderr, "ttsc-wasm check: %v\n", err)
|
|
76
|
+
return 2
|
|
77
|
+
}
|
|
78
|
+
_, _ = os.Stdout.Write(append(data, '\n'))
|
|
79
|
+
return code
|
|
76
80
|
}
|
|
77
81
|
|
|
82
|
+
// runTransform invokes host.Transform and writes the JSON result to stdout.
|
|
78
83
|
func runTransform(args []string) int {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
cwd, tsconfig := parseProject(args)
|
|
85
|
+
data, code, err := host.Transform(cwd, tsconfig)
|
|
86
|
+
if err != nil {
|
|
87
|
+
fmt.Fprintf(os.Stderr, "ttsc-wasm transform: %v\n", err)
|
|
88
|
+
return 2
|
|
89
|
+
}
|
|
90
|
+
_, _ = os.Stdout.Write(append(data, '\n'))
|
|
91
|
+
return code
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
// parseProject extracts --cwd and --tsconfig from args, defaulting to the
|
|
95
|
+
// process working directory and "tsconfig.json" respectively. Both the
|
|
96
|
+
// `--flag value` and `--flag=value` forms are accepted.
|
|
89
97
|
func parseProject(args []string) (string, string) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
98
|
+
cwd, _ := os.Getwd()
|
|
99
|
+
tsconfig := "tsconfig.json"
|
|
100
|
+
const cwdPrefix = "--cwd="
|
|
101
|
+
const tsconfigPrefix = "--tsconfig="
|
|
102
|
+
for i := 0; i < len(args); i++ {
|
|
103
|
+
arg := args[i]
|
|
104
|
+
switch {
|
|
105
|
+
case arg == "--cwd" && i+1 < len(args):
|
|
106
|
+
cwd = args[i+1]
|
|
107
|
+
i++
|
|
108
|
+
case len(arg) > len(cwdPrefix) && arg[:len(cwdPrefix)] == cwdPrefix:
|
|
109
|
+
cwd = arg[len(cwdPrefix):]
|
|
110
|
+
case arg == "--tsconfig" && i+1 < len(args):
|
|
111
|
+
tsconfig = args[i+1]
|
|
112
|
+
i++
|
|
113
|
+
case len(arg) > len(tsconfigPrefix) && arg[:len(tsconfigPrefix)] == tsconfigPrefix:
|
|
114
|
+
tsconfig = arg[len(tsconfigPrefix):]
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return cwd, tsconfig
|
|
108
118
|
}
|
|
109
119
|
|
|
120
|
+
// printHelp writes the usage summary to w.
|
|
110
121
|
func printHelp(w io.Writer) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
fmt.Fprintln(w, "Usage: ttsc-wasm <command> [--cwd=<dir>] [--tsconfig=<path>]")
|
|
123
|
+
fmt.Fprintln(w, "Commands:")
|
|
124
|
+
fmt.Fprintln(w, " build compile a project and print the JSON result")
|
|
125
|
+
fmt.Fprintln(w, " check type-check a project without emit")
|
|
126
|
+
fmt.Fprintln(w, " transform return every source file the program saw")
|
|
127
|
+
fmt.Fprintln(w, " version print version banner")
|
|
117
128
|
}
|
|
118
129
|
|
|
130
|
+
// printVersion writes the build metadata banner to w.
|
|
119
131
|
func printVersion(w io.Writer) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
fmt.Fprintf(
|
|
133
|
+
w,
|
|
134
|
+
"ttsc-wasm %s (commit %s, built %s, %s/%s, go %s)\n",
|
|
135
|
+
version,
|
|
136
|
+
commit,
|
|
137
|
+
date,
|
|
138
|
+
runtime.GOOS,
|
|
139
|
+
runtime.GOARCH,
|
|
140
|
+
runtime.Version(),
|
|
141
|
+
)
|
|
130
142
|
}
|
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
package main
|
|
8
8
|
|
|
9
9
|
import (
|
|
10
|
-
|
|
10
|
+
"github.com/samchon/ttsc/packages/wasm/host"
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
+
// main installs the base ttsc API on globalThis and blocks forever.
|
|
14
|
+
// Expose never returns; the select{} inside it keeps the wasm runtime alive.
|
|
13
15
|
func main() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
host.Expose("ttsc", host.Config{
|
|
17
|
+
Plugins: nil,
|
|
18
|
+
})
|
|
17
19
|
}
|
package/dist/ttsc.wasm
CHANGED
|
Binary file
|
package/host/api.go
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
package host
|
|
7
7
|
|
|
8
8
|
import (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
"encoding/json"
|
|
10
|
+
"fmt"
|
|
11
|
+
"path/filepath"
|
|
12
|
+
"strings"
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
// APIResult is the JSON shape every plugin-dispatch endpoint returns to the
|
|
@@ -21,185 +21,194 @@ import (
|
|
|
21
21
|
// usage error, 3 runtime error). `stdout` / `stderr` are raw strings the
|
|
22
22
|
// caller can render in a console panel.
|
|
23
23
|
type APIResult struct {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
Code int `json:"code"`
|
|
25
|
+
Stdout string `json:"stdout"`
|
|
26
|
+
Stderr string `json:"stderr"`
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// CompileResult mirrors `ttsc api-compile`. Field names are TypeScript-style
|
|
30
30
|
// so JS callers can use it directly without remapping.
|
|
31
31
|
type CompileResult struct {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
Diagnostics []CompileDiagnostic `json:"diagnostics,omitempty"`
|
|
33
|
+
// Output maps cwd-relative paths to emitted JS / d.ts text. Empty when
|
|
34
|
+
// the program produced no files (e.g. `noEmit` projects).
|
|
35
|
+
Output map[string]string `json:"output"`
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// TransformResult is the no-emit companion. The `typescript` map keys files
|
|
39
39
|
// the same way `output` does in compile mode.
|
|
40
40
|
type TransformResult struct {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
Diagnostics []CompileDiagnostic `json:"diagnostics,omitempty"`
|
|
42
|
+
TypeScript map[string]string `json:"typescript"`
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// CompileDiagnostic is the public TypeScript-side diagnostic DTO. Mirrors the
|
|
46
46
|
// shape `ttsc api-compile` writes so the JS host can render it without
|
|
47
47
|
// remapping fields.
|
|
48
48
|
type CompileDiagnostic struct {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
File *string `json:"file"`
|
|
50
|
+
Category string `json:"category"`
|
|
51
|
+
Code int32 `json:"code"`
|
|
52
|
+
Start *int `json:"start,omitempty"`
|
|
53
|
+
Length *int `json:"length,omitempty"`
|
|
54
|
+
Line int `json:"line,omitempty"`
|
|
55
|
+
Character int `json:"character,omitempty"`
|
|
56
|
+
MessageText string `json:"messageText"`
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// Build runs `ttsc build`-shaped emit: load the project, emit JS, return the
|
|
60
60
|
// emitted text map + diagnostics as JSON. `cwd` must be an absolute path
|
|
61
61
|
// inside the host filesystem; `tsconfigPath` may be relative to cwd.
|
|
62
62
|
func Build(cwd, tsconfigPath string) ([]byte, int, error) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
63
|
+
prog, diags, err := driver.LoadProgram(cwd, tsconfigPath, driver.LoadProgramOptions{
|
|
64
|
+
ForceEmit: true,
|
|
65
|
+
})
|
|
66
|
+
if err != nil {
|
|
67
|
+
return nil, 2, err
|
|
68
|
+
}
|
|
69
|
+
if prog != nil {
|
|
70
|
+
defer prog.Close()
|
|
71
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
72
|
+
}
|
|
73
|
+
output := map[string]string{}
|
|
74
|
+
if prog != nil {
|
|
75
|
+
rewrites := driver.NewRewriteSet()
|
|
76
|
+
writeFile := shimcompiler.WriteFile(
|
|
77
|
+
func(fileName, text string, _ *shimcompiler.WriteFileData) error {
|
|
78
|
+
output[apiOutputKey(cwd, fileName)] = text
|
|
79
|
+
return nil
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
_, emitDiags, eerr := prog.EmitAll(rewrites, writeFile)
|
|
83
|
+
if eerr != nil {
|
|
84
|
+
return nil, 3, fmt.Errorf("emit failed: %w", eerr)
|
|
85
|
+
}
|
|
86
|
+
diags = append(diags, emitDiags...)
|
|
87
|
+
}
|
|
88
|
+
result := CompileResult{
|
|
89
|
+
Diagnostics: make([]CompileDiagnostic, 0, len(diags)),
|
|
90
|
+
Output: output,
|
|
91
|
+
}
|
|
92
|
+
for _, d := range diags {
|
|
93
|
+
result.Diagnostics = append(result.Diagnostics, toAPIDiagnostic(d))
|
|
94
|
+
}
|
|
95
|
+
data, err := json.Marshal(result)
|
|
96
|
+
if err != nil {
|
|
97
|
+
return nil, 3, fmt.Errorf("result marshal failed: %w", err)
|
|
98
|
+
}
|
|
99
|
+
code := 0
|
|
100
|
+
if driver.CountErrors(diags) > 0 {
|
|
101
|
+
code = 2
|
|
102
|
+
}
|
|
103
|
+
return data, code, nil
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
// Check runs the typecheck pipeline without emitting JS. The returned JSON
|
|
107
107
|
// has the same shape as Build but with an empty `output` map.
|
|
108
108
|
func Check(cwd, tsconfigPath string) ([]byte, int, error) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
109
|
+
prog, diags, err := driver.LoadProgram(cwd, tsconfigPath, driver.LoadProgramOptions{
|
|
110
|
+
ForceNoEmit: true,
|
|
111
|
+
})
|
|
112
|
+
if err != nil {
|
|
113
|
+
return nil, 2, err
|
|
114
|
+
}
|
|
115
|
+
if prog != nil {
|
|
116
|
+
defer prog.Close()
|
|
117
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
118
|
+
}
|
|
119
|
+
result := CompileResult{
|
|
120
|
+
Diagnostics: make([]CompileDiagnostic, 0, len(diags)),
|
|
121
|
+
Output: map[string]string{},
|
|
122
|
+
}
|
|
123
|
+
for _, d := range diags {
|
|
124
|
+
result.Diagnostics = append(result.Diagnostics, toAPIDiagnostic(d))
|
|
125
|
+
}
|
|
126
|
+
data, err := json.Marshal(result)
|
|
127
|
+
if err != nil {
|
|
128
|
+
return nil, 3, fmt.Errorf("result marshal failed: %w", err)
|
|
129
|
+
}
|
|
130
|
+
code := 0
|
|
131
|
+
if driver.CountErrors(diags) > 0 {
|
|
132
|
+
code = 2
|
|
133
|
+
}
|
|
134
|
+
return data, code, nil
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
// Transform returns every source file the program saw, keyed by
|
|
138
138
|
// project-relative path. The playground uses this to render the TS view
|
|
139
139
|
// after source rewrites (e.g. paths rewriting) have been applied.
|
|
140
140
|
func Transform(cwd, tsconfigPath string) ([]byte, int, error) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
141
|
+
prog, diags, err := driver.LoadProgram(cwd, tsconfigPath, driver.LoadProgramOptions{
|
|
142
|
+
ForceNoEmit: true,
|
|
143
|
+
})
|
|
144
|
+
if err != nil {
|
|
145
|
+
return nil, 2, err
|
|
146
|
+
}
|
|
147
|
+
typescript := map[string]string{}
|
|
148
|
+
if prog != nil {
|
|
149
|
+
defer prog.Close()
|
|
150
|
+
for _, file := range prog.SourceFiles() {
|
|
151
|
+
typescript[apiOutputKey(cwd, file.FileName())] = file.Text()
|
|
152
|
+
}
|
|
153
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
154
|
+
}
|
|
155
|
+
result := TransformResult{
|
|
156
|
+
Diagnostics: make([]CompileDiagnostic, 0, len(diags)),
|
|
157
|
+
TypeScript: typescript,
|
|
158
|
+
}
|
|
159
|
+
for _, d := range diags {
|
|
160
|
+
result.Diagnostics = append(result.Diagnostics, toAPIDiagnostic(d))
|
|
161
|
+
}
|
|
162
|
+
data, err := json.Marshal(result)
|
|
163
|
+
if err != nil {
|
|
164
|
+
return nil, 3, fmt.Errorf("result marshal failed: %w", err)
|
|
165
|
+
}
|
|
166
|
+
code := 0
|
|
167
|
+
if driver.CountErrors(diags) > 0 {
|
|
168
|
+
code = 2
|
|
169
|
+
}
|
|
170
|
+
return data, code, nil
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
// toAPIDiagnostic converts a driver.Diagnostic into the JSON-serialisable
|
|
174
|
+
// CompileDiagnostic. File paths are normalised to forward slashes so the JS
|
|
175
|
+
// host can compare them against its own MemFS paths.
|
|
173
176
|
func toAPIDiagnostic(diag driver.Diagnostic) CompileDiagnostic {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
177
|
+
var file *string
|
|
178
|
+
if diag.File != "" {
|
|
179
|
+
value := filepath.ToSlash(diag.File)
|
|
180
|
+
file = &value
|
|
181
|
+
}
|
|
182
|
+
category := "error"
|
|
183
|
+
if diag.Severity == driver.SeverityWarning {
|
|
184
|
+
category = "warning"
|
|
185
|
+
}
|
|
186
|
+
return CompileDiagnostic{
|
|
187
|
+
File: file,
|
|
188
|
+
Category: category,
|
|
189
|
+
Code: diag.Code,
|
|
190
|
+
Start: diag.Start,
|
|
191
|
+
Length: diag.Length,
|
|
192
|
+
Line: diag.Line,
|
|
193
|
+
Character: diag.Column,
|
|
194
|
+
MessageText: diag.Message,
|
|
195
|
+
}
|
|
193
196
|
}
|
|
194
197
|
|
|
198
|
+
// apiOutputKey returns the map key used in CompileResult.Output and
|
|
199
|
+
// TransformResult.TypeScript. Paths inside cwd are made project-relative;
|
|
200
|
+
// paths outside cwd (e.g. lib files) are returned as absolute slash paths.
|
|
195
201
|
func apiOutputKey(cwd, fileName string) string {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
202
|
+
rel, err := filepath.Rel(cwd, fileName)
|
|
203
|
+
if err != nil || isOutsideRelativePath(rel) {
|
|
204
|
+
return filepath.ToSlash(fileName)
|
|
205
|
+
}
|
|
206
|
+
return filepath.ToSlash(rel)
|
|
201
207
|
}
|
|
202
208
|
|
|
209
|
+
// isOutsideRelativePath reports whether rel escapes the base directory (i.e.
|
|
210
|
+
// starts with ".."). Such paths should not be presented as project-relative
|
|
211
|
+
// keys to the JS caller.
|
|
203
212
|
func isOutsideRelativePath(rel string) bool {
|
|
204
|
-
|
|
213
|
+
return rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator))
|
|
205
214
|
}
|
package/host/doc.go
CHANGED
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
//
|
|
4
4
|
// A consumer wasm looks like this:
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
6
|
+
// //go:build js
|
|
7
|
+
// package main
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
9
|
+
// import (
|
|
10
|
+
// "github.com/samchon/ttsc/packages/wasm/host"
|
|
11
|
+
// yourplugin "example.com/your/plugin"
|
|
12
|
+
// )
|
|
13
13
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
14
|
+
// func main() {
|
|
15
|
+
// // Expose never returns; it installs the JS API and blocks forever.
|
|
16
|
+
// host.Expose("yourApi", host.Config{
|
|
17
|
+
// Plugins: []host.Plugin{yourplugin.New()},
|
|
18
|
+
// })
|
|
19
|
+
// }
|
|
20
20
|
//
|
|
21
21
|
// Expose binds `globalThis[name]` to an object that exposes ttsc's base
|
|
22
22
|
// project commands (build, check, transform, version) plus a `plugin(name,
|