Skip to content

Instantly share code, notes, and snippets.

@doasync
Last active September 3, 2020 12:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doasync/89de08806e8b428a1781985272611a05 to your computer and use it in GitHub Desktop.
Save doasync/89de08806e8b428a1781985272611a05 to your computer and use it in GitHub Desktop.
fry with interceptors
'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