contentmapper

package
v0.0.0-...-aa81492 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package contentmapper defines the types describing an external content mapper: a plugin that transforms otherwise unsupported file content (e.g. .vue) into virtual TypeScript during program construction.

A mapper is declared in tsconfig (Definition), its implementation is described by fields in its npm package's package.json (Manifest), and the two are combined once the package is resolved (Mapper). Resolution itself lives in the tsoptions package (it needs node module resolution).

The package also drives the configured content mappers at build time (Host): it spawns each mapper's package as a child process and talks to it over a JSON-RPC connection (reusing internal/ipc), turning content-mapped source files into virtual TypeScript. Processes are consolidated by mapper identity, so many projects that use the same mapper version share a single process.

Index

Constants

View Source
const (
	MethodInitialize   = "initialize"
	MethodOpenProject  = "openProject"
	MethodCloseProject = "closeProject"
	MethodTransform    = "transform"
)

Content mapper protocol method names.

Variables

View Source
var ErrProjectUnavailable = errors.New("content mapper project is unavailable")

Functions

func CheckSupplementalFileNameCollisions

func CheckSupplementalFileNameCollisions(files SourceFiles, fileExists func(tspath.RootedFilePath) bool) error

CheckSupplementalFileNameCollisions rejects compiler-assigned virtual filenames that name physical files.

func IsSupportedVirtualExtension

func IsSupportedVirtualExtension(extension string) bool

Types

type CloseProjectParams

type CloseProjectParams struct {
	ProjectHandle string `json:"projectHandle"`
}

CloseProjectParams is the parameter object for the closeProject request.

type Definition

type Definition struct {
	Package    string     `json:"package"`
	Extensions []string   `json:"extensions"`
	Options    json.Value `json:"options,omitempty"`
}

Definition is a content mapper as declared in a tsconfig's "contentMappers": the npm package that implements the mapper and the otherwise unsupported file extensions it registers.

type Diagnostic

type Diagnostic struct {
	// MessageText is the diagnostic message.
	MessageText string `json:"messageText"`
	// Start and Length locate the diagnostic in the original content using the selected position encoding.
	Start  int   `json:"start"`
	Length int   `json:"length"`
	Code   int32 `json:"code"`
}

Diagnostic is an error reported by a mapper in original-source coordinates.

type DiagnosticDirectiveError

type DiagnosticDirectiveError struct {
	Kind              DiagnosticDirectiveErrorKind
	Index             int
	SupplementalIndex int
	Policy            DiagnosticDirectivePolicy
}

DiagnosticDirectiveError reports an invalid diagnostic directive in a transform response.

func (*DiagnosticDirectiveError) Error

func (e *DiagnosticDirectiveError) Error() string

type DiagnosticDirectiveErrorKind

type DiagnosticDirectiveErrorKind uint8

DiagnosticDirectiveErrorKind identifies why a diagnostic directive was rejected.

const (
	DiagnosticDirectiveErrorKindInvalidRange DiagnosticDirectiveErrorKind = iota
	DiagnosticDirectiveErrorKindInvalidPolicy
	DiagnosticDirectiveErrorKindExpectMissingUnusedDiagnostic
	DiagnosticDirectiveErrorKindInvalidUnusedDiagnosticIndex
	DiagnosticDirectiveErrorKindOverlap
)

type DiagnosticDirectivePolicy

type DiagnosticDirectivePolicy uint8

DiagnosticDirectivePolicy is the numeric policy stored in a mapped diagnostic directive tuple.

const (
	DiagnosticDirectivePolicyIgnore DiagnosticDirectivePolicy = iota
	DiagnosticDirectivePolicyExpect
)

type DiagnosticDirectives

type DiagnosticDirectives struct {
	UnusedExpectDirectiveDiagnostics []UnusedExpectDirectiveDiagnostic `json:"unusedExpectDirectiveDiagnostics"`
	Directives                       []MappedDiagnosticDirective       `json:"directives"`
}

DiagnosticDirectives shares unused-expect diagnostics across compact directive tuples.

type Host

type Host interface {
	// Timings returns a cumulative snapshot of mapper process and protocol activity.
	Timings() Timings
	// Project returns a retained project-scoped view for spec. Equivalent specs share underlying mapper
	// configuration state; the caller must close the returned Project.
	Project(spec ProjectSpec) Project
	// Acquire retains the processes for the given mapper identities until the returned lease is released.
	// Acquiring a mapper does not start its process; processes remain lazy until Transform is called.
	Acquire(mappers []*Mapper) (release func())
	// SetLocale updates the locale used to initialize mapper processes. Existing processes are stopped
	// and respawned lazily so subsequent transforms use the new locale.
	SetLocale(locale locale.Locale)
	// Transform maps a content-mapped source file to virtual TypeScript using the given content mapper
	// in a short-lived project with default compiler options.
	//
	// A non-nil error indicates the mapper itself failed to produce a result — for example the
	// host hit a broken pipe, a process crash, or could not deserialize the mapper's response.
	Transform(mapper *Mapper, request Request) (result Result, err error)
	// Close shuts down every mapper process the host spawned.
	Close() error
}

Host transforms otherwise unsupported file content into virtual TypeScript during program construction, by driving the configured content mappers. Create one with NewHost; Close tears down every mapper it spawned.

func NewHost

func NewHost(ctx context.Context, spawner Spawner, diagnosticLocale locale.Locale) Host

NewHost creates a Host that spawns each mapper's process via the given spawner and drives it over a JSON-RPC connection. The host's lifetime is bound to ctx: cancelling it (e.g. the CLI's signal context on SIGINT, or a build/watch session ending) tears every mapper process down, so owners of a session context need not close the host explicitly. Close does the same synchronously.

func NewHostWithOptions

func NewHostWithOptions(ctx context.Context, spawner Spawner, diagnosticLocale locale.Locale, options HostOptions) Host

NewHostWithOptions creates a Host with optional protocol and process logging.

type HostOptions

type HostOptions struct {
	Logger Logger
}

HostOptions configures optional content mapper process logging.

type InitializeError

type InitializeError struct {
	Kind             InitializeErrorKind
	MapperName       string
	Command          string
	Detail           string
	ExitCode         int
	TimeoutSeconds   int
	PositionEncoding PositionEncoding
	DiagnosticSource string
}

InitializeError reports an invalid or unsupported mapper initialize response.

func (*InitializeError) Error

func (e *InitializeError) Error() string

type InitializeErrorKind

type InitializeErrorKind uint8

InitializeErrorKind identifies why a mapper's initialize response was rejected.

const (
	InitializeErrorKindProcessStart InitializeErrorKind = iota
	InitializeErrorKindProcessExit
	InitializeErrorKindNoResponse
	InitializeErrorKindInvalidResponse
	InitializeErrorKindRequest
	InitializeErrorKindPositionEncoding
	InitializeErrorKindEmptyDiagnosticSource
	InitializeErrorKindReservedDiagnosticSource
)

type InitializeParams

type InitializeParams struct {
	// Locale is the BCP 47 locale to use for mapper-authored diagnostic messages, when configured.
	Locale string `json:"locale,omitempty"`
	// PositionEncodings lists the coordinate spaces the host accepts.
	PositionEncodings []PositionEncoding `json:"positionEncodings"`
}

InitializeParams is the parameter object for the initialize request.

type InitializeResult

type InitializeResult struct {
	// PositionEncoding selects the coordinate space for all mappings and diagnostics.
	PositionEncoding PositionEncoding `json:"positionEncoding"`
	// DiagnosticSource is the prefix used for every mapper-authored diagnostic code.
	DiagnosticSource string `json:"diagnosticSource"`
}

InitializeResult is the mapper's response to the initialize request.

type InvalidVirtualExtensionError

type InvalidVirtualExtensionError struct {
	Extension string
}

InvalidVirtualExtensionError reports an unsupported or missing virtual extension on a mapped output.

func (*InvalidVirtualExtensionError) Error

type Logger

type Logger func(message string)

Logger receives content mapper protocol and process output as complete log lines.

type Manifest

type Manifest struct {
	Name            string
	Version         string
	Exec            []string
	CompilerOptions []string
	DynamicConfig   bool
}

Manifest is the content-mapper information read from a package's package.json: its name and version (which form the mapper's identity), the argv used to run it, and the compiler options it declares it depends on.

type MappedDiagnosticDirective

type MappedDiagnosticDirective struct {
	OriginalStart              int
	OriginalLength             int
	VirtualStart               int
	VirtualEnd                 int
	Policy                     DiagnosticDirectivePolicy
	UnusedExpectDirectiveIndex *int
}

MappedDiagnosticDirective is encoded as [originalStart, originalLength, virtualStart, virtualEnd, policy, unusedExpectDirectiveIndex?]. An omitted index selects the only unused-expect diagnostic and is invalid when there is not exactly one.

func (MappedDiagnosticDirective) MarshalJSONTo

func (d MappedDiagnosticDirective) MarshalJSONTo(enc *json.Encoder) error

func (*MappedDiagnosticDirective) UnmarshalJSONFrom

func (d *MappedDiagnosticDirective) UnmarshalJSONFrom(dec *json.Decoder) error

type MappedOutput

type MappedOutput struct {
	// Text is the virtual JavaScript or TypeScript source text.
	Text string `json:"text"`
	// Extension determines the virtual source file's syntax.
	Extension string `json:"extension"`
	// Mappings is the span map's tuple-array JSON (see spanmap.Marshal), expressed in the selected
	// position encoding. Absent or empty means the output is fully synthesized.
	Mappings json.Value `json:"mappings,omitempty"`
	// DiagnosticDirectives describe framework directives that suppress TypeScript diagnostics in
	// virtual ranges and optionally report an error when no diagnostic is produced.
	DiagnosticDirectives *DiagnosticDirectives `json:"diagnosticDirectives,omitempty"`
}

MappedOutput is virtual source text and its mapping to an original input.

type MappedResult

type MappedResult struct {
	Text                 string
	VirtualExtension     string
	Mappings             *spanmap.SpanMap
	DiagnosticDirectives []ast.MappedDiagnosticDirective
}

MappedResult is one virtual source file and its mapping to the original input.

type Mapper

type Mapper struct {
	Definition
	Manifest `json:"-"`
	// PackageDirectory is the real path directory returned by package resolution for package-based mappers.
	PackageDirectory tspath.RootedDirectoryPath `json:"-"`
	// ContributionID is provided by an LSP client extension for inferred project content mappers.
	ContributionID string `json:"-"`
}

Mapper is a resolved content mapper: its tsconfig Definition combined with the Manifest resolved from the package's package.json, plus the package directory used as the mapper's working directory.

func (*Mapper) DiagnosticName

func (m *Mapper) DiagnosticName() string

DiagnosticName returns the best available user-facing name, including when manifest resolution failed.

func (*Mapper) Equals

func (m *Mapper) Equals(other *Mapper) bool

Equals compares the complete mapper configuration, not just its advertised identity.

func (*Mapper) Identity

func (m *Mapper) Identity() string

Identity returns the mapper's "name@version" identity, or just the name when it declares no version, or an empty string when the mapper has not been resolved to a name.

func (*Mapper) MarshalDeclaredOptions

func (m *Mapper) MarshalDeclaredOptions(options *core.CompilerOptions) (*collections.OrderedMap[string, json.Value], error)

MarshalDeclaredOptions marshals just the compiler options this mapper declared it depends on, in the declared order, skipping any that are unset. Marshaling only the declared fields avoids serializing the whole CompilerOptions when a mapper depends on few options (or none).

func (*Mapper) TransformIdentity

func (m *Mapper) TransformIdentity(options *core.CompilerOptions) xxh3.Uint128

TransformIdentity returns a fingerprint of everything besides a file's content that determines the output of transforming it with this mapper under the given options: the mapper's identity and the values of the compiler options it declared it depends on. Folding it into a cache key means a change to the mapper version or a relevant compiler option invalidates cached results. It is a pure function of the mapper and options — the declared options come from the manifest, so it never starts the mapper process.

type MapperTimings

type MapperTimings struct {
	Spawn        OperationTiming
	Initialize   OperationTiming
	OpenProject  OperationTiming
	CloseProject OperationTiming
	Transform    OperationTiming
}

MapperTimings is cumulative process and protocol activity for one resolved mapper identity.

type OpenProjectParams

type OpenProjectParams struct {
	// ConfigFileName is the absolute project configuration file name, or empty when there is none.
	ConfigFileName string `json:"configFileName"`
	// ProjectHandle is an opaque, process-local handle assigned by the host.
	ProjectHandle string `json:"projectHandle"`
	// Options is the mapper entry's options from the project's contentMappers configuration.
	Options json.Value `json:"options,omitempty"`
	// CompilerOptions contains the project's effective compiler options.
	CompilerOptions json.Value `json:"compilerOptions"`
}

OpenProjectParams is the parameter object for the openProject request.

type OpenProjectResult

type OpenProjectResult struct {
	// ConfigIdentity is a stable fingerprint of all dynamic configuration that can affect transforms.
	ConfigIdentity string `json:"configIdentity"`
	// WatchedFiles are absolute files whose changes may alter ConfigIdentity or transform output.
	WatchedFiles []string `json:"watchedFiles,omitempty"`
	// OptionDiagnostics report invalid mapper options. Paths are relative to the mapper entry's options object.
	OptionDiagnostics []OptionDiagnosticResult `json:"optionDiagnostics,omitempty"`
}

OpenProjectResult is the mapper's response to an openProject request. ConfigIdentity and WatchedFiles may only be returned by mappers that declare dynamicConfig.

type OperationTiming

type OperationTiming struct {
	Count    uint64
	Duration time.Duration
}

OperationTiming is the cumulative wall time and invocation count for one mapper operation.

type OptionDiagnostic

type OptionDiagnostic struct {
	Mapper      *Mapper
	Path        []OptionPathSegment
	Source      string
	Code        int32
	MessageText string
}

type OptionDiagnosticResult

type OptionDiagnosticResult struct {
	Path        []json.Value `json:"path"`
	MessageText string       `json:"messageText"`
	Code        int32        `json:"code"`
}

type OptionPathSegment

type OptionPathSegment struct {
	Property string
	Index    int
	IsIndex  bool
}

type PositionEncoding

type PositionEncoding string

PositionEncoding is the coordinate space a mapper uses for mappings and diagnostics.

const (
	PositionEncodingUTF8  PositionEncoding = "utf-8"
	PositionEncodingUTF16 PositionEncoding = "utf-16"
)

type Project

type Project interface {
	// Refresh closes opened mapper projects so they are reopened on the next transform or configuration identity query.
	Refresh() error
	// Identities returns sorted transform identities for all configured mappers. It returns an error if
	// dynamic project configuration cannot be opened or validated.
	Identities() ([]string, error)
	// Identity returns the transform identity for mapper, or an empty string if mapper is not in this
	// project. It returns an error if dynamic project configuration cannot be opened or validated.
	Identity(mapper *Mapper) (string, error)
	// WatchedFiles returns the absolute files reported by mappers whose package.json declares dynamicConfig.
	// It returns an error if project configuration cannot be opened or validated.
	WatchedFiles() ([]tspath.RootedFilePath, error)
	// Diagnostics returns option diagnostics cached by mapper projects that have already been opened.
	Diagnostics() []OptionDiagnostic
	// Transform transforms one content-mapped source file using mapper in this project's configuration.
	Transform(mapper *Mapper, request Request) (result Result, err error)
	// Close releases this project reference and closes mapper project handles when no references remain.
	Close() error
}

Project is the project-scoped view of a Host. It owns mapper configuration handles and provides the identities and watch dependencies needed for caching and incremental builds. Mapper projects are opened lazily when a transform is requested, or earlier when dynamic configuration is needed.

type ProjectError

type ProjectError struct {
	Kind ProjectErrorKind
}

ProjectError reports an invalid mapper openProject response.

func (*ProjectError) Error

func (e *ProjectError) Error() string

type ProjectErrorKind

type ProjectErrorKind uint8

ProjectErrorKind identifies why a mapper's openProject response was rejected.

const (
	ProjectErrorKindMalformedResponse ProjectErrorKind = iota
	ProjectErrorKindMissingConfigIdentity
	ProjectErrorKindNonAbsoluteWatchedFile
	ProjectErrorKindUnexpectedConfigIdentity
	ProjectErrorKindUnexpectedWatchedFiles
)

type ProjectSpec

type ProjectSpec struct {
	// ConfigFileName is the absolute project configuration file name, or empty for a project without one.
	ConfigFileName tspath.RootedFilePath
	// Mappers are the resolved content mapper entries configured for the project.
	Mappers []*Mapper
	// CompilerOptions are the project's effective compiler options.
	CompilerOptions *core.CompilerOptions
}

ProjectSpec describes the project configuration visible to its content mappers.

type Request

type Request struct {
	// FileName is the content-mapped source file being transformed.
	FileName tspath.RootedFilePath
	// Content is the content-mapped source file's text.
	Content string
}

Request carries the inputs for transforming one content-mapped source file.

type Result

type Result struct {
	// Text is the virtual TypeScript source text that is parsed into the program.
	Text string
	// VirtualExtension determines how Text is parsed.
	VirtualExtension string
	// Diagnostics are syntax errors in the original content.
	Diagnostics []*ast.Diagnostic
	// Mappings maps positions in Text back to the original content, so that diagnostics the compiler
	// produces against the virtual text can be reported at their original locations. A successful
	// transform must return a non-nil map; an empty map describes fully synthesized output.
	Mappings *spanmap.SpanMap
	// DiagnosticDirectives control TypeScript diagnostics produced in virtual ranges.
	DiagnosticDirectives []ast.MappedDiagnosticDirective
	// Supplemental contains additional unnamed outputs associated with the canonical result.
	Supplemental []MappedResult
}

Result is the outcome of transforming a content-mapped source file into virtual TypeScript.

type SourceFiles

type SourceFiles struct {
	Canonical    *ast.SourceFile
	Supplemental []*ast.SourceFile
}

SourceFiles is the canonical output and its unnamed supplemental compiler inputs.

func ParseResult

func ParseResult(parseOptions ast.SourceFileParseOptions, content string, mapper *Mapper, transformIdentity string, result Result) (SourceFiles, error)

ParseResult validates and parses one mapper result and all its supplemental outputs.

func TransformAndParse

func TransformAndParse(
	parseOptions ast.SourceFileParseOptions,
	content string,
	mapper *Mapper,
	project Project,
) (SourceFiles, error)

TransformAndParse runs the given content mapper's transform for a content-mapped source file and parses the resulting TypeScript, preserving the original file name and retaining the untransformed text on the source file. The mapper is supplied by the caller (which also owns the failure accounting) so it is neither re-resolved nor substituted here. It returns an error if the transform fails or the mapper produces invalid position mappings (a *spanmap.MappingError); the caller decides how to report the failure and what placeholder file to substitute. It is the shared implementation behind CompilerHost.GetContentMappedSourceFile.

type Spawner

type Spawner interface {
	Spawn(command []string, dir string, stderr io.Writer) (io.ReadWriteCloser, error)
}

Spawner starts a child process, returning its stdio as an io.ReadWriteCloser (Read is the process's stdout, Write is its stdin) whose Close tears the process down. This seam keeps os/exec out of this package: production hosts spawn a real process, tests supply an in-process pipe.

type SpawnerFunc

type SpawnerFunc func(command []string, dir string, stderr io.Writer) (io.ReadWriteCloser, error)

SpawnerFunc adapts a spawn function to the Spawner interface.

func (SpawnerFunc) Spawn

func (f SpawnerFunc) Spawn(command []string, dir string, stderr io.Writer) (io.ReadWriteCloser, error)

type SupplementalFileCollisionError

type SupplementalFileCollisionError struct {
	FileName tspath.RootedFilePath
}

SupplementalFileCollisionError reports a compiler-assigned supplemental filename that already exists.

func (*SupplementalFileCollisionError) Error

type SupplementalOutput

type SupplementalOutput struct {
	MappedOutput
}

type Timings

type Timings struct {
	Mappers     map[string]MapperTimings
	RequestWait time.Duration
}

Timings is a cumulative snapshot of content mapper process and protocol activity.

func (Timings) Since

func (t Timings) Since(previous Timings) Timings

Since returns the non-negative operation delta since previous.

type TransformError

type TransformError struct {
	Kind TransformErrorKind
	// contains filtered or unexported fields
}

TransformError reports a failure while preparing, requesting, or decoding a transform.

func NewTransformError

func NewTransformError(kind TransformErrorKind, err error) *TransformError

NewTransformError creates a transform error for the given stage and underlying error.

func (*TransformError) Error

func (e *TransformError) Error() string

func (*TransformError) Unwrap

func (e *TransformError) Unwrap() error

type TransformErrorKind

type TransformErrorKind uint8

TransformErrorKind identifies the stage at which a content mapper transform failed.

const (
	TransformErrorKindUnknown TransformErrorKind = iota
	TransformErrorKindInitialize
	TransformErrorKindProject
	TransformErrorKindRequest
	TransformErrorKindResponse
	TransformErrorKindMappings
)

type TransformParams

type TransformParams struct {
	// FileName is the absolute name of the content-mapped source file being transformed.
	FileName string `json:"fileName"`
	// Content is the content-mapped source file's text.
	Content string `json:"content"`
	// ProjectHandle identifies the mapper project configuration opened for this transform.
	ProjectHandle string `json:"projectHandle"`
}

TransformParams is the parameter object for the transform request.

type TransformResult

type TransformResult struct {
	MappedOutput
	// Diagnostics are mapper-authored errors expressed in original-source coordinates.
	Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
	// Supplemental contains additional unnamed compiler inputs associated with this source file.
	Supplemental []SupplementalOutput `json:"supplemental,omitempty"`
}

TransformResult is the canonical output for one input file.

type UnusedExpectDirectiveDiagnostic

type UnusedExpectDirectiveDiagnostic struct {
	Code        int32  `json:"code"`
	MessageText string `json:"messageText"`
}

Jump to

Keyboard shortcuts

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