import crypto from 'node:crypto'; export function createImgproxySigner(key, salt) { const keyBuf = Buffer.from(key, 'hex'); const saltBuf = Buffer.from(salt, 'hex'); function signPath(path) { const signaturePayload = Buffer.concat([saltBuf, Buffer.from(path)]); const signature = crypto.createHmac('sha256', keyBuf).update(signaturePayload).digest(); const signatureB64 = signature.toString('base64url'); return `/${signatureB64}${path}`; } function buildUrl(baseUrl, storagePath, preset = 'display') { if (!baseUrl || !storagePath) { throw new Error('baseUrl and storagePath are required'); } let width, height, quality, format; switch (preset) { case 'vision': width = 768; height = 768; quality = 60; format = 'jpg'; break; case 'thumb': width = 256; height = 256; quality = 70; format = 'jpg'; break; case 'display': default: width = 1280; height = 1280; quality = 85; format = 'jpg'; break; } const unsignedPath = `/rs:fit:${width}:${height}:0/q:${quality}/plain/local:///${storagePath}@${format}`; const signedPath = signPath(unsignedPath); const baseUrlNormalized = String(baseUrl).replace(/\/$/, ''); return `${baseUrlNormalized}${signedPath}`; } return { buildUrl, signPath }; } export default createImgproxySigner;