@folklore/fetch
Version:
Fetch utilities
137 lines (127 loc) • 3.4 kB
JavaScript
import Cookies from 'js-cookie';
class ResponseError extends Error {
constructor(message, responseData, status) {
super(message);
this.name = 'ResponseError';
this.responseData = responseData;
this.status = status;
}
getResponseData() {
return this.responseData;
}
}
class ValidationError extends ResponseError {
constructor(message, responseData, status) {
super(message, responseData, status);
this.name = 'ValidationError';
}
getErrors() {
return this.responseData;
}
}
const getResponseAndDataObject = response => response.json().then(data => ({
data,
response
}));
const throwResponseError = responseObject => {
const {
response,
data
} = responseObject;
if (response.status >= 200 && response.status < 300) {
return data;
}
throw new ResponseError(response.statusText, data, response.status);
};
const throwValidationError = error => {
if (error.name === 'ResponseError' && error.status === 422) {
throw new ValidationError(error.message, error.responseData, error.status);
}
throw error;
};
const getJSON = (url, opts) => {
const {
headers,
...options
} = opts || {};
return fetch(url, {
method: 'GET',
headers: {
Accept: 'application/json',
...(headers || null)
},
...(options || null)
}).then(getResponseAndDataObject).then(throwResponseError);
};
const postJSON = (url, data, opts) => {
const {
headers,
...options
} = opts || {};
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...(headers || null)
},
body: JSON.stringify(data),
...(options || null)
}).then(getResponseAndDataObject).then(throwResponseError).catch(throwValidationError);
};
const defaultOptions = {
headers: null,
fileParamName: 'file'
};
const uploadFile = (url, file, opts = null) => {
const {
headers,
fileParamName,
...options
} = {
...defaultOptions,
...opts
};
const formData = new FormData();
formData.append(fileParamName, file);
return fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
...headers
},
body: formData,
...(options || null)
}).then(getResponseAndDataObject).then(throwResponseError).catch(throwValidationError);
};
const getXSRFToken = (cookieName = null) => {
const cookies = Cookies.get();
return (cookieName !== null ? cookies[cookieName] : null) || cookies['XSRF-TOKEN'] || null;
};
const getCsrfToken = (name = null) => {
const metaName = name || 'csrf-token';
if (typeof document === 'undefined') {
return null;
}
const metas = [].slice.call(document.getElementsByTagName('meta'));
return metas.reduce((val, meta) => meta.getAttribute('name') === metaName ? meta.getAttribute('content') : val, null);
};
const getCSRFHeaders = ({
csrfMetaName = null,
xsrfCookieName = null
} = {}) => {
const XSRF = getXSRFToken(xsrfCookieName);
if (XSRF !== null) {
return {
'X-XSRF-TOKEN': XSRF
};
}
const CSRF = getCsrfToken(csrfMetaName);
if (CSRF !== null) {
return {
'X-CSRF-TOKEN': CSRF
};
}
return null;
};
export { ResponseError, ValidationError, getCSRFHeaders, getCsrfToken, getJSON, getResponseAndDataObject, getXSRFToken, postJSON, throwResponseError, throwValidationError, uploadFile };