ttsc 0.30.2 → 0.30.3

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 (2) hide show
  1. package/package.json +8 -8
  2. package/utility/host.go +86 -36
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttsc",
3
- "version": "0.30.2",
3
+ "version": "0.30.3",
4
4
  "description": "General-purpose TypeScript-Go compiler, runtime, plugin host, and LSP host.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -47,13 +47,13 @@
47
47
  "typescript": "^7.0.2"
48
48
  },
49
49
  "optionalDependencies": {
50
- "@ttsc/linux-x64": "0.30.2",
51
- "@ttsc/linux-arm": "0.30.2",
52
- "@ttsc/linux-arm64": "0.30.2",
53
- "@ttsc/darwin-x64": "0.30.2",
54
- "@ttsc/darwin-arm64": "0.30.2",
55
- "@ttsc/win32-x64": "0.30.2",
56
- "@ttsc/win32-arm64": "0.30.2"
50
+ "@ttsc/linux-x64": "0.30.3",
51
+ "@ttsc/linux-arm": "0.30.3",
52
+ "@ttsc/darwin-arm64": "0.30.3",
53
+ "@ttsc/win32-x64": "0.30.3",
54
+ "@ttsc/linux-arm64": "0.30.3",
55
+ "@ttsc/win32-arm64": "0.30.3",
56
+ "@ttsc/darwin-x64": "0.30.3"
57
57
  },
58
58
  "sideEffects": [
59
59
  "./lib/register.js",
package/utility/host.go CHANGED
@@ -39,8 +39,8 @@ type hostOptions struct {
39
39
  }
40
40
 
41
41
  // transformResult is the JSON envelope written to stdout by RunTransform.
42
- // TypeScript maps relative output key → printer output; Diagnostics is
43
- // reserved for future plugin diagnostics (currently always empty/omitted).
42
+ // TypeScript maps relative output key → printer output. Failed transforms
43
+ // retain diagnostics and recovery inputs without publishing partial output.
44
44
  // Graph carries the host-owned reference graph (direct resolved reference
45
45
  // edges, global-scope files, tsconfig extends chain) keyed like TypeScript,
46
46
  // so cache layers can register every file whose content can influence a
@@ -52,7 +52,7 @@ type transformResult struct {
52
52
  // driver.Program.TransformDependenciesFor.
53
53
  Dependencies map[string][]string `json:"dependencies,omitempty"`
54
54
  DependenciesComplete []string `json:"dependenciesComplete,omitempty"`
55
- Diagnostics []any `json:"diagnostics,omitempty"`
55
+ Diagnostics []transformDiagnostic `json:"diagnostics,omitempty"`
56
56
  Graph *driver.TransformGraph `json:"graph,omitempty"`
57
57
  HostInputs []string `json:"hostInputs,omitempty"`
58
58
  HostInputHashes map[string]*string `json:"hostInputHashes,omitempty"`
@@ -60,6 +60,18 @@ type transformResult struct {
60
60
  TypeScript map[string]string `json:"typescript"`
61
61
  }
62
62
 
63
+ // transformDiagnostic matches the public JavaScript compiler diagnostic shape.
64
+ type transformDiagnostic struct {
65
+ File *string `json:"file"`
66
+ Category string `json:"category"`
67
+ Code int32 `json:"code"`
68
+ Start *int `json:"start,omitempty"`
69
+ Length *int `json:"length,omitempty"`
70
+ Line int `json:"line,omitempty"`
71
+ Character int `json:"character,omitempty"`
72
+ MessageText string `json:"messageText"`
73
+ }
74
+
63
75
  // RunCheck validates the project and linked plugin configuration without
64
76
  // emitting output.
65
77
  func RunCheck(args []string) int {
@@ -138,34 +150,60 @@ func RunTransformWithIO(args []string, stdout, stderr io.Writer) int {
138
150
  if !ok {
139
151
  return 2
140
152
  }
141
- prog, _, ok := loadUtilityProgram(opts)
153
+ prog, _, diags, ok := loadUtilityProgramWithDiagnostics(opts)
142
154
  if !ok {
143
155
  return 2
144
156
  }
145
- defer prog.Close()
146
- // Compute the reference graph before linked plugins run: plugin hooks
147
- // mutate parsed ASTs in place (e.g. @ttsc/paths rewrites import
148
- // specifiers), and the graph must describe the original source's resolved
149
- // references — the transform's inputs — not the mutated output.
150
- graph := driver.NewTransformGraph(prog, opts.cwd)
151
- if err := prog.ApplyLinkedPlugins(); err != nil {
152
- fmt.Fprintln(opts.stderr, err)
153
- return 2
157
+ out := transformResult{TypeScript: map[string]string{}}
158
+ if prog != nil {
159
+ defer prog.Close()
160
+ // The same failed Program owns the missing resolution candidates needed
161
+ // for recovery. Capture them before closing it or applying mutations.
162
+ out.Graph = driver.NewTransformGraph(prog, opts.cwd)
163
+ }
164
+ if len(diags) != 0 {
165
+ driver.WritePrettyDiagnostics(opts.stderr, diags, opts.cwd)
166
+ } else if prog != nil {
167
+ if err := prog.ApplyLinkedPlugins(); err != nil {
168
+ fmt.Fprintln(opts.stderr, err)
169
+ diags = append(diags, driver.Diagnostic{Message: err.Error()})
170
+ } else {
171
+ printer := shimprinter.NewPrinter(shimprinter.PrinterOptions{}, shimprinter.PrintHandlers{}, nil)
172
+ for _, file := range prog.SourceFiles() {
173
+ text := shimprinter.EmitSourceFile(printer, file)
174
+ out.TypeScript[apiOutputKey(opts.cwd, file.FileName())] = text
175
+ }
176
+ dependencies := prog.TransformDependenciesFor(opts.cwd)
177
+ out.Dependencies = dependencies.Dependencies
178
+ out.DependenciesComplete = dependencies.Complete
179
+ }
180
+ }
181
+ if prog != nil {
182
+ out.HostInputs = prog.PluginHostInputs()
183
+ out.HostInputHashes = prog.PluginHostInputHashes()
184
+ out.HostInputRealpaths = prog.PluginHostInputRealpaths()
185
+ }
186
+ for _, diag := range diags {
187
+ var file *string
188
+ if diag.File != "" {
189
+ value := diag.File
190
+ file = &value
191
+ }
192
+ category := "error"
193
+ if diag.Severity == driver.SeverityWarning {
194
+ category = "warning"
195
+ }
196
+ out.Diagnostics = append(out.Diagnostics, transformDiagnostic{
197
+ File: file, Category: category, Code: diag.Code,
198
+ Start: diag.Start, Length: diag.Length, Line: diag.Line,
199
+ Character: diag.Column, MessageText: diag.Message,
200
+ })
154
201
  }
155
- printer := shimprinter.NewPrinter(shimprinter.PrinterOptions{}, shimprinter.PrintHandlers{}, nil)
156
- out := transformResult{TypeScript: map[string]string{}, Graph: graph}
157
- for _, file := range prog.SourceFiles() {
158
- text := shimprinter.EmitSourceFile(printer, file)
159
- out.TypeScript[apiOutputKey(opts.cwd, file.FileName())] = text
160
- }
161
- dependencies := prog.TransformDependenciesFor(opts.cwd)
162
- out.Dependencies = dependencies.Dependencies
163
- out.DependenciesComplete = dependencies.Complete
164
- out.HostInputs = prog.PluginHostInputs()
165
- out.HostInputHashes = prog.PluginHostInputHashes()
166
- out.HostInputRealpaths = prog.PluginHostInputRealpaths()
167
202
  data, _ := json.Marshal(out)
168
203
  fmt.Fprintln(opts.stdout, string(data))
204
+ if len(diags) != 0 {
205
+ return 2
206
+ }
169
207
  return 0
170
208
  }
171
209
 
@@ -297,10 +335,28 @@ func flagName(arg string) (string, bool) {
297
335
  // Program along with the decoded plugin entries. Returns (nil, nil, false) and
298
336
  // prints diagnostics to stderr on any error.
299
337
  func loadUtilityProgram(opts hostOptions) (*driver.Program, []driver.PluginEntry, bool) {
338
+ prog, entries, diags, ok := loadUtilityProgramWithDiagnostics(opts)
339
+ if !ok {
340
+ return nil, nil, false
341
+ }
342
+ if len(diags) != 0 {
343
+ driver.WritePrettyDiagnostics(opts.stderr, diags, opts.cwd)
344
+ if prog != nil {
345
+ _ = prog.Close()
346
+ }
347
+ return nil, nil, false
348
+ }
349
+ return prog, entries, true
350
+ }
351
+
352
+ // loadUtilityProgramWithDiagnostics leaves a loaded Program owned by its caller,
353
+ // even on compiler diagnostics. Transform must publish its recovery graph;
354
+ // check/build/serve retain their existing rejection boundary in the wrapper.
355
+ func loadUtilityProgramWithDiagnostics(opts hostOptions) (*driver.Program, []driver.PluginEntry, []driver.Diagnostic, bool) {
300
356
  entries, err := parsePluginEntries(opts.pluginsJSON)
301
357
  if err != nil {
302
358
  fmt.Fprintln(opts.stderr, err)
303
- return nil, nil, false
359
+ return nil, nil, nil, false
304
360
  }
305
361
  restoreEnv := setLinkedPluginManifest(opts.pluginsJSON)
306
362
  defer restoreEnv()
@@ -317,18 +373,12 @@ func loadUtilityProgram(opts hostOptions) (*driver.Program, []driver.PluginEntry
317
373
  })
318
374
  if err != nil {
319
375
  fmt.Fprintf(opts.stderr, "ttsc utility: %v\n", err)
320
- return nil, nil, false
376
+ return nil, nil, nil, false
321
377
  }
322
- if len(diags) > 0 {
323
- driver.WritePrettyDiagnostics(opts.stderr, diags, opts.cwd)
324
- return nil, nil, false
378
+ if prog != nil {
379
+ diags = append(diags, prog.Diagnostics()...)
325
380
  }
326
- if diags := prog.Diagnostics(); len(diags) > 0 {
327
- driver.WritePrettyDiagnostics(opts.stderr, diags, opts.cwd)
328
- _ = prog.Close()
329
- return nil, nil, false
330
- }
331
- return prog, entries, true
381
+ return prog, entries, diags, true
332
382
  }
333
383
 
334
384
  // parsePluginEntries decodes the --plugins-json flag value into a slice of