ttsc 0.12.4 → 0.13.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.
Files changed (52) hide show
  1. package/cmd/ttsc/api_compile.go +15 -2
  2. package/cmd/ttsc/api_transform.go +15 -2
  3. package/cmd/ttsc/build.go +34 -4
  4. package/cmd/ttsc/filter.go +70 -0
  5. package/cmd/ttsc/filter_strips_unknown_forwarded_flag_test.go +61 -0
  6. package/cmd/ttsc/flags_gen.go +30 -0
  7. package/driver/program.go +105 -4
  8. package/driver/rewrite.go +39 -4
  9. package/lib/compiler/internal/project/resolveProjectConfig.js +18 -0
  10. package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
  11. package/lib/compiler/internal/runBuild.d.ts +5 -4
  12. package/lib/compiler/internal/runBuild.js +243 -47
  13. package/lib/compiler/internal/runBuild.js.map +1 -1
  14. package/lib/flags/parser.d.ts +63 -0
  15. package/lib/flags/parser.js +254 -0
  16. package/lib/flags/parser.js.map +1 -0
  17. package/lib/flags/schema.d.ts +147 -0
  18. package/lib/flags/schema.js +405 -0
  19. package/lib/flags/schema.js.map +1 -0
  20. package/lib/launcher/internal/prepareExecution.js +3 -0
  21. package/lib/launcher/internal/prepareExecution.js.map +1 -1
  22. package/lib/launcher/internal/runTtsc.js +71 -147
  23. package/lib/launcher/internal/runTtsc.js.map +1 -1
  24. package/lib/launcher/internal/runTtsx.js +104 -72
  25. package/lib/launcher/internal/runTtsx.js.map +1 -1
  26. package/lib/plugin/internal/loadProjectPlugins.js +58 -23
  27. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  28. package/lib/structures/ITtscPlugin.d.ts +24 -0
  29. package/lib/structures/ITtscPluginCapabilities.d.ts +29 -0
  30. package/lib/structures/ITtscPluginCapabilities.js +3 -0
  31. package/lib/structures/ITtscPluginCapabilities.js.map +1 -0
  32. package/lib/structures/index.d.ts +1 -0
  33. package/lib/structures/index.js +1 -0
  34. package/lib/structures/index.js.map +1 -1
  35. package/lib/structures/internal/ITtscLoadedNativePlugin.d.ts +5 -0
  36. package/lib/structures/internal/TtscCommonOptions.d.ts +19 -0
  37. package/package.json +9 -9
  38. package/src/compiler/internal/project/resolveProjectConfig.ts +20 -0
  39. package/src/compiler/internal/runBuild.ts +288 -57
  40. package/src/flags/parser.ts +367 -0
  41. package/src/flags/schema.ts +570 -0
  42. package/src/launcher/internal/prepareExecution.ts +3 -0
  43. package/src/launcher/internal/runTtsc.ts +78 -136
  44. package/src/launcher/internal/runTtsx.ts +116 -74
  45. package/src/plugin/internal/loadProjectPlugins.ts +74 -27
  46. package/src/structures/ITtscPlugin.ts +26 -0
  47. package/src/structures/ITtscPluginCapabilities.ts +29 -0
  48. package/src/structures/index.ts +1 -0
  49. package/src/structures/internal/ITtscLoadedNativePlugin.ts +5 -0
  50. package/src/structures/internal/TtscCommonOptions.ts +19 -0
  51. package/utility/flags_gen.go +30 -0
  52. package/utility/host.go +43 -33
@@ -1,3 +1,4 @@
1
+ import type { ITtscPluginCapabilities } from "./ITtscPluginCapabilities";
1
2
  import type { ITtscPluginContributor } from "./ITtscPluginContributor";
2
3
  import type { TtscPluginStage } from "./TtscPluginStage";
3
4
 
@@ -64,6 +65,31 @@ export interface ITtscPlugin {
64
65
  */
65
66
  stage?: TtscPluginStage;
66
67
 
68
+ /**
69
+ * Optional capability flags declared by the sidecar.
70
+ *
71
+ * ttsc carries a few cross-cutting flags (`--singleThreaded`, `--checkers`,
72
+ * …) the lint sidecar parses but a typical third-party transform host
73
+ * does not. Capability flags let the plugin author opt into those flags
74
+ * explicitly, instead of ttsc keeping a hard-coded allow-list keyed by
75
+ * plugin name. Every capability defaults to `false`.
76
+ *
77
+ * @see ITtscPluginCapabilities
78
+ */
79
+ capabilities?: ITtscPluginCapabilities;
80
+
81
+ /**
82
+ * Whether a check-stage sidecar reports the normal TypeScript diagnostics for
83
+ * the project as part of its `check` subcommand.
84
+ *
85
+ * Leave this unset for ordinary check plugins that only report their own
86
+ * diagnostics; ttsc will keep running a separate `tsgo --noEmit` guard so
87
+ * TypeScript errors are not suppressed. Set it only when the sidecar builds
88
+ * the project Program and emits the same TypeScript diagnostics the guard
89
+ * would have produced.
90
+ */
91
+ reportsTypeScriptDiagnostics?: boolean;
92
+
67
93
  /**
68
94
  * Additional Go source packages to statically link into this plugin's binary
69
95
  * at build time ("plugin-within-plugin" composition).
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Optional capability flags declared by a native ttsc plugin descriptor.
3
+ *
4
+ * ttsc owns a small set of cross-cutting flags (`--singleThreaded`,
5
+ * `--checkers`, …) that the lint sidecar accepts but a typical third-party
6
+ * transform host (built with bare `flag.FlagSet`) would reject with exit 2.
7
+ * Capabilities let the plugin author tell ttsc up front which of those flags
8
+ * the sidecar understands, instead of ttsc hard-checking the plugin name and
9
+ * silently dropping the flag for anything else.
10
+ *
11
+ * Every field is optional and defaults to `false`. Plugin authors opt in by
12
+ * setting only the capabilities their sidecar actually implements; ttsc
13
+ * keeps the conservative default for everything else.
14
+ */
15
+ export interface ITtscPluginCapabilities {
16
+ /**
17
+ * Whether the sidecar accepts `--singleThreaded` and `--checkers` on its
18
+ * command line. The lint sidecar parses both flags via
19
+ * `parseSubcommandFlags` and threads them into `loadProgram` (parse phase)
20
+ * and `engine.SetSerial` (rule walk); other check-stage hosts may not.
21
+ *
22
+ * When `false` (the default), ttsc strips both flags from the sidecar's
23
+ * arg list — the conservative behavior that ad3443a restored after
24
+ * `#113` over-forwarded them to typia/nestia hosts.
25
+ *
26
+ * @default false
27
+ */
28
+ threadingArgs?: boolean;
29
+ }
@@ -3,6 +3,7 @@ export * from "./ITtscCompilerDiagnostic";
3
3
  export * from "./ITtscCompilerResult";
4
4
  export * from "./ITtscCompilerTransformation";
5
5
  export * from "./ITtscPlugin";
6
+ export * from "./ITtscPluginCapabilities";
6
7
  export * from "./ITtscPluginContributor";
7
8
  export * from "./ITtscPluginFactoryContext";
8
9
  export * from "./ITtscProjectPluginConfig";
@@ -1,3 +1,4 @@
1
+ import type { ITtscPluginCapabilities } from "../ITtscPluginCapabilities";
1
2
  import type { ITtscPluginContributor } from "../ITtscPluginContributor";
2
3
  import type { ITtscProjectPluginConfig } from "../ITtscProjectPluginConfig";
3
4
  import type { TtscPluginStage } from "../TtscPluginStage";
@@ -6,6 +7,8 @@ import type { TtscPluginStage } from "../TtscPluginStage";
6
7
  export interface ITtscLoadedNativePlugin {
7
8
  /** Executable produced by the lazy Go source build cache. */
8
9
  binary: string;
10
+ /** Capability flags declared by the descriptor (see `ITtscPluginCapabilities`). */
11
+ capabilities?: ITtscPluginCapabilities;
9
12
  /** Original tsconfig plugin entry passed unchanged to the sidecar. */
10
13
  config: ITtscProjectPluginConfig;
11
14
  /** Contributor Go sources statically linked into the binary, if any. */
@@ -14,6 +17,8 @@ export interface ITtscLoadedNativePlugin {
14
17
  kind: "executable" | "linked";
15
18
  /** Optional human label used in diagnostics and native manifests. */
16
19
  name?: string;
20
+ /** Whether a check-stage plugin already emits TypeScript diagnostics. */
21
+ reportsTypeScriptDiagnostics?: boolean;
17
22
  /** Go source directory selected by the plugin descriptor. */
18
23
  source: string;
19
24
  /** Pipeline stage where the sidecar participates. */
@@ -22,6 +22,25 @@ export interface TtscCommonOptions {
22
22
  cacheDir?: string;
23
23
  /** Normalize compiler output so diagnostics can be parsed structurally. */
24
24
  structuredDiagnostics?: boolean;
25
+ /**
26
+ * Run TypeScript-Go single-threaded — one checker, serial parse/check/emit.
27
+ * Mirrors `tsgo --singleThreaded`. Useful for deterministic debugging and CI
28
+ * repro.
29
+ */
30
+ singleThreaded?: boolean;
31
+ /**
32
+ * Type-checker pool size, mirroring `tsgo --checkers`. `undefined` leaves
33
+ * TypeScript-Go's default; ignored when `singleThreaded` is set.
34
+ */
35
+ checkers?: number;
36
+ /**
37
+ * CLI tokens ttsc did not recognize as its own, forwarded verbatim to the
38
+ * underlying `tsgo` invocation. This is how a tsgo flag ttsc has no first-
39
+ * class option for (`--strict`, `--target es2020`, `--listFiles`, …) still
40
+ * reaches the compiler: ttsc owns its own flags and lets tsgo — which has the
41
+ * complete, arity-aware option parser — handle the rest.
42
+ */
43
+ passthrough?: readonly string[];
25
44
  /**
26
45
  * Override project plugin loading for this invocation.
27
46
  *
@@ -0,0 +1,30 @@
1
+ // Code generated by packages/ttsc/scripts/gen-flags.mts. DO NOT EDIT.
2
+ //
3
+ // Source of truth: packages/ttsc/src/flags/schema.ts.
4
+ // Regenerate with: pnpm format
5
+ // Verify in CI with: node packages/ttsc/scripts/check-flags.cjs
6
+
7
+ package utility
8
+
9
+ // HostFlagAllowList is the allow-list of CLI flags this Go layer accepts. The map's
10
+ // value is true when the flag carries a separate value token (--flag VALUE
11
+ // or --flag=VALUE) and false when the flag is boolean (--flag).
12
+ //
13
+ // Generated from packages/ttsc/src/flags/schema.ts. Edit the schema, not
14
+ // this file.
15
+ var HostFlagAllowList = map[string]bool{
16
+ "checkers": true,
17
+ "cwd": true,
18
+ "emit": false,
19
+ "manifest": true,
20
+ "noEmit": false,
21
+ "outDir": true,
22
+ "p": true,
23
+ "plugins-json": true,
24
+ "project": true,
25
+ "quiet": false,
26
+ "singleThreaded": false,
27
+ "tsconfig": true,
28
+ "tsgo-args": true,
29
+ "verbose": false,
30
+ }
package/utility/host.go CHANGED
@@ -17,14 +17,17 @@ import (
17
17
  // hostOptions is the parsed form of the flags accepted by all three
18
18
  // subcommands (check, build, transform).
19
19
  type hostOptions struct {
20
- cwd string
21
- emit bool
22
- noEmit bool
23
- outDir string
24
- pluginsJSON string
25
- quiet bool
26
- tsconfig string
27
- verbose bool
20
+ cwd string
21
+ emit bool
22
+ noEmit bool
23
+ outDir string
24
+ pluginsJSON string
25
+ quiet bool
26
+ tsconfig string
27
+ verbose bool
28
+ singleThreaded bool
29
+ checkers int
30
+ tsgoArgs []string
28
31
  }
29
32
 
30
33
  // transformResult is the JSON envelope written to stdout by RunTransform.
@@ -134,9 +137,19 @@ func parseHostOptions(command string, args []string) (hostOptions, bool) {
134
137
  quiet := fs.Bool("quiet", true, "suppress summary")
135
138
  tsconfig := fs.String("tsconfig", "tsconfig.json", "project tsconfig")
136
139
  verbose := fs.Bool("verbose", false, "print summary")
140
+ singleThreaded := fs.Bool("singleThreaded", false, "run TypeScript-Go single-threaded")
141
+ checkers := fs.Int("checkers", 0, "type-checker pool size (0 = TypeScript-Go default)")
142
+ tsgoArgsRaw := fs.String("tsgo-args", "", "JSON array of forwarded tsgo CLI flags")
137
143
  if err := fs.Parse(filterHostArgs(args)); err != nil {
138
144
  return hostOptions{}, false
139
145
  }
146
+ var tsgoArgs []string
147
+ if *tsgoArgsRaw != "" {
148
+ if err := json.Unmarshal([]byte(*tsgoArgsRaw), &tsgoArgs); err != nil {
149
+ fmt.Fprintf(os.Stderr, "ttsc utility: invalid --tsgo-args: %v\n", err)
150
+ return hostOptions{}, false
151
+ }
152
+ }
140
153
  if *emit && *noEmit {
141
154
  fmt.Fprintln(os.Stderr, "ttsc utility: --emit and --noEmit are mutually exclusive")
142
155
  return hostOptions{}, false
@@ -159,14 +172,17 @@ func parseHostOptions(command string, args []string) (hostOptions, bool) {
159
172
  resolvedCwd = abs
160
173
  }
161
174
  return hostOptions{
162
- cwd: filepath.Clean(resolvedCwd),
163
- emit: *emit,
164
- noEmit: *noEmit,
165
- outDir: *outDir,
166
- pluginsJSON: *pluginsJSON,
167
- quiet: *quiet,
168
- tsconfig: *tsconfig,
169
- verbose: *verbose,
175
+ cwd: filepath.Clean(resolvedCwd),
176
+ emit: *emit,
177
+ noEmit: *noEmit,
178
+ outDir: *outDir,
179
+ pluginsJSON: *pluginsJSON,
180
+ quiet: *quiet,
181
+ tsconfig: *tsconfig,
182
+ verbose: *verbose,
183
+ singleThreaded: *singleThreaded,
184
+ checkers: *checkers,
185
+ tsgoArgs: tsgoArgs,
170
186
  }, true
171
187
  }
172
188
 
@@ -175,20 +191,11 @@ func parseHostOptions(command string, args []string) (hostOptions, bool) {
175
191
  // cause flag.FlagSet to error. Flags not in the known set are consumed together
176
192
  // with their value argument when they clearly take one (no inline "=" and the
177
193
  // next token does not start with "-").
194
+ //
195
+ // The allow-list itself is generated from packages/ttsc/src/flags/schema.ts
196
+ // (see flags_gen.go); editing it means editing the schema and re-running
197
+ // `pnpm format`, not patching this file.
178
198
  func filterHostArgs(args []string) []string {
179
- // known maps flag name → whether it takes a separate value token.
180
- // true = the flag accepts a value (--flag value or --flag=value).
181
- // false = the flag is boolean (no following value token).
182
- known := map[string]bool{
183
- "cwd": true,
184
- "emit": false,
185
- "noEmit": false,
186
- "outDir": true,
187
- "plugins-json": true,
188
- "quiet": false,
189
- "tsconfig": true,
190
- "verbose": false,
191
- }
192
199
  filtered := make([]string, 0, len(args))
193
200
  for i := 0; i < len(args); i++ {
194
201
  current := args[i]
@@ -200,7 +207,7 @@ func filterHostArgs(args []string) []string {
200
207
  continue
201
208
  }
202
209
  name, hasInlineValue := flagName(current)
203
- takesValue, ok := known[name]
210
+ takesValue, ok := HostFlagAllowList[name]
204
211
  if ok {
205
212
  filtered = append(filtered, current)
206
213
  if takesValue && !hasInlineValue && i+1 < len(args) {
@@ -238,9 +245,12 @@ func loadUtilityProgram(opts hostOptions) (*driver.Program, []driver.PluginEntry
238
245
  defer restoreEnv()
239
246
 
240
247
  prog, diags, err := driver.LoadProgram(opts.cwd, opts.tsconfig, driver.LoadProgramOptions{
241
- ForceEmit: opts.emit,
242
- ForceNoEmit: opts.noEmit,
243
- OutDir: opts.outDir,
248
+ ForceEmit: opts.emit,
249
+ ForceNoEmit: opts.noEmit,
250
+ OutDir: opts.outDir,
251
+ SingleThreaded: opts.singleThreaded,
252
+ Checkers: opts.checkers,
253
+ TsgoArgs: opts.tsgoArgs,
244
254
  })
245
255
  if err != nil {
246
256
  fmt.Fprintf(os.Stderr, "ttsc utility: %v\n", err)