/// import type { Plugin, TsconfigRaw } from "esbuild"; import type { FileSystemEvent, WatchrOptions } from "@d1g1tal/watchr"; import type { CompilerOptions, Diagnostic, ProjectReference, ScriptTarget } from "typescript"; import type { PerformanceEntry, PerformanceMeasureOptions } from "node:perf_hooks"; declare global { interface ImportMeta { env?: { tsbuild_version?: string; }; } } type Prettify = T extends infer U ? { [K in keyof U]: U[K]; } : never; type KnownKeys = keyof RemoveIndex; type MarkRequired = Prettify; type RemoveIndex = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; }; type PrettyModify>> = Prettify & R>; type Modify>> = Omit & R; type Optional = T | undefined | void; type OptionalReturn any> = Optional>; type Fn

= (...args: P[]) => R; type TypedFunction any> = (...args: Parameters) => ReturnType; type InferredFunction = T extends (...args: infer P) => infer R ? (...args: P) => R : never; /** * Type representing a method function signature with typed this, arguments, and return type. * Used to avoid inlining the method signature type repeatedly in decorator code. * * @template T - The type of 'this' context for the method * @template A - The types of the method arguments as a tuple * @template R - The return type of the method */ type MethodFunction = (this: T, ...args: A) => R; type Callable = Fn; type Constructor

= new (...args: P) => R; interface Closable { close: Callable; } type ClosableConstructor = Constructor; type PerformanceSubStep = { name: string; duration: string; ms: number; }; type PerformanceEntryDetail = { message: string; result?: T; steps?: PerformanceSubStep[]; notes?: string[]; }; type DetailedPerformanceMeasureOptions = Modify; }>; type DetailedPerformanceEntry = PerformanceEntry & { detail: PerformanceEntryDetail; }; type Pattern = string | RegExp; declare const ES_VERSIONS: readonly [6, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025]; type EsVersion = typeof ES_VERSIONS[number]; type EsTarget = `ES${EsVersion}` | 'ESNext'; type BannerOrFooter = { [type in 'js' | 'css']?: string; }; /** * Creates a "branded" type with nominal typing. * This adds a unique, non-existent property to 'T' to make it * incompatible with other types that are structurally the same. * * @template T - The base type to brand * @template U - The brand identifier (symbol type or any other type) * * @example Symbol brands (stronger nominal typing): * declare const PathSymbol: unique symbol; * type Path = Brand; * * @example Generic brands: * type JsonString = Brand; */ type Brand = U extends symbol ? T & { readonly [K in U]: true; } : T & { readonly __brand: U; }; declare const AbsolutePathBrand: unique symbol; declare const RelativePathBrand: unique symbol; /** An absolute file system path (e.g., `/home/user/project` or `C:\Users\project`) */ type AbsolutePath = Brand; /** A relative file system path (e.g., `./src` or `../lib`) */ type RelativePath = Brand; /** A file system path that can be either absolute or relative */ type Path = AbsolutePath | RelativePath; type ConditionalPath = T extends AbsolutePath ? AbsolutePath : T extends RelativePath ? RelativePath : Path; type JsonString = Brand; type DtsOptions = { /** Names of the projects `entryPoints` to be used to generate the DTS files */ entryPoints?: string[]; /** Resolve external types used in dts files from node_modules */ resolve?: boolean; }; type DtsConfiguration = MarkRequired; type IifeOptions = { /** Global variable name for the IIFE bundle (e.g., 'MyLib' becomes `globalThis.MyLib`) */ globalName?: string; }; type WatchOptions = PrettyModify; type WatchConfiguration = MarkRequired; type PendingFileChange = { event: FileSystemEvent; path: AbsolutePath; nextPath?: AbsolutePath; }; type JsxRenderingMode = NonNullable['compilerOptions']['jsx']>; /** User-facing tsbuild configuration (excludes TypeScript compiler options like target, outDir, sourceMap) */ type BuildOptions = { /** Project directory (relative or absolute). Defaults to the current directory. Resolved to absolute internally. */ project?: Path; /** Force a full rebuild, even if no files have changed. Applicable for incremental builds */ force?: boolean; entryPoints?: EntryPoints; /** Platform target. Auto-detected from tsconfig lib (DOM = browser, no DOM = node) */ platform?: 'browser' | 'node' | 'neutral'; bundle?: boolean; /** Remove all files from the output directory before building. Defaults to true */ clean?: boolean; /** Default behavior for node_modules dependencies */ packages?: 'bundle' | 'external'; /** Specific dependencies to externalize (don't bundle) */ external?: Pattern[]; /** Specific dependencies to bundle (override packages setting) */ noExternal?: Pattern[]; splitting?: boolean; minify?: boolean; /** Source map options. Overrides the value in tsconfig.json CompilerOptions */ sourceMap?: boolean | 'inline' | 'external' | 'both'; banner?: BannerOrFooter; footer?: BannerOrFooter; env?: Record; dts?: DtsOptions; watch?: WatchOptions; /** Emit decorator metadata (requires `@swc/core` as optional dependency) */ decoratorMetadata?: boolean; /** Produce additional IIFE output alongside ESM. Set to `true` for default IIFE or provide options. */ iife?: boolean | IifeOptions; /** Custom esbuild plugins (Plugin objects via programmatic API, or string/tuple references via config) */ plugins?: (Plugin | PluginReference)[]; }; /** * A reference to an esbuild plugin resolved at build time. * - `string` — bare npm specifier or relative path to a plugin module * - `[string, Record]` — module specifier with options passed to the factory function */ type PluginReference = string | [string, Record]; type BuildConfiguration = PrettyModify, { watch: WatchConfiguration; dts: DtsConfiguration; }>; type EntryPoints = Record; type AsyncEntryPoints = Promise>; /** Project build options used internally (includes values from both tsbuild config and compiler options) */ type ProjectBuildConfiguration = Readonly>; type TypeScriptCompilerOptions = Modify>, { target?: ScriptTarget; }>; type TypeScriptCompilerConfiguration = MarkRequired; type TypeScriptOptions = { clearCache?: boolean; compilerOptions?: TypeScriptCompilerOptions; tsbuild?: BuildOptions; }; /** Cached declaration file with pre-processed code and extracted references */ type CachedDeclaration = { code: string; /** Triple-slash type reference directives extracted during pre-processing */ typeReferences: ReadonlySet; /** Triple-slash file reference directives extracted during pre-processing */ fileReferences: ReadonlySet; }; /** Persistent cache payload stored in .tsbuild/dts_cache.v8.br */ type BuildCache = { /** Cache format version for compatibility checking */ version: number; /** Cached declaration files: path -> pre-processed code with extracted references */ files: Map; /** Build configuration fingerprint: hash of output-affecting options (minify, iife, declaration, platform, etc.) */ fingerprint?: string; }; interface BuildCacheManager { invalidate(): void; restore(target: Map): Promise; save(source: ReadonlyMap, fingerprint: string): Promise; isValid(): boolean; isBuildInfoFile(filePath: AbsolutePath): boolean; /** Synchronously checks whether persisted incremental state exists on disk (i.e. .tsbuildinfo). */ hasPersistedState(): boolean; /** Synchronously checks whether a manifest snapshot from a prior build is available. */ hasPersistedManifest(): boolean; /** Returns the project-relative output paths recorded by the previous build, or undefined if none. */ getPreviousOutputs(): readonly string[] | undefined; /** Persists the project-relative output paths produced by the current build. Fire-and-forget. */ saveOutputs(outputs: readonly string[]): Promise; /** Checks whether the build configuration has changed since the cache was last saved. */ fingerprintMatches(currentFingerprint: string): Promise; } type TypeScriptConfiguration = Readonly>; type ProjectDependencies = { dependencies?: Record; devDependencies?: Record; peerDependencies?: Record; optionalDependencies?: Record; }; type ReadConfigSuccess = { config: TypeScriptOptions; error: undefined; }; type ReadConfigError = { config: undefined; error: Diagnostic; }; type ReadConfigResult = ReadConfigSuccess | ReadConfigError; type WrittenFile = { readonly path: RelativePath; readonly size: number; }; type CompilerOptionOverrides = Readonly<{ noEmitOnError: true; allowJs: false; checkJs: false; declarationMap: false; skipLibCheck: true; preserveSymlinks: false; target: ScriptTarget.ESNext; }>; type SourceMap = { version: number; sources: string[]; names: string[]; mappings: string; file?: string; sourceRoot?: string; sourcesContent?: string[]; }; type FormatSupplier = (text: string) => string; type LogEntryType = 'info' | 'success' | 'done' | 'error' | 'warn'; /** Class representing a TypeScript project */ declare class TypeScriptProject implements Closable { private fileWatcher?; private builderProgram; private readonly directory; private readonly configuration; private readonly fileManager; private readonly buildConfiguration; private readonly pendingChanges; private readonly buildDependencies; private pendingStaleOutputsCleanup?; /** Identity of the Program that populated buildDependencies — skip re-walking when unchanged */ private buildDependenciesProgram; private dependencyPaths?; /** * Creates a TypeScript project and prepares it for building/bundling. * @param directory - Project root directory (defaults to current working directory) * @param options - Project options to merge with tsconfig.json */ constructor(directory?: string | AbsolutePath, options?: TypeScriptOptions); /** * Cleans the output directory * @returns A promise that resolves when the cleaning is complete. */ clean(): Promise; /** * Removes outputs that the previous build wrote but the current build did not — e.g. renamed * entry points or content-hashed chunks whose hash changed. Restricted to files under outDir * for safety. Fire-and-forget: scheduled after build completion so it never inflates timings. * @param previous - Project-relative paths recorded by the previous build (or undefined) * @param current - Project-relative paths produced by the current build */ private cleanupStaleOutputs; /** * Waits for fire-and-forget stale-output cleanup to settle. * Useful for deterministic tests that need to assert post-cleanup filesystem state. */ flushBackgroundCleanup(): Promise; /** * Builds the project * @returns A promise that resolves when the build is complete. */ build(): Promise; /** * Type-checks the project and optionally emits declaration files. * When declarations are enabled in compiler options, this method also handles * initializing and finalizing the file manager for incremental builds. * * For incremental builds, TypeScript's emit writes a .tsbuildinfo file only when changes * are detected. This is used to determine whether subsequent build phases should run. * * @returns True if files were emitted (or non-incremental build), false if no changes detected */ private typeCheck; /** * Transpiles the project using esbuild. * @returns A promise that resolves to an array of written files after transpilation. */ private transpile; /** * Watches for changes in the project files and rebuilds the project when changes are detected. */ private watch; /** Closes the project and cleans up resources. */ close(): void; /** * Processes declaration files. * @returns A promise that resolves to an array of written files after processing declarations. */ private processDeclarations; /** * Triggers a rebuild after debouncing. */ private triggerRebuild; /** * Resolves configuration by merging options with tsconfig.json. * @param directory - Project root directory * @param typeScriptOptions - Partial TypeScript options to merge * @returns Resolved configuration and TypeScript parser results */ private static resolveConfiguration; /** * Gets the entry points for the project. * @param entryPoints - The entry points to get. * @returns A promise that resolves to the entry points. */ private getEntryPoints; /** * Gets the project dependency paths. * The promise is started in the constructor so it overlaps with TS Program creation. * @returns A promise that resolves to an array of project dependency paths. */ private getProjectDependencyPaths; /** * Handles build errors by logging unexpected errors and setting appropriate exit codes. * Expected build failures (TypeCheckError, BundleError) are already logged when they occur, * so this method only logs unexpected errors to avoid duplicate output. * @param error - The error to handle */ private handleBuildError; /** * Handles type errors in the project. * @param message - The message to display. * @param diagnostics - The diagnostics to handle. * @param projectDirectory - The project directory. */ private static handleTypeErrors; } export { Plugin, TypeScriptProject }; export type { AbsolutePath, AsyncEntryPoints, Brand, BuildCache, BuildCacheManager, BuildConfiguration, CachedDeclaration, Closable, ClosableConstructor, CompilerOptionOverrides, ConditionalPath, DetailedPerformanceEntry, DetailedPerformanceMeasureOptions, EntryPoints, EsTarget, Fn, FormatSupplier, IifeOptions, InferredFunction, JsonString, JsxRenderingMode, LogEntryType, MethodFunction, OptionalReturn, Path, Pattern, PendingFileChange, PerformanceSubStep, PluginReference, ProjectBuildConfiguration, ProjectDependencies, ReadConfigResult, RelativePath, SourceMap, TypeScriptConfiguration, TypeScriptOptions, TypedFunction, WrittenFile };