import { ts } from 'ts-morph'; import type { DeclarationPosition } from '../utils/get-declaration-location.ts'; import type { DirectoryEntry } from './types.ts'; /** Separator used in export IDs (format: "path/to/file.ts::exportName") */ export declare const EXPORT_ID_SEPARATOR = "::"; /** Maximum file size for AST parsing (1MB) */ export declare const MAX_PARSE_BYTES: number; /** Extension priority for module resolution */ export declare const EXTENSION_PRIORITY: string[]; /** Index file candidates for module resolution */ export declare const INDEX_FILE_CANDIDATES: string[]; /** Minimum Dice similarity for signature-based rename detection */ export declare const RENAME_SIGNATURE_DICE_MIN = 0.9; /** Lower threshold for renamed files */ export declare const RENAME_SIGNATURE_DICE_MIN_RENAMED_FILE = 0.7; /** Margin required between best and second-best candidates */ export declare const RENAME_SIGNATURE_DICE_MARGIN = 0.05; /** Minimum Dice similarity for path-based rename detection */ export declare const RENAME_PATH_DICE_MIN = 0.6; /** * Represents an export item from a module. * The ID is the unique identifier for the export across the codebase. */ export interface ExportItem { /** The exported name of the symbol */ name: string; /** The local declaration name when it differs from the export name (e.g. the class name for `export default class Foo`) */ localName?: string; /** The source name (for re-exports like `export { x as y }`) */ sourceName?: string; /** The ID of the export (format: "path/to/file::ExportName" or special markers) */ id: string; /** SHA-1 hash of the AST node text (for update detection) */ bodyHash: string; /** SHA-1 hash of the export signature (for update detection) */ signatureHash: string; /** The signature text (for similarity comparison) */ signatureText: string; /** The starting line number of the export (1-based) */ startLine?: number; /** The ending line number of the export (1-based) */ endLine?: number; /** The starting character offset of the resolved declaration node. */ position?: number; /** The syntax kind of the resolved declaration node. */ syntaxKind?: ts.SyntaxKind; /** The declaration line/column range of the resolved node. */ declarationPosition?: DeclarationPosition; /** Whether the export is deprecated */ deprecated?: true; /** The deprecation message */ deprecatedMessage?: string; } export interface ScanModuleExportsOptions { /** * Whether to compute stable body/signature hashes for each export. * * Disable this when callers only need export names and declaration * locations, since hashing dominates cold large-barrel scans. */ includeHashes?: boolean; /** * Whether to compute 1-based start/end line numbers for each export. * * Disable this when callers only need declaration positions, since the * line-number work is otherwise duplicated. */ includeLines?: boolean; /** * Whether to compute deprecation metadata from JSDoc and comments. * * Disable this for bulk header discovery where deprecation data is not * consumed, since comment scanning is expensive on large barrels. */ includeDeprecation?: boolean; } interface DeprecatedInfo { deprecated: true; deprecatedMessage?: string; } /** Get the shared TypeScript printer for consistent output */ export declare function getSharedTsPrinter(): ts.Printer; /** * Parse an export ID into its file and name components. * @param id The export ID (format: "path/to/file.ts::exportName") * @returns The parsed file and name, or null if invalid */ export declare function parseExportId(id: string): { file: string; name: string; } | null; /** * Format an export ID from file path and export name. * @param file The file path * @param name The export name * @returns The formatted export ID */ export declare function formatExportId(file: string, name: string): string; /** * Get the cache key for export parsing. * @param digest The content/blob digest * @param parserFlavor The parser flavor (usually derived from file extension) * @returns The cache key */ export declare function getExportParseCacheKey(digest: string, parserFlavor?: string): string; /** * Derive a stable parser flavor from a file name. * @param fileName The file name * @returns A lowercased extension-like parser flavor */ export declare function getParserFlavorFromFileName(fileName: string): string; /** * Get the TypeScript script kind for a file path. * @param fileName The file name * @returns The TypeScript script kind */ export declare function getScriptKindForPath(fileName: string): ts.ScriptKind; /** * Get the canonical surface (signature) of a TypeScript node. * This extracts the public API signature without implementation details. */ export declare function getCanonicalSurface(node: ts.Node, sourceFile: ts.SourceFile, printer: ts.Printer): string; /** * Get deprecation info from a TypeScript node. */ export declare function getDeprecatedInfo(node: ts.Node, sourceFile?: ts.SourceFile): DeprecatedInfo | null; /** * Check if a node has the export modifier. */ export declare function hasExportModifier(node: ts.Node): boolean; /** * Check if a node has the default modifier. */ export declare function hasDefaultModifier(node: ts.Node): boolean; /** * Get binding identifiers from a binding pattern. */ export declare function getBindingIdentifiers(node: ts.BindingName): string[]; /** * Scan exports from a file using the TypeScript AST. * Returns a map of export name to ExportItem. */ export declare function scanModuleExports(fileName: string, content: string, options?: ScanModuleExportsOptions): Map; /** * Calculates string similarity using Dice Coefficient on bigrams. */ export declare function getDiceSimilarity(str1: string, str2: string): number; /** * Check if a file path is under a scope directory. */ export declare function isUnderScope(file: string, scope: string | string[]): boolean; /** * Check if a path looks like a file path (has an extension). */ export declare function looksLikeFilePath(path: string): boolean; /** Base change record with commit information. */ export interface ChangeBase { sha: string; unix: number; date: string; release?: string; } /** Maps for comparing exports between commits. */ export interface ExportComparisonMaps { previousById: Map; currentById: Map; previousNamesById: Map>; } /** Build maps for comparing exports between two commit states. */ export declare function buildExportComparisonMaps(previousExports: Map>, currentExports: Map>): ExportComparisonMaps; /** * Rename pair detected between exports. */ export interface RenamePair { addedId: string; oldId: string; score: number; } export interface DetectSameFileRenamesOptions { previousById: Map; currentById: Map; removedIds: string[]; thresholdDice?: number; /** Pre-grouped added/removed by file. If provided, grouping is skipped. */ preGrouped?: { byFileAdded: Map; byFileRemoved: Map; }; /** Files where a lower threshold applies (e.g. git-renamed files). */ renamedFileGroups?: Set; renamedFileThreshold?: number; /** Margin required between best and second-best candidates. */ marginThreshold?: number; } /** * Detect same-file renames by comparing signature similarity. * Returns a map of new ID -> { oldId } for detected renames. */ export declare function detectSameFileRenames(previousById: Map, currentById: Map, removedIds: string[], thresholdDice?: number): { renamePairs: Map; usedRemovedIds: Set; }; export declare function detectSameFileRenames(options: DetectSameFileRenamesOptions): { renamePairs: Map; usedRemovedIds: Set; }; /** * Merge rename history from old ID to new ID in the exports record. * When both histories exist, they are concatenated (old first, then new). */ export declare function mergeRenameHistory(exports: Record, newId: string, oldId: string): T[]; /** * Detect cross-file renames by matching body+signature hashes. * Uses path similarity for tie-breaking when multiple candidates exist. */ export declare function detectCrossFileRenames(previousById: Map, currentById: Map, removedIds: string[], usedRemovedIds: Set, renamePairs: Map, pathDiceMin?: number, marginThreshold?: number): void; /** * Detect re-export moves where the same public export name resolves to a * different defining file between commits. This catches cases where a barrel * file (or re-export chain) is reorganized, causing the same export to be * traced to a different origin file even though the public API is unchanged. * * For example, if `timerGlobal` was re-exported from `TimerNode.js` and is * now re-exported from `Timer.js`, this should be treated as a move rather * than a separate remove + add. * * Must run AFTER other rename detection passes (git renames, signature * matching, cross-file hash matching) to only catch what they missed. */ export declare function detectSameNameMoves(previousExports: Map>, currentExports: Map>, previousById: Map, currentById: Map, removedIds: string[], usedRemovedIds: Set, renamePairs: Map): void; /** * Check if an oscillation should be collapsed (Added followed by Removed or vice versa * within the same release). * Returns true if the oscillation was collapsed (last entry was removed from history). */ export declare function checkAndCollapseOscillation(history: T[], changeKind: 'Added' | 'Removed', changeRelease: string | undefined): boolean; /** * Returns `true` if the module's exports consist exclusively of * re-exports from relative paths (i.e. it is a barrel file). */ export declare function isBarrelFile(rawExports: Map): boolean; /** * Selects entry files from a directory by checking for: * * 1. Index file candidates (`index.ts`, `index.tsx`, etc.) * 2. Files named after the directory (e.g. `Foo.ts` in a `foo/` directory) * 3. Barrel files (modules that only re-export from relative paths) */ export declare function selectEntryFiles(options: { scopeDirectory: string; entries: DirectoryEntry[]; readContent: (path: string) => Promise; }): Promise; export {};