diff --git a/src/util/Util.js b/src/util/Util.js index 00c8063..494b768 100644 --- a/src/util/Util.js +++ b/src/util/Util.js @@ -17,6 +17,67 @@ class Util { }); } + static async #parseResponse (response) { + const { headers: rawHeaders, status } = response; + // Fetch returns heders as an interable for some reason + const headers = [ ...rawHeaders ].reduce((acc, [ key, val ]) => { + acc[key.toLowerCase()] = val; + return acc; + }, {}); + const success = status >= 200 && status < 300; + const base = { success, status }; + + if (headers['content-type']?.includes('application/json')) { + const data = await response.json(); + return { ...base, data }; + } + return { ...base, message: await response.text() }; + } + + static #params (params) { + return `${Object.entries(params) + .filter(([ , v ]) => Boolean(v)) + .map(([ k, v ]) => `${encodeURI(k)}=${encodeURI(v)}`) + .join('&')}`; + } + + static async get (url, options = {}) { + + const { params, ...rest } = options; + if (params) url = Util.#params(url, params); + + const response = await fetch(url, { ...rest }); + return Util.#parseResponse(response); + + } + + static async post (url, options = {}) { + + // eslint-disable-next-line prefer-const + let { params, body, ...rest } = options; + if (params) url += '?' + Util.#params(params); + + if (rest.headers) { + const headers = Object.keys(rest.headers); + const contentType = headers.find((k) => k.toLowerCase() === 'content-type'); + + if (contentType) { + const value = rest.headers[contentType].toLowerCase(); + + if (value === 'application/json' && typeof body !== 'string') { + body = JSON.stringify(body); + } else if (value === 'application/x-www-form-urlencoded') { + if (body) body = Util.#params(body); + } + + } + } + + const response = await fetch(url, { ...rest, body, method: 'post' }); + return Util.#parseResponse(response); + + } + static checkPermissions (perms, perm, level = 1) { if (!perms || typeof perms !== 'object') throw new Error('Missing perms object');