<commit_before>import fetch from 'isomorphic-fetch';
import Promise from 'promise-polyfill';
import {
  forEach,
  merge
} from 'lodash';

import { getStorageItem } from './storage';

/**
 * Which actions are allowed without authentication
 * @type {[*]}
 */
const ALLOWED_METHODS_WITHOUT_AUTHENTICATION = ['GET'];

// Add Promise to window if not supported...
if (!window.Promise) {
  window.Promise = Promise;
}

/**
 *
 * @param endpoint
 * @param params
 * @param options
 * @returns {*}
 */
export function get (endpoint, params = {}, options = {}) {
  return callApi(endpoint, params, options);
}

/**
 *
 * @param endpoint
 * @param data
 * @param params
 * @param options
 * @returns {*}
 */
export function post (endpoint, data, params = {}, options = {}) {
  if (typeof data !== 'string') {
    data = JSON.stringify(data);
    options.headers = merge(
      { 'Content-Type': 'application/json' },
      options.headers
    );
  }
  return callApi(endpoint, params, merge({ body: data, method: 'POST' }, options));
}

/**
 *
 * @param endpoint
 * @param data
 * @param params
 * @param options
 * @returns {*}
 */
export function put (endpoint, data, params = {}, options = {}) {
  if (typeof data !== 'string') {
    data = JSON.stringify(data);
    options.headers = merge(
      { 'Content-Type': 'application/json' },
      options.headers
    );
  }
  return callApi(endpoint, params, merge({ body: data, method: 'PUT' }, options));
}

/**
 *
 * @param endpoint
 * @param params
 * @param options
 * @returns {*}
 */
export function del (endpoint, params = {}, options = { method: 'DELETE' }) {
  return callApi(endpoint, params, options);
}

/**
 *
 * @param endpoint
 * @param params
 * @param options
 * @returns {*}
 */
export function callApi (endpoint, params, options = {}) {
  const token = getStorageItem('token');
  const defaultHeaders = new Headers();
  const url = getApiUrl(endpoint, params);
  const finalOptions = merge({
    method: 'GET',
    credentials: 'include',
    mode: 'cors'
  }, options);

  defaultHeaders.append('Accept', 'application/json');

  if (!token && ALLOWED_METHODS_WITHOUT_AUTHENTICATION.indexOf(finalOptions.method) !== 0) {
    throw Error(`Following methods for API-endpoint require authentication: ${ALLOWED_METHODS_WITHOUT_AUTHENTICATION.join(', ')}`);
  }

  if (token) {
    defaultHeaders.append('Authorization', `JWT ${token}`);
  }

  if (options.headers) {
    Object.keys(options.headers).map(key => {
      defaultHeaders.append(key, options.headers[key]);
    });
  }

  finalOptions.headers = defaultHeaders;
  return fetch(url, finalOptions);
}

/**
 *
 * @param url
 * @param query
 * @returns {string}
 */
export function getApiUrl (url, query = {}) {
  const queryString = buildQueryString(query);
  return [API_URL, API_VERSION, url, queryString].join('/');
}

/**
 *
 * @param query
 * @returns {string}
 */
export function buildQueryString (query) {
  const pairs = [];

  forEach(query, (value, key) => {
    pairs.push([key, value].join('='));
  });

  return pairs.length ? '?' + pairs.join('&') : '';<commit_msg>Fix navigation-not-loading bug due to expired token. Note! Just a quick’n ugly fix untill the refresh-token is implemented.<commit_after>import fetch from 'isomorphic-fetch';
import Promise from 'promise-polyfill';
import {
  forEach,
  merge
} from 'lodash';

import { getStorageItem, removeStorageItem } from './storage';

/**
 * Which actions are allowed without authentication
 * @type {[*]}
 */
const ALLOWED_METHODS_WITHOUT_AUTHENTICATION = ['GET'];

// Add Promise to window if not supported...
if (!window.Promise) {
  window.Promise = Promise;
}

/**
 *
 * @param endpoint
 * @param params
 * @param options
 * @returns {*}
 */
export function get (endpoint, params = {}, options = {}) {
  return callApi(endpoint, params, options);
}

/**
 *
 * @param endpoint
 * @param data
 * @param params
 * @param options
 * @returns {*}
 */
export function post (endpoint, data, params = {}, options = {}) {
  if (typeof data !== 'string') {
    data = JSON.stringify(data);
    options.headers = merge(
      { 'Content-Type': 'application/json' },
      options.headers
    );
  }
  return callApi(endpoint, params, merge({ body: data, method: 'POST' }, options));
}

/**
 *
 * @param endpoint
 * @param data
 * @param params
 * @param options
 * @returns {*}
 */
export function put (endpoint, data, params = {}, options = {}) {
  if (typeof data !== 'string') {
    data = JSON.stringify(data);
    options.headers = merge(
      { 'Content-Type': 'application/json' },
      options.headers
    );
  }
  return callApi(endpoint, params, merge({ body: data, method: 'PUT' }, options));
}

/**
 *
 * @param endpoint
 * @param params
 * @param options
 * @returns {*}
 */
export function del (endpoint, params = {}, options = { method: 'DELETE' }) {
  return callApi(endpoint, params, options);
}

/**
 *
 * @param endpoint
 * @param params
 * @param options
 * @returns {*}
 */
export function callApi (endpoint, params, options = {}) {
  const token = getStorageItem('token');
  const defaultHeaders = new Headers();
  const url = getApiUrl(endpoint, params);
  const finalOptions = merge({
    method: 'GET',
    credentials: 'include',
    mode: 'cors'
  }, options);

  defaultHeaders.append('Accept', 'application/json');

  if (!token && ALLOWED_METHODS_WITHOUT_AUTHENTICATION.indexOf(finalOptions.method) !== 0) {
    throw Error(`Following methods for API-endpoint require authentication: ${ALLOWED_METHODS_WITHOUT_AUTHENTICATION.join(', ')}`);
  }

  if (token) {
    defaultHeaders.append('Authorization', `JWT ${token}`);
  }

  if (options.headers) {
    Object.keys(options.headers).map(key => {
      defaultHeaders.append(key, options.headers[key]);
    });
  }

  finalOptions.headers = defaultHeaders;
  return fetch(url, finalOptions)
    .then(res => {
      // TODO: Remove me & use refresh token
      if (res.status === 401) {
        removeStorageItem('token');
        return window.location.reload();
      }
      return res;
    });
}

/**
 *
 * @param url
 * @param query
 * @returns {string}
 */
export function getApiUrl (url, query = {}) {
  const queryString = buildQueryString(query);
  return [API_URL, API_VERSION, url, queryString].join('/');
}

/**
 *
 * @param query
 * @returns {string}
 */
export function buildQueryString (query) {
  const pairs = [];

  forEach(query, (value, key) => {
    pairs.push([key, value].join('='));
  });

  return pairs.length ? '?' + pairs.join('&') : '';
{'fraction_non_alphanumeric': 0.16704980842911876, 'fraction_numerical': 0.0007662835249042146, 'mean_word_length': 3.599013389711064, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5767128', 'n_tokens_mistral': 2011, 'n_tokens_neox': 1994, 'n_words': 525}