export type ListDir = (dir: string) => Promise export type ReadFile = (path: string) => Promise function toBase64(u8: Uint8Array): string { if (typeof Buffer !== 'undefined') return Buffer.from(u8).toString('base64') throw new Error('Buffer not available') } // Generate inputs for verify CLI from a folder tree. // - root: export folder (contains assets.integrity.index.json and assets/*) // - listDir: returns list of file paths under root (can be recursive listing) // - readFile: reads a file into bytes export async function generateVerifyInputs( root: string, listDir: ListDir, readFile: ReadFile ): Promise<{ extras: Record; assets: Record }> { const all = await listDir(root) const norm = (p: string) => p.replace(/\\/g, '/') const rootNorm = norm(root).replace(/\/$/, '') const rel = (p: string) => { const pn = norm(p) return pn.startsWith(rootNorm + '/') ? pn.slice(rootNorm.length + 1) : pn } const extras: Record = {} const assets: Record = {} // assets.integrity.index.json at root const integrityPath = all.find((p) => rel(p) === 'assets.integrity.index.json') if (integrityPath) { const bytes = await readFile(integrityPath) extras['assets.integrity.index.json'] = toBase64(bytes) } // collect assets/**/* for (const abs of all) { const r = rel(abs) if (!r.startsWith('assets/')) continue // skip directories: best-effort by checking trailing slash if (r.endsWith('/')) continue const bytes = await readFile(abs) assets[r] = toBase64(bytes) } return { extras, assets } }