import {readFile} from 'node:fs/promises'; export const origin='https://datoka-hooks-test.bhazarstudio.workers.dev'; export async function inputs(args=process.argv.slice(2)) { const [accessFile,eventId,payloadFile]=args; if(!accessFile||!payloadFile||!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(eventId??''))throw new Error('usage: node examples/send-http.mjs ACCESS_FILE STABLE_EVENT_ID PAYLOAD_FILE'); const access=JSON.parse(await readFile(accessFile,'utf8')); if(access.origin&&access.origin!==origin)throw new Error('unexpected_origin'); if(!/^pub-[a-f0-9]{32}$/.test(access.hookId??'')||!/^[a-f0-9]{64}$/.test(access.token??''))throw new Error('invalid_access_file'); const body=await readFile(payloadFile);if(body.length>65536)throw new Error('body_too_large'); JSON.parse(body.toString('utf8')); return {access,eventId,body}; } export async function sendHttp({access,eventId,body},request=fetch) { const response=await request(`${origin}/v1/hooks/${access.hookId}/events`,{method:'POST',redirect:'error',signal:AbortSignal.timeout(20000),headers:{authorization:'Bearer '+access.token,'content-type':'application/json','x-datoka-event-id':eventId},body}); // HTTP 202 means acceptance. A network error is safe to retry with the same // event ID and unchanged file; never generate a new ID to retry this command. if(!response.ok)throw new Error('hooks_http_'+response.status); return response.json(); } export function summary(data){return {deliveryId:data.deliveryId,state:data.state,attempts:data.attempts};}