Skip to Content

Driver API

github.com/samchon/ttsc/packages/ttsc/driver is the Go façade plugin authors should call instead of building a tsgo Program themselves. Every shipped third-party-shaped consumer in this repo — every command under packages/ttsc/cmd/, packages/lint/linthost/host.go, packages/wasm/host/api.go, and the tests/projects/go-source-plugin* fixtures — uses it.

This page is the curated, plugin-relevant surface. For the raw shim path (custom checker pool, in-memory-only Program, no tsconfig.json), see AST & Checker → If you cannot use the driver.

Program lifecycle

import "github.com/samchon/ttsc/packages/ttsc/driver" prog, parseDiags, err := driver.LoadProgram(cwd, "tsconfig.json", driver.LoadProgramOptions{ ForceEmit: false, ForceNoEmit: false, OutDir: "", SourcePreamble: "", }) if err != nil { /* parse-time failure */ } if len(parseDiags) > 0 { /* tsconfig errors */ } defer prog.Close() // releases the leased Checker back to the pool for _, file := range prog.SourceFiles() { /* walk */ } diags := prog.Diagnostics() // pre-deduped, pre-filtered checker := prog.Checker // type-aware queries

LoadProgram:

  • parses tsconfig.json (relative paths resolve against cwd).
  • applies LoadProgramOptions overrides — ForceEmit / ForceNoEmit flip the emit decision; OutDir overrides the parsed outDir; SourcePreamble overlays a JSDoc preamble before parsing (the seam @ttsc/banner uses).
  • builds the tsgo Program through shim/compiler.NewProgram and leases a *shimchecker.Checker from the pool.
  • returns a *driver.Program carrying the parsed config, the host, the FS, and the lease release function.

Program.SourceFiles() filters declaration files for you. Program.Diagnostics() runs GetDiagnosticsOfAnyProgram + SortAndDeduplicateDiagnostics and drops the unused-overload-signature noise that tsgo emits internally. Always defer prog.Close() — without it the checker pool fills up and subsequent loads stall.

Emit

// Build-stage: tsgo owns JS, d.ts, and source-map printing. emitted, emitDiags, err := prog.EmitAllRaw(nil) // Transform-stage: render per-file source through the printer to drive // downstream callers (bundlers, in-memory transformers). text := shimprinter.EmitSourceFile(printer, file)
FunctionUse it when…
EmitAllRawYou want tsgo’s full output (JS, d.ts, source maps) with default write-file handling.
EmitAll(rs, fn)You want to layer a *RewriteSet over emit and intercept each write through fn.
EmitFile(...)You only need one file’s emit (rarely used outside the utility host).
DefaultWriteFileThe default WriteFileFunc — writes through the program’s FS. Pass to EmitAll when you don’t need interception.

For the transform subcommand, the host treats typescript[fileName] as opaque text — see Plugin protocol → Transform. Run a printer before placing AST-mutated source in the map.

Diagnostics

// Three-line canonical lint-style flow. var diags []driver.Diagnostic diags = append(diags, driver.NewLintDiagnostic( file, start, end, /*code*/ 9001, driver.SeverityError, "[my-rule] explanation here", )) driver.WritePrettyDiagnostics(os.Stderr, diags, cwd) if driver.CountErrors(diags) > 0 { os.Exit(1) }
SymbolNotes
NewLintDiagnostic(file, pos, end, code, sev, msg)Wraps the offset pair into a Diagnostic with the file’s path.
DiagnosticThe struct the host’s renderer accepts.
Severity + SeverityError / SeverityWarningConstants the host’s exit-code logic understands. SeverityError fails the build; SeverityWarning prints with warning coloring but keeps the exit code at zero.
CountErrors(diags []Diagnostic) intReturns the number of diagnostics that should fail the build (every diagnostic except explicit warnings).
WritePrettyDiagnostics(w io.Writer, diags, cwd)Renders to w using the same colorful format ttsc itself uses. No return value.

Rewrites

rs := driver.NewRewriteSet() rs.Add(driver.Rewrite{ File: file, // *ast.SourceFile from prog.SourceFiles() RootName: "console", Method: "log", Replacement: "/* console.log */", }) prog.EmitAll(rs, driver.DefaultWriteFile)

RewriteSet is the path the engine uses to splice replacements over plugin-owned call expressions in the emitted JavaScript text. Pair with EmitAll; pass DefaultWriteFile unless you need to intercept. The RewriteSentinel constant (/* @ttsc-rewritten */) is the idempotency marker inserted at the top of a patched file so re-emitting an already-rewritten file is a no-op.

Source preambles

text = driver.ApplySourcePreamble(text, "/* @license MIT */")

ApplySourcePreamble keeps a BOM or hashbang at the physical start of the file while inserting generated text after it. @ttsc/banner computes the preamble through driver.SourcePreamblePlugin; the generic host applies it when source text or declaration output needs the banner.

Linked Plugins

Non-main transform packages register with the driver instead of owning a process:

func init() { driver.RegisterPlugin(plugin{}) } type plugin struct{} func (plugin) ApplyProgram(prog *driver.Program, ctx driver.PluginContext) error { // mutate prog.SourceFiles() return nil }

Implement SourcePreamble(ctx) when the plugin needs text before parsing, and ApplyProgram(prog, ctx) when it mutates the loaded Program. ctx.Entry.Config is the original compilerOptions.plugins[] object for this linked entry.

Hosting ttscserver

These symbols are for embedders of ttscserver, not for plugin authors. Skip this section unless you are building a ttsc-aware editor extension.

ttscserver is a process wrapper around the project-selected tsgo --lsp --stdio binary. Resolve @typescript/native-preview in the user project, pass its absolute executable path as TsgoBinary, and keep plugin diagnostics/code actions in your PluginSource.

err := driver.RunLSPServer(context.Background(), driver.LSPServerOptions{ In: os.Stdin, Out: os.Stdout, Err: os.Stderr, Cwd: projectRoot, TsgoBinary: tsgoBinary, Source: source, // your driver.PluginSource impl })
SymbolPurpose
PluginSource interface, NullPluginSourceThe seam downstream pipelines implement to feed ttsc plugins into the LSP.
RunLSPServer, LSPServerOptions, ErrCommandNotHandledHost-side entry points.
LSPDocumentVersion, LSPDiagnostic, LSPCodeAction, LSPRange, LSPWorkspaceEditWire types in the LSP envelope.

DenyNpmInstall remains for older in-process embedders, but the shipped ttscserver no longer embeds tsgo and cannot override tsgo’s internal ATA callback.

Lower-level helpers

Use when LoadProgram’s defaults don’t fit.

SymbolNotes
DefaultFS()The OS-backed VFS wrapped with the bundled library files.
DefaultHost(cwd, fs)A tsgo compiler host pre-wired with the FS and the bundled lib.*.d.ts paths.
ParseTSConfig(path, host)Parses a tsconfig.json without building a Program.
CreateProgramFromConfig(...)Builds a Program from a parsed config without going through LoadProgram’s convenience overrides.

Stability

The driver surface is the closest thing ttsc has to a stable plugin SDK. Symbols listed here have Go doc-comments and are exercised by the in-repo test suite on every CI run. Lower-level shim symbols may move between releases; the driver insulates plugin authors from that churn. When you must reach below the driver, see AST & Checker for the supported escape hatches.

Last updated on