/** * Split a Zapier/middleware request into chain vs archive parts. * @module splitRequest */ import { createHash } from 'node:crypto'; /** * @param {string} data * @returns {string} */ export function sha256Hex(data) { return createHash('sha256').update(String(data), 'utf8').digest('hex'); } /** * @param {object} body * @returns {{ * chain: { sha256: string, hashAlg: string, data?: string }, * archivePuts: Array<{ kind: string, sha256: string, record: object }>, * includeAttached: boolean * }} */ export function splitRequest(body = {}) { const sha256 = (body.sha256 || (body.data != null ? sha256Hex(body.data) : '')).toLowerCase(); if (!sha256) { throw new Error('data or sha256 is required'); } const includeAttached = Boolean(body.includeAttached); const archivePuts = []; if (body.publicMetadata && Object.keys(body.publicMetadata).length) { archivePuts.push({ kind: 'publicMeta', sha256, record: { publicMetadata: body.publicMetadata }, }); } if (body.privateMetadata && Object.keys(body.privateMetadata).length) { archivePuts.push({ kind: 'privateMeta', sha256, record: { privateMetadata: body.privateMetadata }, }); } const files = Array.isArray(body.files) ? body.files : []; for (const f of files) { const bytes = f.contentBase64 ? Buffer.from(String(f.contentBase64), 'base64') : Buffer.from(String(f.data ?? ''), 'utf8'); const fileHash = sha256Hex(bytes); archivePuts.push({ kind: 'file', sha256, record: { path: f.path || f.filename || 'file.bin', size: bytes.length, contentSha256: fileHash, contentBase64: bytes.toString('base64'), }, }); } return { chain: { sha256, hashAlg: body.hashAlg || 'SHA256', data: body.data, }, archivePuts, includeAttached, }; }