jsreach

package
v0.11.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 11, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package jsreach implements a Tier-3 (package-level) reachability analyzer for npm packages. It walks application source files reachable from package.json entry points, builds a static import graph, and reports each npm registry vulnerability as Reachable / Unreachable / Unknown depending on whether the affected package's bare specifier appears in the import set.

Tier-3 caveat: "unreachable" here means "the application does not import this package at all, neither directly nor indirectly through app source". It does NOT mean "the vulnerability cannot be triggered" — for example, a server runtime might dynamically require the package based on user input. See docs/REACHABILITY.md for full semantics.

The runner uses the vendored github.com/evanw/esbuild/pkg/api library to walk the project's entry points in-process so users never need an esbuild binary on PATH. esbuild handles ESM, CJS, TS/TSX/JSX, conditional exports, and subpath imports natively. The Runner interface is preserved (rather than calling api.Build directly from the analyzer) so unit tests can inject a fake runner for deterministic behavior.

Index

Constants

View Source
const Name = "jsreach"

Name is the analyzer's stable identifier (used in selectors and output).

Variables

This section is empty.

Functions

This section is empty.

Types

type Analyzer

type Analyzer struct {
	// Runner is the underlying esbuild driver. Defaults to
	// NewRunner(Logger) when nil.
	Runner Runner
	Logger *zap.Logger
	// CacheDir overrides the default per-project result cache
	// location. Empty means "use the OS user cache directory under
	// bomly/analyzers/jsreach".
	CacheDir string
	// CacheTTL overrides the default 24h cache lifetime. Zero means
	// use the default.
	CacheTTL time.Duration
	// DisableCache turns off the on-disk result cache entirely.
	// Useful in CI smoke runs where freshness matters more than
	// speed.
	DisableCache bool
}

Analyzer is a Tier-3 (package-level) reachability analyzer for npm packages. It groups npm packages in the input graph by project root, runs the configured Runner once per project, and annotates each registry vulnerability on npm packages with a Reachability result.

Tier-3 caveat: "unreachable" here means "the application source does not import this package, neither directly nor indirectly through app code". It does NOT mean "the vulnerability cannot be triggered". docs/REACHABILITY.md is the authoritative source on this distinction.

func (Analyzer) Analyze

Analyze runs the configured Runner per discovered npm project root and writes Reachability onto every npm registry vulnerability in the graph. Errors degrade to Status=Unknown with a stable Reason — the engine relies on this to keep the pipeline running.

func (Analyzer) Applicable

func (a Analyzer) Applicable(_ context.Context, req model.AnalyzeRequest) (bool, error)

Applicable reports whether the request graph contains at least one npm package with attached vulnerabilities. Without vulnerabilities to annotate, the analyzer would do work without producing output.

func (Analyzer) Descriptor

func (a Analyzer) Descriptor() model.AnalyzerDescriptor

Descriptor returns the registration metadata for the jsreach analyzer.

func (Analyzer) Ready

func (a Analyzer) Ready() bool

Ready reports whether the analyzer is callable. Always true; the runner surfaces missing-toolchain or parser errors at Run time as Status=Unknown rather than blocking applicability.

type Runner

type Runner interface {
	// Name returns a stable identifier (e.g. "library") used in
	// telemetry and Reason fields.
	Name() string
	// Version returns the underlying tool version. The result cache
	// folds it into its key so toolchain upgrades invalidate prior
	// entries automatically. Empty string is acceptable; the cache
	// treats it like any other distinct value.
	Version() string
	// Run walks projectDir and returns the bare-specifier import set
	// found across every entry-reachable source file. projectDir must
	// contain a package.json.
	Run(ctx context.Context, projectDir string) (RunnerResult, error)
}

Runner walks an npm project rooted at projectDir and returns the bare-specifier import set reachable from its declared entry points. Implementations must NEVER panic and should map missing toolchains, parse errors, and other recoverable conditions to a (RunnerResult, error) pair where the error is descriptive but does not abort the pipeline.

func NewRunner

func NewRunner(logger *zap.Logger) Runner

NewRunner returns the analyzer's Runner implementation, backed by the vendored github.com/evanw/esbuild/pkg/api library. The runner walks the project's entry points in-process and emits a metafile we parse for the bare-specifier import set, so users never need an esbuild binary on PATH.

type RunnerResult

type RunnerResult struct {
	// ImportedPackages is the set of bare specifiers (e.g. "react",
	// "@scope/pkg") imported anywhere in the project's reachable source
	// tree. Subpath imports ("@scope/pkg/util") are normalized to the
	// owning package name.
	ImportedPackages map[string]struct{}
	// EntryPoints is the list of files the runner started its walk
	// from (mostly for logging / debug output).
	EntryPoints []string
	// SourceFiles is the count of project source files the runner
	// visited (for telemetry).
	SourceFiles int
	// DynamicImportsDetected is true when the runner observed
	// dynamic-import constructs in app source it cannot follow
	// statically (e.g. `require(variable)`, `import(variable)`,
	// `await import(name)`). When true, the analyzer's "unreachable"
	// verdicts are necessarily incomplete and the per-vuln
	// Reachability.DynamicImportsDetected flag is set.
	DynamicImportsDetected bool
}

RunnerResult is the parsed output of one runner pass over a project. It carries enough information for the analyzer to map advisories to reachable/unreachable/unknown without re-reading any source.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL