import { DocHistoryData } from './types.js'; /** * True when the current working tree is inside a git repository. Public entry * points call this first and return empty results when it is false, so no git * command is spawned (and `getRepoRoot()` never throws) outside a repo. This is * what lets `pnpm dev` / `pnpm build` succeed in a project that has not been * `git init`-ed yet, instead of crashing the doc-history preBuild hook. */ declare function isGitRepo(): boolean; /** * Pure parser for `git log --follow --format=%H --name-only` output. * * git emits records with the structure: * <40-hex-hash>\n\n\n * where the blank line (`\n\n`) appears between the hash and the filepath — * it is git's commit separator emitted for every --format output even when * using the minimal %H format. Consecutive records are delimited by the * filepath of the previous record followed immediately by the next hash line * (single `\n` between them, not a blank line). * * Parsing strategy: scan line by line, using a state machine that transitions * from EXPECT_HASH → EXPECT_BLANK → EXPECT_PATH and back. The blank-line * state is the structural record boundary — it distinguishes the separator * git injects after each format output from ordinary non-hash lines. This * avoids the previous two-pass approach (collect all hashes → re-classify) * and is robust against file paths that happen to be 40-char hex strings. */ declare function parseHashToPathMap(output: string): Map; /** * Get the complete history for a document file. * * Optimised: uses ONE `git log --follow` for commit metadata AND ONE * `git log --follow --name-only` for the hash→path map, run in PARALLEL * via Promise.all (they are independent git walks). Then a single * `git cat-file --batch` for all content fetches. Falls back to * per-commit logic only for batch misses (renamed-path entries where the * current path didn't exist at that commit). * * Issues all git commands via execFile / spawn (non-blocking) so the CLI's * semaphore-bounded concurrency actually parallelizes across files (#1986). */ declare function getDocHistoryAsync(filePath: string, slug: string, maxEntries?: number): Promise; /** Oldest + newest author/date for a single current-path key. */ interface FirstLastMeta { /** The file's creation-side commit (author = page author, date = createdDate). */ oldest: { author: string; date: string; }; /** The file's most recent commit (date = updatedDate). */ newest: { author: string; date: string; }; } /** * Pure parser + rename reconstruction for the single-pass walk's stdout. * Keyed by CURRENT repo-relative path (exactly what git emits). Exported for * unit tests; the streaming walk uses the same accumulator incrementally. */ declare function parseFirstLastMeta(output: string): Map; /** * Walk the WHOLE git history ONCE and return `{oldest, newest}` author/date for * every current file, keyed by ABSOLUTE path (`/`) so a * consumer whose project root differs from the repo root still matches by the * absolute paths its content walker produced. * * ONE streaming `git log --full-history --name-status --find-renames -l0` * spawn, parsed incrementally (never execFile+maxBuffer — that reintroduced the * #2293 silent-truncation class — and never concat-all-then-parse, since a * full-history buffer can be large in arbitrary consumer repos). * * `-l0` is mandatory: a bulk `--name-status --find-renames` walk runs rename * detection per-commit under the global `diff.renameLimit`; a mass-rename commit * that hits the limit emits `D`+`A` instead of `R`, silently dropping pre-rename * history (wrong createdDate/author) where per-path `--follow` would find it. * * `--full-history` is required to MATCH per-file `--follow`: default history * simplification prunes commits on merged side-branches that are TREESAME to the * first parent, so a bounded directory walk would miss updates that `--follow` * (which effectively sees the full per-file history) reports. Without it, most * pages collapsed updatedDate onto createdDate. Merges still emit header-only * name-status under the default `--diff-merges`, so this does not double-count. * * `pathspecs` bound the walk to the content dirs (absolute or repo-relative; * absolute entries are converted to repo-relative like the other helpers). Pass * `[]` to walk full history. * * cwd = repo root (#1907). Returns an empty Map outside a git repo so callers * degrade to an empty manifest instead of crashing. */ declare function getAllFilesFirstLastMetaAsync(pathspecs?: string[]): Promise>; /** * Collect all MDX/md files in a content directory. * Returns array of { filePath, slug } pairs. */ declare function collectContentFiles(dir: string): Array<{ filePath: string; slug: string; }>; export { type FirstLastMeta, collectContentFiles, getAllFilesFirstLastMetaAsync, getDocHistoryAsync, isGitRepo, parseFirstLastMeta, parseHashToPathMap };