UNPKG

@folklore/fetch

Version:
149 lines (138 loc) 3.68 kB
'use strict'; var Cookies = require('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; }; exports.ResponseError = ResponseError; exports.ValidationError = ValidationError; exports.getCSRFHeaders = getCSRFHeaders; exports.getCsrfToken = getCsrfToken; exports.getJSON = getJSON; exports.getResponseAndDataObject = getResponseAndDataObject; exports.getXSRFToken = getXSRFToken; exports.postJSON = postJSON; exports.throwResponseError = throwResponseError; exports.throwValidationError = throwValidationError; exports.uploadFile = uploadFile;