import type { BufferSource } from 'node:stream/web'; import { sha256Base64 } from '../signing/hashing.js'; import { sha256Object } from '../signing/index.js'; import unreachable from '../utils/unreachable.js'; import type { DirectoryEntry } from './types.js'; export async function hashFileContents(contents: string | BufferSource): Promise { return sha256Base64(contents); } function compareFilenames(str1: string, str2: string): number { // JS does string comparison in UTF-16 code units, which might be hard to replicate in other systems. // A better approach is to sort by unicode code points. One way to do this is to convert the strings // to their UTF-8 representation and compare the bytes. This is equivalent to comparing the unicode // code points as it is one of the properties of UTF-8. // Note: this code uses node.js specific APIs return Buffer.from(str1).compare(Buffer.from(str2)); } function normalizeEntryForHashing(entry: DirectoryEntry) { switch (entry.type) { case '-': return { type: '-', name: entry.name, executable: entry.executable, hash: entry.hash }; case 'd': return { type: 'd', name: entry.name, hash: entry.hash }; case 'l': return { type: 'l', name: entry.name, target: entry.target }; default: unreachable(entry); } } export async function hashDirectoryContents(contents: DirectoryEntry[]): Promise { const normalizedContents = contents.map(normalizeEntryForHashing).sort((a, b) => compareFilenames(a.name, b.name)); return await sha256Object(normalizedContents); }