Created
May 25, 2023 08:40
-
-
Save johandalabacka/d3381f1c53e1fd6d8102a11dc5232c28 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* @param {Response} response | |
* @returns {any} | |
*/ | |
async function _fetchBody (response) { | |
const contentType = response.headers.get('content-type') | |
if (contentType === 'application/json') { | |
return await response.json() | |
} else if (contentType.includes('text')) { | |
return await response.text() | |
} else { | |
return await response.blob() | |
} | |
} | |
class FetchAxiosError extends Error { | |
constructor (message, response) { | |
super(message) | |
this.response = response | |
} | |
} | |
class FetchAxios { | |
constructor ({ baseURL = '', params, auth, headers } = {}) { | |
this.baseURL = baseURL | |
this.params = params | |
this.headers = headers | |
this.auth = auth?.username && auth?.password ? btoa(`${auth.username}:${auth.password}`) : null | |
} | |
_getUrl (url, params) { | |
/** | |
* @type {URLSearchParams?} combinedParams | |
*/ | |
let combinedParams = null | |
if (this.params || params) { | |
combinedParams = URLSearchParams({ ...this.params, ...params }) | |
} | |
let finalUrl = this.baseURL + url | |
if (combinedParams) { | |
finalUrl = finalUrl + '?' + combinedParams.toString() | |
} | |
return finalUrl | |
} | |
_getHeaders (headers) { | |
const combinedHeaders = { ...this.headers, ...headers } | |
if (this.auth) { | |
combinedHeaders.Authorization = `Basic ${this.auth}` | |
} | |
if (!combinedHeaders.Accept) { | |
combinedHeaders.Accept = 'application/json' | |
} | |
return combinedHeaders | |
} | |
async get (url, options = {}) { | |
const combinedOptions = { method: 'GET' } | |
const combinedUrl = this._getUrl(url, options.params) | |
combinedOptions.headers = this._getHeaders(options.headers) | |
const response = await fetch(combinedUrl, combinedOptions) | |
response.data = await _fetchBody(response) | |
if (!response.ok) { | |
throw new FetchAxiosError(`${response.status} - ${response.statusText}`, response) | |
} | |
return response | |
} | |
async post (url, payload, options) { | |
/** | |
* @type {Request} input | |
*/ | |
const combinedOptions = { method: 'POST' } | |
const combinedUrl = this._getUrl(url, options.params) | |
combinedOptions.headers = this._getHeaders(options.headers) | |
const response = await fetch(combinedUrl, combinedOptions) | |
response.data = _fetchBody(response) | |
if (!response.ok) { | |
throw new FetchAxiosError(`${response.status} - ${response.statusText}`, response) | |
} | |
return response | |
} | |
} | |
module.exports = { | |
client: new FetchAxios(), | |
FetchAxios, | |
FetchAxiosError, | |
create (options) { | |
return new FetchAxios(options) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment