Last active
September 3, 2020 12:13
-
-
Save doasync/89de08806e8b428a1781985272611a05 to your computer and use it in GitHub Desktop.
fry with interceptors
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
'use strict'; | |
const queryString = (params) => { | |
const qs = String(new URLSearchParams(params)); | |
return qs ? `?${qs}` : ""; | |
}; | |
const joinBase = (url, baseUrl) => | |
`${baseUrl.replace(/\/$/, "")}/${url.replace(/^\/|\/$/, "")}/`; | |
const contentTypeJson = { "Content-Type": "application/json" }; | |
const createRequest = (baseConfig, { | |
onBeforeRequest, | |
onRequestError, | |
onBeforeResponse, | |
onResponseError | |
}) => async (customConfig) => { | |
if (typeof customConfig === 'string') { | |
customConfig = { url: customConfig } | |
} | |
let promise = Promise.resolve(); | |
let config = { ...baseConfig, ...customConfig }; | |
if (onBeforeRequest) { | |
try { | |
config = await onBeforeRequest(config) | |
} catch (error) { | |
promise = Promise.reject(error) | |
} | |
} | |
const { baseUrl, url, data, params, fn, silent, ...init } = config; | |
const resource = `${joinBase(url, baseUrl)}${queryString(params)}`; | |
if (data) { | |
Object.assign(init, { | |
headers: { ...contentTypeJson, ...config.headers }, | |
body: JSON.stringify(data), | |
}); | |
} | |
const request = new Request(resource, init); | |
const handleRequestErrors = async (response) => { | |
if (!response.ok) { | |
let error = Error(response.statusText); | |
Object.assign(error, { config, request, response, resource, baseConfig }); | |
if (onResponseError) { | |
return onResponseError(error) | |
} | |
return Promise.reject(error) | |
} | |
return response; | |
}; | |
return promise | |
.then(() => fetch(request)) | |
.catch(onRequestError ?? (error => Promise.reject(error))) | |
.then(onBeforeResponse ?? (response => response)) | |
.then(!silent ? handleRequestErrors : (response => response)) | |
.then(async (response) => { | |
let jsonData; | |
try { | |
jsonData = await response.json(); | |
} catch (error) {} | |
return fn | |
? fn({ config, request, response, resource, baseConfig, jsonData }) | |
: jsonData; | |
}); | |
}; | |
const request = createRequest(); | |
module.exports = { request, createRequest }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment