@ttsc/lint 0.28.5 → 0.28.6

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.
@@ -220,12 +220,13 @@ func (s *residentCheckState) run(
220
220
  opts.cwd,
221
221
  opts.tsconfig,
222
222
  loadProgramOptions{
223
- forceNoEmit: true,
224
- needsRuleChecker: engine.NeedsTypeChecker(),
225
- singleThreaded: opts.singleThreaded,
226
- checkers: opts.checkers,
227
- tsgoArgs: opts.tsgoArgs,
228
- projectIdentity: opts.projectIdentity,
223
+ forceNoEmit: true,
224
+ semanticConfigPath: opts.semanticConfigPath,
225
+ needsRuleChecker: engine.NeedsTypeChecker(),
226
+ singleThreaded: opts.singleThreaded,
227
+ checkers: opts.checkers,
228
+ tsgoArgs: opts.tsgoArgs,
229
+ projectIdentity: opts.projectIdentity,
229
230
  },
230
231
  )
231
232
  if err != nil {
@@ -74,6 +74,7 @@ func RunTransform(args []string) int {
74
74
 
75
75
  // RunTransformWithIO runs transform with invocation-owned output streams.
76
76
  func RunTransformWithIO(args []string, stdout, stderr io.Writer) int {
77
+ semanticConfigPath := os.Getenv(semanticConfigPathEnv)
77
78
  fs := flag.NewFlagSet("transform", flag.ContinueOnError)
78
79
  fs.SetOutput(stderr)
79
80
  file := fs.String("file", "", "absolute or cwd-relative path of the .ts file to transform")
@@ -122,12 +123,13 @@ func RunTransformWithIO(args []string, stdout, stderr io.Writer) int {
122
123
  engine.SetSerial(*singleThreaded)
123
124
 
124
125
  prog, parseDiags, err := loadProgram(resolvedCwd, *tsconfig, loadProgramOptions{
125
- forceEmit: true,
126
- needsRuleChecker: engine.NeedsTypeChecker(),
127
- singleThreaded: *singleThreaded,
128
- checkers: *checkers,
129
- tsgoArgs: tsgoArgs,
130
- projectIdentity: projectIdentity,
126
+ forceEmit: true,
127
+ semanticConfigPath: semanticConfigPath,
128
+ needsRuleChecker: engine.NeedsTypeChecker(),
129
+ singleThreaded: *singleThreaded,
130
+ checkers: *checkers,
131
+ tsgoArgs: tsgoArgs,
132
+ projectIdentity: projectIdentity,
131
133
  })
132
134
  if err != nil {
133
135
  fmt.Fprintf(stderr, "@ttsc/lint: %v\n", err)
@@ -201,21 +203,22 @@ func RunTransformWithIO(args []string, stdout, stderr io.Writer) int {
201
203
  }
202
204
 
203
205
  type subcommandOpts struct {
204
- cwd string
205
- tsconfig string
206
- pluginsJSON string
207
- emit bool
208
- noEmit bool
209
- quiet bool
210
- verbose bool
211
- diagnostics bool
212
- outDir string
213
- singleThreaded bool
214
- checkers int
215
- tsgoArgs []string
216
- projectIdentity publicrule.ProjectIdentity
217
- stdout io.Writer
218
- stderr io.Writer
206
+ cwd string
207
+ tsconfig string
208
+ pluginsJSON string
209
+ emit bool
210
+ noEmit bool
211
+ quiet bool
212
+ verbose bool
213
+ diagnostics bool
214
+ outDir string
215
+ semanticConfigPath string
216
+ singleThreaded bool
217
+ checkers int
218
+ tsgoArgs []string
219
+ projectIdentity publicrule.ProjectIdentity
220
+ stdout io.Writer
221
+ stderr io.Writer
219
222
  }
220
223
 
221
224
  // parseSubcommandFlags parses the shared flag set used by the `check`,
@@ -226,6 +229,7 @@ func parseSubcommandFlags(name string, args []string) (*subcommandOpts, error) {
226
229
  }
227
230
 
228
231
  func parseSubcommandFlagsWithIO(name string, args []string, stdout, stderr io.Writer) (*subcommandOpts, error) {
232
+ semanticConfigPath := os.Getenv(semanticConfigPathEnv)
229
233
  if stdout == nil {
230
234
  stdout = io.Discard
231
235
  }
@@ -267,21 +271,22 @@ func parseSubcommandFlagsWithIO(name string, args []string, stdout, stderr io.Wr
267
271
  return nil, err
268
272
  }
269
273
  return &subcommandOpts{
270
- cwd: resolvedCwd,
271
- tsconfig: *tsconfig,
272
- pluginsJSON: *pluginsJSON,
273
- emit: *emit,
274
- noEmit: *noEmit,
275
- quiet: *quiet,
276
- verbose: *verbose,
277
- diagnostics: *diagnostics || *extendedDiagnostics,
278
- outDir: *outDir,
279
- singleThreaded: *singleThreaded,
280
- checkers: *checkers,
281
- tsgoArgs: tsgoArgs,
282
- projectIdentity: projectIdentity,
283
- stdout: stdout,
284
- stderr: stderr,
274
+ cwd: resolvedCwd,
275
+ tsconfig: *tsconfig,
276
+ pluginsJSON: *pluginsJSON,
277
+ emit: *emit,
278
+ noEmit: *noEmit,
279
+ quiet: *quiet,
280
+ verbose: *verbose,
281
+ diagnostics: *diagnostics || *extendedDiagnostics,
282
+ outDir: *outDir,
283
+ semanticConfigPath: semanticConfigPath,
284
+ singleThreaded: *singleThreaded,
285
+ checkers: *checkers,
286
+ tsgoArgs: tsgoArgs,
287
+ projectIdentity: projectIdentity,
288
+ stdout: stdout,
289
+ stderr: stderr,
285
290
  }, nil
286
291
  }
287
292
 
@@ -332,14 +337,15 @@ func runProject(opts *subcommandOpts) int {
332
337
  engine.SetSerial(opts.singleThreaded)
333
338
 
334
339
  prog, parseDiags, err := loadProgram(opts.cwd, opts.tsconfig, loadProgramOptions{
335
- forceEmit: opts.emit,
336
- forceNoEmit: opts.noEmit,
337
- outDir: opts.outDir,
338
- needsRuleChecker: engine.NeedsTypeChecker(),
339
- singleThreaded: opts.singleThreaded,
340
- checkers: opts.checkers,
341
- tsgoArgs: opts.tsgoArgs,
342
- projectIdentity: opts.projectIdentity,
340
+ forceEmit: opts.emit,
341
+ forceNoEmit: opts.noEmit,
342
+ outDir: opts.outDir,
343
+ semanticConfigPath: opts.semanticConfigPath,
344
+ needsRuleChecker: engine.NeedsTypeChecker(),
345
+ singleThreaded: opts.singleThreaded,
346
+ checkers: opts.checkers,
347
+ tsgoArgs: opts.tsgoArgs,
348
+ projectIdentity: opts.projectIdentity,
343
349
  })
344
350
  if err != nil {
345
351
  fmt.Fprintf(opts.stderr, "@ttsc/lint: %v\n", err)
package/linthost/fix.go CHANGED
@@ -143,13 +143,14 @@ func runFix(opts *subcommandOpts) int {
143
143
  // NoEmit forced on. Returns (nil, 2) when loading or config parsing fails.
144
144
  func loadFixProgram(opts *subcommandOpts, needsRuleChecker bool) (*program, int) {
145
145
  prog, parseDiags, err := loadProgram(opts.cwd, opts.tsconfig, loadProgramOptions{
146
- forceNoEmit: true,
147
- outDir: opts.outDir,
148
- needsRuleChecker: needsRuleChecker,
149
- singleThreaded: opts.singleThreaded,
150
- checkers: opts.checkers,
151
- tsgoArgs: opts.tsgoArgs,
152
- projectIdentity: opts.projectIdentity,
146
+ forceNoEmit: true,
147
+ outDir: opts.outDir,
148
+ semanticConfigPath: opts.semanticConfigPath,
149
+ needsRuleChecker: needsRuleChecker,
150
+ singleThreaded: opts.singleThreaded,
151
+ checkers: opts.checkers,
152
+ tsgoArgs: opts.tsgoArgs,
153
+ projectIdentity: opts.projectIdentity,
153
154
  })
154
155
  if err != nil {
155
156
  fmt.Fprintf(os.Stderr, "@ttsc/lint: %v\n", err)
package/linthost/host.go CHANGED
@@ -33,6 +33,11 @@ import (
33
33
 
34
34
  var programLifecycleSequence atomic.Uint64
35
35
 
36
+ // semanticConfigPathEnv mirrors `driver.SemanticConfigPathEnv`: the internal
37
+ // channel that identifies the user-authored config behind a generated wrapper.
38
+ // This module cannot import the ttsc driver; see the package boundary above.
39
+ const semanticConfigPathEnv = "TTSC_SEMANTIC_CONFIG_PATH"
40
+
36
41
  // program bundles the tsgo Program with the parsed config and the standalone
37
42
  // checker used only by type-aware lint rules.
38
43
  type program struct {
@@ -54,9 +59,10 @@ type program struct {
54
59
  }
55
60
 
56
61
  type loadProgramOptions struct {
57
- forceEmit bool
58
- forceNoEmit bool
59
- outDir string
62
+ forceEmit bool
63
+ forceNoEmit bool
64
+ outDir string
65
+ semanticConfigPath string
60
66
  // needsRuleChecker asks loadProgram to create the standalone checker that
61
67
  // type-aware lint rules receive through Context.Checker.
62
68
  needsRuleChecker bool
@@ -118,6 +124,9 @@ func loadProgram(cwd, tsconfigPath string, options loadProgramOptions) (*program
118
124
  if len(parsed.Errors) > 0 {
119
125
  return nil, parsed.Errors, nil
120
126
  }
127
+ if err := applySemanticConfigPath(parsed, options.semanticConfigPath); err != nil {
128
+ return nil, nil, err
129
+ }
121
130
  if options.forceNoEmit {
122
131
  forceNoEmit(parsed)
123
132
  }
@@ -158,6 +167,18 @@ func loadProgram(cwd, tsconfigPath string, options loadProgramOptions) (*program
158
167
  }, nil, nil
159
168
  }
160
169
 
170
+ func applySemanticConfigPath(parsed *tsoptions.ParsedCommandLine, semanticConfigPath string) error {
171
+ configured := strings.TrimSpace(semanticConfigPath)
172
+ if configured == "" {
173
+ return nil
174
+ }
175
+ if !filepath.IsAbs(configured) {
176
+ return fmt.Errorf("linthost: semantic config path must be absolute: %s", configured)
177
+ }
178
+ parsed.ParsedConfig.CompilerOptions.ConfigFilePath = shimtspath.ResolvePath(configured)
179
+ return nil
180
+ }
181
+
161
182
  func normalizeProjectIdentity(
162
183
  identity publicrule.ProjectIdentity,
163
184
  cwd string,
package/linthost/lsp.go CHANGED
@@ -145,10 +145,11 @@ type lspCommandOptions struct {
145
145
  pluginsJSON string
146
146
  // rangeJSON carries the editor selection used to limit quickfix.ttsc
147
147
  // actions. Source fix-all and format actions remain document-wide.
148
- rangeJSON string
149
- tsconfig string
150
- uri string
151
- projectIdentity publicrule.ProjectIdentity
148
+ rangeJSON string
149
+ semanticConfigPath string
150
+ tsconfig string
151
+ uri string
152
+ projectIdentity publicrule.ProjectIdentity
152
153
  }
153
154
 
154
155
  // lspCommandIDs is the workspace/executeCommand ids owned by @ttsc/lint, shared
@@ -424,16 +425,17 @@ func parseLSPCommandOptions(name string, args []string) (*lspCommandOptions, boo
424
425
  return nil, false
425
426
  }
426
427
  return &lspCommandOptions{
427
- argumentsJSON: *argumentsJSON,
428
- command: *command,
429
- contextJSON: *contextJSON,
430
- contentStdin: *contentStdin,
431
- cwd: resolvedCwd,
432
- pluginsJSON: *pluginsJSON,
433
- rangeJSON: *rangeJSON,
434
- tsconfig: *tsconfig,
435
- uri: *uri,
436
- projectIdentity: projectIdentity,
428
+ argumentsJSON: *argumentsJSON,
429
+ command: *command,
430
+ contextJSON: *contextJSON,
431
+ contentStdin: *contentStdin,
432
+ cwd: resolvedCwd,
433
+ pluginsJSON: *pluginsJSON,
434
+ rangeJSON: *rangeJSON,
435
+ semanticConfigPath: os.Getenv(semanticConfigPathEnv),
436
+ tsconfig: *tsconfig,
437
+ uri: *uri,
438
+ projectIdentity: projectIdentity,
437
439
  }, true
438
440
  }
439
441
 
package/linthost/serve.go CHANGED
@@ -80,9 +80,10 @@ func (c *residentProgramCache) acquire(
80
80
  }
81
81
  }
82
82
  prog, diags, err := loadProgram(opts.cwd, opts.tsconfig, loadProgramOptions{
83
- forceNoEmit: true,
84
- needsRuleChecker: needsChecker,
85
- projectIdentity: opts.projectIdentity,
83
+ forceNoEmit: true,
84
+ needsRuleChecker: needsChecker,
85
+ projectIdentity: opts.projectIdentity,
86
+ semanticConfigPath: opts.semanticConfigPath,
86
87
  })
87
88
  if err != nil {
88
89
  return nil, nil, noopClose, err
@@ -172,9 +173,10 @@ func acquireProgram(
172
173
  return residentPrograms.acquire(opts, needsChecker)
173
174
  }
174
175
  prog, diags, err := loadProgram(opts.cwd, opts.tsconfig, loadProgramOptions{
175
- forceNoEmit: true,
176
- needsRuleChecker: needsChecker,
177
- projectIdentity: opts.projectIdentity,
176
+ forceNoEmit: true,
177
+ needsRuleChecker: needsChecker,
178
+ projectIdentity: opts.projectIdentity,
179
+ semanticConfigPath: opts.semanticConfigPath,
178
180
  })
179
181
  if prog == nil {
180
182
  return prog, diags, noopClose, err
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttsc/lint",
3
- "version": "0.28.5",
3
+ "version": "0.28.6",
4
4
  "description": "Reference ttsc plugin: ESLint-style lint rules over the TypeScript-Go Program used by the type-check pass.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "@types/node": "^25.3.0",
38
38
  "rimraf": "^6.1.2",
39
39
  "typescript": "^7.0.2",
40
- "ttsc": "0.28.5"
40
+ "ttsc": "0.28.6"
41
41
  },
42
42
  "repository": {
43
43
  "type": "git",