import { address } from './APIAddress' // User Session Token let defaultToken = 'empty token' // CRUD methods /** * get list method * @param {string} endpoint - for example `user/` */ const _getList = async (endpoint) => { return await responseGD(address + endpoint, 'GET', defaultToken) } /** * get one row / record * @param {string} endpoint - for example `user/` */ const _getOne = async (endpoint) => { return await responseGD(address + endpoint, 'GET', defaultToken) } /** * universal post method * @param {string} endpoint - for example `user/` * @param {{}} body - body request * @param {string} token - token for verify user in API */ const _post = async (endpoint, body, token) => { return await responseCRU(address + endpoint, 'POST', body, token) } /** * universal put method * @param {string} endpoint - for example `user/{id}/` where {id} is object id * @param {{}} body - body request * @param {string} token - token for verify user in API */ const _put = async (endpoint, body, token) => { return await responseCRU(address + endpoint, 'PUT', body, token) } /** * universal patch method * @param {string} endpoint - for example `user/{id}/` where {id} is object id * @param {{}} body - body request * @param {string} token - token for verify user in API */ const _patch = async (endpoint, body, token) => { return await responseCRU(address + endpoint, 'PATCH', body, token) } /** * universal delete method * @param {string} endpoint - for example `user/{id}/` where {id} is object id * @param {string} token - token for verify user in API */ const _delete = async (endpoint, token) => { return await responseGD(address + endpoint, 'DELETE', token) } // Utils // Fetch methods /** * fetch `get` / `delete` type methods * @param {string} address - full endpoint address * @param {string} method - method like `get` / `delete` * @param {string} token - token for verify user in API */ const responseGD = async (address, method, token) => { try { const response = await fetch(address, { method: method, credentials: 'same-origin', headers: { "Authorization": token, "X-CSRFToken": csrftoken, "accept": "application/json", "Content-Type": "application/json" } }) return await responseExceptions( await response.json(), response.status ) } catch (error) { return { info: error } } } /** * fetch `post` / `put` / `patch` type methods * @param {string} address - full endpoint address * @param {string} method - method like `post` / `put` / `patch` * @param {{}} body - body of request * @param {string} token - token for verify user session in API */ const responseCRU = async (address, method, body, token) => { try { const response = await fetch(address, { method: method, credentials: 'same-origin', body: JSON.stringify(body), headers: { "Authorization": token, "X-CSRFToken": csrftoken, "accept": "application/json", "Content-Type": "application/json" } }) return await responseExceptions( await response.json(), response.status ) } catch (error) { return { info: error } } } /** * fetch bonus exceptions ( not blank fields in request / bad requests ) * @param {Response} response - response from fetch * @param {number} status - request status */ const responseExceptions = async (response, status) => { try { //progressStream( response ) if (status > 300) { let info = '' Object.keys(response).forEach(element => { if (element !== 'detail') info += element + ' - ' + response[element][0] else info += response[element] }) return { response: response, info: info } } else return { response: response, info: 'operation success' } } catch (error) { return { response: response, info: error } } } // Get CSRF Token /** * get cookie method for CSRF verification * @param {string} name - name of handled cookie */ const getCookie = (name) => { if (!document.cookie) { return null; } const token = document.cookie.split(';') .map(c => c.trim()) .filter(c => c.startsWith(name + '=')); if (token.length === 0) { return null; } return decodeURIComponent(token[0].split('=')[1]); } const csrftoken = getCookie('csrftoken') // Get progress stream /** * Fetch streaming (use in `then` statement) usefull for get request progress info * @param response - is a response from fetch */ export const progressStream = (response) => { const contentLength = response.headers.get('content-length') if (!contentLength) throw Error('Content-Length response header unavailable') const total = parseInt(contentLength, 10) let loaded = 0 return new Response( new ReadableStream({ start(controller) { const reader = response.body.getReader() read() function read() { reader.read() .then(({ done, value }) => { if (done) { controller.close() return } loaded += value.byteLength console.log(loaded / total * 100) controller.enqueue(value) read() }) .catch(error => { console.error(error) controller.error(error) }) } } }) ) } export default { _getList, _getOne, _post, _put, _patch, _delete, defaultToken, progressStream }