File Hash Manifest

Build a sorted SHA-256 manifest of file contents so unchanged inputs can be skipped and integrity verified.

TypescriptCli Tooling

Code

snippet
import { createHash } from 'node:crypto';
import { readFile, readdir } from 'node:fs/promises';
import { join } from 'node:path';

export async function hashFile(path: string): Promise<string> {
  const content = await readFile(path);
  return 'sha256:' + createHash('sha256').update(content).digest('hex');
}

export async function buildManifest(root: string): Promise<Array<{ path: string; hash: string }>> {
  const entries = await readdir(root, { withFileTypes: true });
  const files = entries.filter((e) => e.isFile()).map((e) => e.name).sort();
  const manifest: Array<{ path: string; hash: string }> = [];
  for (const name of files) {
    manifest.push({ path: name, hash: await hashFile(join(root, name)) });
  }
  return manifest;
}

export function manifestUnchanged(a: readonly { path: string; hash: string }[], b: readonly { path: string; hash: string }[]): boolean {
  if (a.length !== b.length) return false;
  return a.every((entry, i) => {
    const other = b[i];
    return other !== undefined && entry.path === other.path && entry.hash === other.hash;
  });
}