import * as fs from 'fs'; import type { IgnoreStrategy } from './ignore'; import { SymlinkFollowMode } from './options'; export declare function isInternalPath(rootPath: string, targetPath: string): boolean; export declare function resolveLinkTarget(realPath: string, linkTarget: string): string; export interface WalkEntry { /** * Where the entry sits in the tree * * If a symlink was followed to get here, this path goes through the symlink rather * than through the target it points at. */ readonly path: string; /** * The path to read this entry's content from * * Same as `path`, unless a symlink was followed, in which case it is the link's target. */ readonly realPath: string; } /** * A directory whose contents are about to be walked */ export interface WalkDirectoryEntry extends WalkEntry { /** * Whether the directory itself is excluded by the ignore strategy * * The walk still descends into it, because a pattern that excludes a directory can * re-include files underneath it. A directory that is excluded along with everything * inside it is skipped and never reported at all. */ readonly ignored: boolean; } /** * A file, or a symlink that was followed to one */ export interface WalkFileEntry extends WalkEntry { /** * Stats of a followed symlink's target * * Only set when the walk already had to stat the target, so callers that need stats can * use these instead of calling `stat` again. */ readonly stats?: fs.BigIntStats; } /** * A symlink that is being kept as a link rather than followed */ export interface WalkSymlinkEntry extends WalkEntry { /** * The link target exactly as written, which is what gets copied or hashed */ readonly linkTarget: string; /** * `linkTarget` resolved against the link's own directory */ readonly resolvedLinkTarget: string; /** * Whether the target is inside the walk root */ readonly internal: boolean; } /** * Receives the entries that a walk includes in its result * Every callback is optional, so a visitor only implements the entry kinds it cares * about. Entries excluded by the ignore strategy are never reported. */ export interface WalkVisitor { /** * A file, or a symlink that was followed to a file */ onFile?(entry: WalkFileEntry): void; /** * A directory, or a symlink that was followed to a directory */ onDirectory?(entry: WalkDirectoryEntry): void; /** * A symlink that is not being followed */ onSymlink?(entry: WalkSymlinkEntry): void; /** * A followed symlink whose target is neither a file nor a directory * * For example a socket, a named pipe or a device node. */ onUnsupported?(entry: WalkEntry): void; } /** * Options for `walkDirectory` */ export interface WalkOptions { /** * What to do with the symlinks encountered along the way */ readonly follow: SymlinkFollowMode; /** * Which entries to leave out of the walk */ readonly ignoreStrategy: IgnoreStrategy; /** * The tree a symlink has to point inside of to count as internal * * @default - the directory being walked */ readonly root?: string; } /** * Walk a directory tree, reporting the entries that belong in its result * * Fingerprinting, copying and symlink validation all share this traversal, so all three * agree on what an asset contains: how the ignore strategy is applied, which symlinks are * followed, and how a link target is resolved. Those decisions are made here; callers only * decide what to do with an entry. * * Entries are visited in sorted order, so a caller that hashes the entries it is given * gets the same hash every time. */ export declare function walkDirectory(directory: string, options: WalkOptions, visitor: WalkVisitor): void;