const TIMEOUT = process.browser ? 60000 : 120000 function fetchWithTimeout (url, options) { return new Promise((resolve, reject) => { fetch(url, options).then(resolve, reject) setTimeout(() => reject(new Error(`Timed out after ${TIMEOUT / 1000} seconds`)), TIMEOUT) }) } function makeOpts (method, headers) { return { method, headers: Object.assign(headers || {}, { 'Accept': 'application/json' }) } } async function throwErrorIfInvalidResponse (response) { let json = await response.json() if (response.status >= 200 && response.status < 300) { return json } if (json && json.error) { throw new Error(response.status + ': ' + json.error) } throw new Error('Request failed: ' + response.status) } async function _fetch (url, options, timeout) { let fetchFunc = timeout ? fetchWithTimeout : fetch let response = await fetchFunc(url, options) return throwErrorIfInvalidResponse(response) } async function _putOrPost (url, body, headers, timeout, method) { let opts = makeOpts(method, headers) if (body) { if (body instanceof FormData) { opts.body = body } else { opts.body = JSON.stringify(body) opts.headers['Content-Type'] = 'application/json' } } return _fetch(url, opts, timeout) } async function _post (url, body, headers, timeout) { return _putOrPost(url, body, headers, timeout, 'POST') } async function _put (url, body, headers, timeout) { return _putOrPost(url, body, headers, timeout, 'PUT') } async function _get (url, headers, timeout) { return _fetch(url, makeOpts('GET', headers), timeout) } async function _delete (url, headers, timeout) { return _fetch(url, makeOpts('DELETE', headers), timeout) } export async function put (url, body, headers) { return _put(url, body, headers, false) } export async function putWithTimeout (url, body, headers) { return _put(url, body, headers, true) } export async function post (url, body, headers) { return _post(url, body, headers, false) } export async function postWithTimeout (url, body, headers) { return _post(url, body, headers, true) } export async function getWithTimeout (url, headers) { return _get(url, headers, true) } export async function get (url, headers) { return _get(url, headers, false) } export async function deleteWithTimeout (url, headers) { return _delete(url, headers, true) } export function paramsString (paramsObject) { let res = '' Object.keys(paramsObject).forEach((key, i) => { if (i > 0) { res += '&' } res += encodeURIComponent(key) + '=' + encodeURIComponent(paramsObject[key]) }) return res }