Providers and Toolchains¶
The contract a rule outside this ruleset writes against: the providers the
rules return, and the toolchains they resolve. Four providers load from
@rules_typescript//ts:defs.bzl; the toolchain contract loads from
@rules_typescript//ts/toolchain:defs.bzl.
load(
"@rules_typescript//ts:defs.bzl",
"BundlerInfo",
"DevServerInfo",
"TsInfo",
"TsTestRunnerInfo",
)
| Provider | Returned by |
|---|---|
TsInfo |
ts_compile, ts_codegen, ts_binary, the @npm package targets and a member's hub view |
TsTestRunnerInfo |
//ts/runners:vitest, //ts/runners:node_test, a runner of your own |
BundlerInfo |
any rule that brings its own bundler; the ruleset ships none |
DevServerInfo |
//vite:dev_server, a server of your own |
TsInfo¶
A dep provides one thing: what a consumer's program and runtime need. TsInfo
carries the files a consumer stages, its npm closure and the store files it
reaches, and deps on ts_compile and ts_test accepts any target returning
it.
A direct field carries only what the target itself produces. A rule that
forwards a dep's files leaves the direct field empty and puts the closure in the
transitive one; ts_compile does that for its deps' data files, which reach
transitive_data and never data. A consumer that wants everything reachable
reads the transitive field. Declarations have no transitive field: the
closure's are the owners records', one per target, so a consumer reads them
all or leaves a target's out.
| Field | Type | Description |
|---|---|---|
js |
depset of File |
The .js files this target produces: compiled output, plus any JavaScript src staged as-is |
js_maps |
depset of File |
The .js.map beside them |
declarations |
depset of File |
The declarations this target produces, plus the ambient ones it passes through from srcs. Emitted when a consumer's compile reads them or --output_groups=declarations asks, never as a default output (Which Tool Emits the Declarations). A global one is in scope in a consumer only when the consumer's tsconfig types names it |
data |
depset of File |
Non-program srcs and explicit ts_compile.data assets. Assets use package-relative paths; JSON follows the importing module's runtime layout, with original paths for an all-source closure |
manifest |
File or None |
The package-root npm publication manifest: <name>.package.json with entry points projected when emission is enabled or runtime placement changes; the original File for source mode with an unchanged layout. A dependent's compiler overlay and a member's store tree use it. Runtime package scopes use the package_scopes projection; explicit JSON modules in srcs retain authored contents, subject to scope compatibility (Compiler inputs and emitted layout) |
sources |
depset of File |
The original source Files the compiler reads as its own: .ts, .tsx, JavaScript and declarations. A ts_test under the same tsconfig checks them as its own program's inputs; runtime placement uses the recorded source/runtime pairs (The Test's Program) |
tsconfig |
File or None |
The tsconfig.json the program's options come from, the tsconfig attribute's file: the identity a ts_test joins a dep's sources by |
transitive_js |
depset of File |
Every .js from this target and its first-party deps |
transitive_js_maps |
depset of File |
Their .js.map |
transitive_data |
depset of File |
The data files of this target and its first-party deps: what a compiled module reaches beside itself at run time or in a bundle |
transitive_es_twins |
depset of (File, File) |
For a program tsgo emits, each .js of this target and its first-party deps paired with the ES module oxc emits from the same source; the vitest runner stages the second at the first's runfiles path (The Module Format) |
npm_packages |
depset of NpmPackageInfo |
The npm closure of this target's deps: what the ownership manifest names and a runner checks its packages against. A package itself arrives through its NpmPackageInfo |
npm_files |
depset of File |
The store files this target's program and runtime reach: the importer links of its direct npm deps and their @types twins, the member links its deps name, every store tree and edge link of their closures, the hoist links whose names the closure holds with the trees they enter (The Store), and its first-party deps' npm_files. An action stages this and nothing else of the store. A dep's emitted .d.ts imports the packages the dep declared and resolves them from the dep's own importer's links, which this depset carries into the consumer's action |
owners |
depset of struct(label, files, declarations, type_inputs, importers) with optional declaration_files, canonical_links, asset_files, runtime_files, runtime_scopes and npm_bindings |
One record per first-party target in the closure, this one first: label, the string a deps list writes; files, its owned files for the strict-deps check; declarations, its own alone; type_inputs, consumer compiler inputs including declarations and declared package scopes; importers, its npm importer directories. A consumer reads each record's type_inputs; joining its sources removes only its declarations from that set. Optional runtime_files contains immutable (source File, runtime File) pairs for runfiles File identity and package-scope projection. An npm package's declarations arrive through npm_files |
An emitted library publishes source/runtime pairs for shared module placement,
runfiles admission and package-scope projection. A source-mode consumer of a relocated dependency records its original source and staged TypeScript File in the same pairs; sources and compiler inputs keep their original identities. A custom producer supplies runtime_files as a
tuple of pairs constructed from its actual source and output Files. An empty
tuple states that the owner has no runtime mappings. These mappings do not
establish which imports survive emission or whether relative imports resolve.
Optional declaration_files is a tuple of exact (source File, declaration File) pairs allocated by the producer. Compiler consumers use the source origin to overlay the canonical declaration at the path the original import resolves to. Runtime consumers use runtime_files to place canonical dependency links when an emitted program spans source roots. See Shared Source Layout. Older records may omit declaration_files; their declarations retain the existing published-path overlay behavior.
Optional canonical_links records exact (link File, canonical File) pairs the producer creates for dependency placement or unchanged scope symlinks. A workspace member's npm store may copy metadata-only scope aliases backed by those identities and scope records. It rejects selected module and declaration aliases, including scopes used as JSON modules: copying their bytes would lose the canonical dependency's package scope and npm importer. Use a separately published npm dependency or include its sources in the member. Links outside the store's selected files do not restrict publication; older records may omit this field.
Optional asset_files records immutable (original File, logical coordinate, published File) triples for ordinary data whose bytes are unchanged. The coordinate is the producer's package-local view: //app packaging //assets:theme.css records app/assets/theme.css; external producers use an external/<repository>/ prefix. Consumers use only records whose published File is live in transitive_data. Multiple aliases of the same original and coordinate are valid; different originals at one coordinate fail. A consumer may link directly to that exact original File without selecting an alias by order. JSON modules and scope projections retain their separate module/scope records; a File explicitly declared as both type_inputs and data retains both roles. Older providers without asset records keep ordinary pass-through behavior; consumers do not infer origins.
Previous owner records may omit runtime_files. The consumer preserves their
original records and published runtime File identities at their exec paths,
without inventing pairs or adding an empty field. Declaration-only and
runtime-bearing custom producers need no edit to retain this contract.
Optional runtime_scopes is a tuple of immutable (original scope File,
runtime File) pairs, separate from module mappings. Consumers reuse a pair
only while its runtime File is in transitive_data. Older records may omit
the field: ordinary data passes through, but a new scope placement cannot
reuse an unproven occupant at its destination.
Optional npm_bindings is a tuple of immutable (package name, importer link File, store tree File) facts. Binaries and tests preserve these positive source-owned lookup contexts beside each admitted runtime module and its package scope. A test's selected ES twin or staged TypeScript retains the canonical module's source provenance. Consumers retain every declared binding; they do not infer an empty lookup context from emitted syntax. Older records may omit the field and retain their previous behavior without invented binding facts.
A dep reached through the store -- an @npm package, a member's link target
-- reaches the consumer's program and runtime there: ts_compile reads
npm_packages off it and none of its file fields, and stages its link and
store files, so an npm package's TsInfo stages nothing by path and its
owners is empty. A first-party dep's files are staged
at their exec paths, its declarations, js and data are what an import may
resolve to, and its owners record is what names it when an import does
(Deps have to be direct).
ts_binary with a bundler returns the bundle as the one member of both .js
fields, and the entry's data closure; without one it returns the entry's
TsInfo. ts_codegen with out_dir returns the directory as the one member
of js and declarations; nothing downstream compiles the tree, so what it
holds is already compiled output. An outs codegen returns its .js outs in
js and its .d.ts outs in declarations, so deps = [":worker_types"] is
legal and a consumer's tsconfig types can name the generated declaration.
A global .d.ts travels as a declaration output and nothing more: the consumer
names it in its own tsconfig types to bring its globals into scope. See
Which ambients a consumer gets.
TsTestRunnerInfo¶
| Field | Type | Description |
|---|---|---|
packages |
list of string |
The npm packages the runner needs in the test's npm closure, vitest for the vitest runner; ts_test fails at analysis naming the one no dep provides |
hook |
File |
The one module the runner loads into node before the tests: the node:test runner's resolver, the vitest runner's reads recorder |
es_modules |
bool |
True when the runner runs the program as ES modules whatever its tsconfig's module -- vitest -- so ts_test emits its srcs as such and stages a dep's ES twins; False for node:test, which runs the package's format (Runners) |
launch |
function |
The runner's half of one test's analysis: given the action-owning ctx and the struct ts_test builds from the compile, it returns the launcher config's mode and section, the env, and the runfiles the runner adds |
A runner is a target, the way a toolchain is: //ts/runners:vitest and
//ts/runners:node_test are the two shipped, and a rule in another ruleset
returning this provider is a third. See Runners.
The callback receives the private executable producer's real ctx. Its ctx.label owns the generated Files and actions; ctx.attr.public_name names the public test in the same package. The public test retains its Bazel test controls, coverage and editor metadata.
The test input's runtime_files contains live exact source/runtime pairs, with the test's own srcs taking precedence for those sources; asset_files contains live ordinary asset records. A runner may return optional replacements, an exact original-File-to-replacement-File dictionary. It must omit each replaced File from its ordinary inputs and bind that File's path through symlinks; final runfiles admission validates the replacement. Omitting this field preserves ordinary-file precedence.
BundlerInfo¶
| Field | Type | Description |
|---|---|---|
bundler_binary |
File or FilesToRunProvider |
Standalone executable, or executable target with its runfiles |
config_file |
File or None |
A static config passed as --config, in mode 1 only |
runtime_deps |
depset of File |
Files the bundler needs at run time |
use_generated_config |
bool |
True selects mode 2: ts_binary generates a vite.config.mjs and passes it with the entry, the output directory and the stylesheet. Default False |
The two invocation modes and the recipe for a bundler of your own are in Bundling.
NpmPackageInfo¶
NpmPackageInfo is not exported from @rules_typescript//ts:defs.bzl. It loads
from @rules_typescript//ts/private:providers.bzl, and everything under
ts/private/ is volatile. Every @npm package
target returns it, and so does a workspace member's hub view
npm_workspace_package; a node_modules target links store's tree under
package_name, ts_compile resolves a direct dep to that link, and store
names the snapshot's tree in the store.
| Field | Type | Description |
|---|---|---|
package_name |
string |
The npm name, react or @types/react; what the tree links the package as |
package_version |
string |
The version; 0.0.0 on a workspace member, which pnpm resolves by path |
peer_id |
string |
A filesystem-safe token naming the peer set this resolution was made against, empty for a package pnpm resolved only one way. Two snapshots can share name@version and differ only here |
package_dir |
File or None |
The package.json at the root of the extracted package. None on a workspace member, whose compile writes the manifest as built |
package_root |
string |
Exec-root-relative directory the files in all_files hang off: the store tree for an extracted tarball, the member's directory under bazel-bin for a workspace member |
all_files |
depset of File |
The package's files: the store tree alone for an extracted tarball; a member's outputs, the files its store tree copies, the manifest as built in place of the src |
transitive_deps |
depset of NpmPackageInfo |
Every npm package reachable from this one, the paired @types/* package included |
store |
NpmStoreInfo |
The snapshot's store tree and the links beside it: key, tree, links, transitive (npm/private/store.bzl) |
The package's exports, types and main are nowhere in it: tsgo and node
read the manifest in the tree, as they do over an install.
DevServerInfo¶
The default //oj:dev_server and optional //vite:dev_server return this
provider. ts_dev_server(server = ...) accepts other implementations too.
oj 0.2.16 uses a native binary, the Vite config dialect and native React Fast
Refresh. It ignores config fields root and cacheDir;
its root and cache come from the launcher. server.open is supported.
The table below describes the optional Vite implementation.
| Field | Type | Vite | Description |
|---|---|---|---|
server_binary |
File or None |
None |
The server executable, for a server that is a build artifact. None when it ships inside the npm tree |
server_in_tree |
string |
"vite/bin/vite.js" |
The executable's path under the importer's node_modules directory, for a server that ships as an npm package. Exactly one of the two is set |
argv |
list of string |
["dev", "--config", "{config}"] |
The command line after the executable. {config} expands to the generated config's path, {port} to the port attr, {root} to the directory served |
config_dialect |
string |
"vite" |
The config format the server is handed. Only "vite" is generated today; a server reading its own format declares its own dialect, and the generator has to learn it before that server can be selected |
runs_in_js_runtime |
bool |
True |
True when the executable is JavaScript and the toolchain Node runs it. A native server still gets the toolchain Node on PATH, for a plugin host that is a Node process |
ignored_config_fields |
list of string |
[] |
Dotted config paths the server does not honour. A target whose configuration reaches one fails at analysis time naming the field and the server |
native_react_refresh |
bool |
False |
True when the server applies React Fast Refresh itself. react_refresh = True then fails at analysis time |
runtime_deps |
depset of File |
empty | Everything the server needs in runfiles beyond the generated config and the importer's node_modules |
A server shipping as an npm package has no File to point at: its executable is
a path under the importer's node_modules directory, reached through the
package's link, which no artifact names. That is why server_in_tree exists
beside server_binary.
NodeModulesInfo¶
A node_modules target returns it; ts_codegen,
ts_binary, ts_dev_server and esbuild_bundle read it from their
node_modules attr, and take the target's DefaultInfo.files -- every link
and every store tree the links reach -- as inputs or runfiles; ts_compile
and ts_test follow parent up the chain and stage the links a direct dep
resolves to (The Chain), and from hoist, the
lockfile's hidden hoist carried unchanged down the chain, the links whose
names the closure holds (The Store).
| Field | Type | Description |
|---|---|---|
label |
Label |
The node_modules target's: the importer's package, and what a message names |
dir |
string |
The importer's node_modules directory as a bin-dir path, bazel-out/<cfg>/bin/<package>/node_modules: the parent of every link, which no artifact names |
links |
dict of string -> NpmLinkInfo |
Per package name, the declared symlink node_modules/<name> and the store it enters |
parent |
NodeModulesInfo or None |
The importer above's |
hoist |
NpmHoistInfo |
The lockfile's hidden hoist, the root importer's hoist target's, the same on every importer of its chain (NpmHoistInfo) |
NpmHoistInfo¶
A lockfile's hidden hoist, what its npm_store_hoist target
node_modules/.pnpm/node_modules returns
(The Store); the root importer names the target
in hoist, and every importer on the chain carries it as
NodeModulesInfo.hoist.
| Field | Type | Description |
|---|---|---|
links |
dict of string -> NpmLinkInfo |
Per hoisted name, the declared symlink node_modules/.pnpm/node_modules/<name> (a public-hoist-pattern match's at the root importer's node_modules/<name>) and the store it enters |
members |
dict of string -> File |
Per hoisted workspace member, the declared symlink alone, with no dependency on the member's tree; a consumer's closure holds the tree through the member's link target |
NpmLinkInfo¶
One link node_modules/<name> into a store tree: an entry of
NodeModulesInfo.links, and what a node_modules_member
target returns beside the member's TsInfo and NpmPackageInfo, so a
ts_compile or ts_test names the link target in deps where it named the
hub's view, and a ts_codegen names it there for a generator that resolves
the member.
| Field | Type | Description |
|---|---|---|
link |
File |
The declared symlink node_modules/<name> |
store |
NpmStoreInfo |
The store the link enters |
Toolchain Contract¶
@rules_typescript//ts/toolchain:defs.bzl exports seventeen names: six
toolchain type labels, five providers, and six accessors.
load(
"@rules_typescript//ts/toolchain:defs.bzl",
"JS_RUNTIME_TOOLCHAIN_TYPE",
"JS_TOOL_TOOLCHAIN_TYPE",
"LAUNCHER_TOOLCHAIN_TYPE",
"OXC_TOOLCHAIN_TYPE",
"TOOLS_TOOLCHAIN_TYPE",
"TSGO_TOOLCHAIN_TYPE",
"JsRuntimeInfo",
"LauncherInfo",
"OxcToolchainInfo",
"ToolsInfo",
"TsgoToolchainInfo",
"get_js_runtime",
"get_js_tool",
"get_launcher_toolchain",
"get_oxc_toolchain",
"get_tools_toolchain",
"get_tsgo_toolchain",
)
| Type label | Target | Runs on | Accessor | Returns |
|---|---|---|---|---|
OXC_TOOLCHAIN_TYPE |
//ts/toolchain:oxc_toolchain_type |
the exec platform | get_oxc_toolchain(ctx) |
OxcToolchainInfo |
TSGO_TOOLCHAIN_TYPE |
//ts/toolchain:tsgo_toolchain_type |
the exec platform | get_tsgo_toolchain(ctx) |
TsgoToolchainInfo |
TOOLS_TOOLCHAIN_TYPE |
//ts/toolchain:tools_toolchain_type |
the exec platform | get_tools_toolchain(ctx) |
ToolsInfo |
LAUNCHER_TOOLCHAIN_TYPE |
//ts/toolchain:launcher_toolchain_type |
the target platform | get_launcher_toolchain(ctx) |
LauncherInfo, or None when no toolchain resolved |
JS_RUNTIME_TOOLCHAIN_TYPE |
//ts/toolchain:js_runtime_type |
the target platform | get_js_runtime(ctx) |
JsRuntimeInfo, or None when no toolchain resolved |
JS_TOOL_TOOLCHAIN_TYPE |
//ts/toolchain:js_tool_type |
the exec platform | get_js_tool(ctx) |
JsRuntimeInfo, or None when no toolchain resolved |
The labels are Label() values, so they resolve in this ruleset's own
repository mapping and keep working under another repository name.
Node fills two roles that resolve against different platforms. js_runtime_type
is the runtime a ts_test or ts_binary program executes on: it is built for
the target platform and staged into runfiles. js_tool_type is Node as a build
tool (the node_modules tree builder, ts_codegen, the bundlers): it runs on
the exec platform. The two are equal under a plain host
build and differ the moment --platforms does.
| Provider | Field | Type | Description |
|---|---|---|---|
OxcToolchainInfo |
oxc_binary |
File |
The oxc-bazel CLI binary |
TsgoToolchainInfo |
tsgo_binary |
File |
The tsgo CLI binary |
ToolsInfo |
tsaction |
File |
The runner behind the TsConfig, TsEmit, tsgo, TsLint, TsTestPaths, TsManifest and NpmStore actions |
lcov_merger |
File |
ts_test's coverage merger, run through //ts/toolchain:lcov_merger_resolved |
|
copy_to_workspace |
File |
The copier ts_refresh_tsconfig writes the source tree with |
|
LauncherInfo |
launcher |
File |
The launcher a ts_test, ts_binary, ts_dev_server or npm_bin executable is a symlink of |
JsRuntimeInfo |
runtime_binary |
File |
The runtime executable: node, or a Deno, Bun or wrapper a consumer registers |
runtime_name |
string |
The name diagnostics use; "node" for the shipped toolchains |
|
args_prefix |
list of string |
Arguments placed before the entry script |
A rule declares the types it needs and reads them through the accessors:
load(
"@rules_typescript//ts/toolchain:defs.bzl",
"JS_TOOL_TOOLCHAIN_TYPE",
"TSGO_TOOLCHAIN_TYPE",
"get_js_tool",
"get_tsgo_toolchain",
)
def _impl(ctx):
tsgo = get_tsgo_toolchain(ctx).tsgo_binary
node = get_js_tool(ctx)
...
my_rule = rule(
implementation = _impl,
toolchains = [
TSGO_TOOLCHAIN_TYPE,
config_common.toolchain_type(JS_TOOL_TOOLCHAIN_TYPE, mandatory = False),
],
)
get_oxc_toolchain, get_tsgo_toolchain and get_tools_toolchain index
ctx.toolchains directly, so a rule listing any of the three types as mandatory
fails toolchain resolution when nothing registers one. get_js_runtime,
get_js_tool and get_launcher_toolchain return None for a type declared
with mandatory = False that nothing registered; ts_compile declares tsgo and
the JS tool that way, and oxc and the tools as mandatory; the four rules that
run a launcher declare it that way and fail analysis naming the target platform
when none resolved.
register_toolchains("@rules_typescript//ts/toolchain:all") registers every
instance: one oxc toolchain, built from source by rules_rs for whichever exec
platform runs the build; one tsgo toolchain per platform in TSGO_PLATFORMS,
constrained on the exec platform; one source-built tools toolchain for the execution platform and one source-built launcher toolchain per supported target platform; one Node runtime toolchain
per platform in NODE_PLATFORMS, constrained on the target platform; and one
Node tool toolchain per platform, constrained on the exec platform.
Which compiler the tsgo toolchains hold is the ts extension's to say, and it
reads a pnpm lockfile: the root importer's typescript entry names the version,
and the packages: entries of that version's platform packages
(@typescript/typescript-<os>-<cpu>) carry the tarball and integrity of each
lib/tsc, which is what the per-platform repository rule downloads and
verifies. A consumer names its own lockfile:
ts = use_extension("@rules_typescript//ts:extensions.bzl", "ts")
ts.tsgo(pnpm_lock = "//:pnpm-lock.yaml")
With no call the lockfile is rules_typescript's own
ts/private/tsgo/pnpm-lock.yaml. ts.tsgo(version = "...") is the alternative
for a release no lockfile states, downloaded unverified;
package = "@typescript/native-preview" selects the nightly, whose binary is
lib/tsgo. TsgoToolchainInfo.tsgo_binary is that file either way.
Runtime input lifetime¶
Native binaries and node:test runners exec the configured runtime with the launcher's PID, process group, terminal and stdio. Their runtime view is a declared build output: the launcher neither creates a temporary application tree nor removes inputs when the original process exits. Surviving children can read those inputs for the lifetime of Bazel's outputs; an action sandbox still has Bazel's own lifetime.
The view preserves selected File provenance, canonical module coordinates and one internal authority for each ordinary File or npm store. It does not promise inode identity with an outside source or store. The native child receives the built view as its runfiles directory. Standard runfiles lookup and module imports therefore select the same module and npm store authority. The view carries Bazel's generated repository mapping unchanged. Package the launcher's runfiles with its generated config and complete runtime directory, retaining internal relative links; a runfiles manifest may relocate that group but cannot scatter its members independently. The configured runtime executable is resolved through its original runfiles.
Vitest and dev-server retain their mutable per-run setup and post-run behavior. Their owned workspace node_modules link is removed nonrecursively; private temporary trees are removed recursively.
tsgo from source¶
//ts/toolchain/tsgo_source is the same compiler built by rules_go.
ts/private/tsgo_source/go.mod names
github.com/microsoft/typescript-go/cmd/tsgo in a tool directive and
requires the module at the commit the lockfile's typescript release was
built from, so the two toolchains run one compiler at one revision, and a
change the ruleset makes to that source reaches a build that registers this
one. The ts extension reads the go.mod and its go.sum and declares one
Gazelle-written go_repository per require, the module's dependencies under
the names Gazelle writes for them; @tsgo_source//:tsgo aliases the module's
cmd/tsgo binary, and the toolchain over it constrains no platform, since
cfg = "exec" on the binary builds it for whichever platform runs the build.
The lockfile's binary reads its lib/*.d.ts from beside itself
(-tags=noembed); this build embeds them, so the binary is one file and its
listings name them under bundled:///libs/. The toolchain is outside
//ts/toolchain:all, so a consumer registers it by name, first:
register_toolchains(
"@rules_typescript//ts/toolchain/tsgo_source",
"@rules_typescript//ts/toolchain:all",
)
Two changes ride on that build, each a file under ts/private/tsgo_source/
that go_repository's patches (-p1) applies to the module's repository
before rules_go compiles it.
isolated-declarations-bound-expando.patch: under
isolatedDeclarations the 7.0.2 compiler crashes on an exported initializer
of the shape f().p || "" (panic: Unhandled case in Node.Text:
*ast.CallExpression): the declaration tracker's isBoundExpando took every
binary expression with a property access on its left for an expando
assignment and asked the resolver about the head of that access chain, which
the resolver reads as an identifier. Patched, it asks only when the operator
is = and the head is an identifier, and the compiler reports TS9013 where
TypeScript 5.9 reports TS9007. The patch carries the module's own case,
isolatedDeclarationsBoundExpandoCallee, with its baselines;
//tests/integration:oxc_declarations_test runs TsgoCheck over the shape
under this toolchain and expects TS9013. The lockfile's binary keeps the
crash.
module-augmentation-include-reason.patch: a declare module "<name>"
augmentation resolves its module as an import does and adds no file, and the
7.0.2 compiler records no reason for it, so --explainFiles lists the
augmented file with the imports that reached it and never the augmentation.
Patched, a module the program holds is listed with Augmented via "<name>"
from file '<augmenting file>' (with the packageId where the resolution has
one) and the related info File is augmented here.; the program's file set
is unchanged, so a module nothing imports is still TS2664. The patch carries
the module's own case, TestExplainFilesModuleAugmentation in
internal/compiler/program_test.go;
//tests/integration:gazelle_roundtrip_test registers this toolchain first
and expects //augmented's dep on the package its probe.ts augments and
never imports. The lockfile's binary lists no augmentation, so Gazelle over
it writes no such dep.
The pin moves in ts/private/tsgo_source with
go get github.com/microsoft/typescript-go@<commit> && go mod tidy; for
TypeScript 7.1 the Go code moved into github.com/microsoft/TypeScript under
tsc/, so the next pin changes the module path in the tool line and the
require. //ts/private/tsgo:tsgo_test reads the revision the lockfile's
linux-amd64 binary embeds (go version -m prints it as vcs.revision) and
fails when it is not the pinned one, naming both, so a typescript bump in
the lockfile names the pin to move. A build that first resolves the toolchain
compiles the module: 91 sandboxed actions, 113.5 s wall and an 89.6 s critical
path on a 22-core machine at load 11, cached after. rules_go's apparent name
in this module is io_bazel_rules_go, the name Gazelle writes into the BUILD
files of a repository with no MODULE.bazel of its own.
//tests/toolchain:foreign_target_platform_test pins the split. It analyses a
probe rule under --platforms=//platforms:windows_amd64, a platform with a Node
runtime and no compiler binary: oxc and tsgo still resolve to exec-platform
binaries, the staged runtime is nodejs_windows_amd64, and the tool runtime is
not.