UNPKG

matterbridge-webhooks

Version:
73 lines (72 loc) 2.79 kB
import http from 'node:http'; import https from 'node:https'; export async function fetch(url, method = 'GET', data = {}, timeout = 5000) { return new Promise((resolve, reject) => { const controller = new AbortController(); const timeoutId = setTimeout(() => { controller.abort(); reject(new Error(`Request timed out after ${timeout / 1000} seconds`)); }, timeout).unref(); let requestUrl = url; const jsonData = JSON.stringify(data); if (method === 'GET') { const queryParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => { if (value === null) { acc[key] = ''; } else if (typeof value === 'object') { acc[key] = JSON.stringify(value); } else { acc[key] = String(value); } return acc; }, {})).toString(); if (queryParams) { const separator = url.includes('?') ? '&' : '?'; requestUrl = `${url}${separator}${queryParams}`; } } const options = { method, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', ...(method === 'POST' && { 'Content-Length': Buffer.byteLength(jsonData) }), }, signal: controller.signal, }; const protocol = url.startsWith('https') ? https : http; const req = protocol.request(requestUrl, options, (res) => { res.setEncoding('utf8'); let responseData = ''; if (res.statusCode && res.statusCode >= 300) { clearTimeout(timeoutId); res.resume(); req.destroy(); reject(new Error(`Request failed with status code: ${res.statusCode}`)); } res.on('data', (chunk) => { responseData += chunk; }); res.on('end', () => { clearTimeout(timeoutId); try { const jsonResponse = JSON.parse(responseData); resolve(jsonResponse); } catch (err) { reject(new Error(`Failed to parse response JSON: ${err instanceof Error ? err.message : err}`)); } }); }); req.on('error', (error) => { clearTimeout(timeoutId); reject(new Error(`Request failed: ${error instanceof Error ? error.message : error}`)); }); if (method === 'POST') { req.write(jsonData); } req.end(); }); }