text: const defaults = require('lodash.defaults');
  const xhr = require('xhr');
  
  const jar = require('./jar');
  const log = require('./log');
  const urlParams = require('./url-params');
  
  /**
   * Helper method that constructs requests to the scratch api.
   * Custom arguments:
   *     - useCsrf [boolean] – handles unique csrf token retrieval for POST requests. This prevents
   *       CSRF forgeries (see: https://www.squarefree.com/securitytips/web-developers.html#CSRF)
   *
   * It also takes in other arguments specified in the xhr library spec.
   *
   * @param  {object}   opts     optional xhr args (see above)
   * @param  {Function} callback [description]
   */
  module.exports = (opts, callback) => {
      defaults(opts, {
          host: process.env.API_HOST,
          headers: {
  
              authorization: 'token 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'
          },
          responseType: 'json',
          useCsrf: false
      });
  
      if (opts.host === '') {
          defaults(opts.headers, {
              'X-Requested-With': 'XMLHttpRequest'
          });
      }
  
      opts.uri = opts.host + opts.uri;
  
      if (opts.params) {
          opts.uri = [opts.uri, urlParams(opts.params)]
              .join(opts.uri.indexOf('?') === -1 ? '?' : '&');
      }
  
      if (opts.formData) {
          opts.body = urlParams(opts.formData);
          opts.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      }
  
      const apiRequest = options => {
          if (options.host !== '') {
              if ('withCredentials' in new XMLHttpRequest()) {
                  options.useXDR = false;
              } else {
                  // For IE < 10, we must use XDR for cross-domain requests. XDR does not support
                  // custom headers.
                  options.useXDR = true;
                  delete options.headers;
                  if (options.authentication) {
                      const authenticationParams = [`x-token=${options.authentication}`];
                      const parts = options.uri.split('?');
                      const qs = (parts[1] || '')
                          .split('&')
                          .concat(authenticationParams)
                          .join('&');
                      options.uri = `${parts[0]}?${qs}`;
                  }
              }
          }
          xhr(options, (err, res, body) => {
              if (err) log.error(err);
              if (options.responseType === 'json' && typeof body === 'string') {
                  // IE doesn't parse responses as JSON without the json attribute,
                  // even with responseType: 'json'.
                  // See https://github.com/Raynos/xhr/issues/123
                  try {
                      body = JSON.parse(body);
                  } catch (e) {
                      // Not parseable anyway, don't worry about it
                  }
              }
              // Legacy API responses come as lists, and indicate to redirect the client like
              // [{success: true, redirect: "/location/to/redirect"}]
              try {
                  if ('redirect' in body[0]) window.location = body[0].redirect;
              } catch (e) {
                  // do nothing
              }
              callback(err, body, res);
          });
      };
  
      if (typeof jar.get('scratchlanguage') !== 'undefined') {
          opts.headers['Accept-Language'] = `${jar.get('scratchlanguage')}, en;q=0.8`;
      }
      if (opts.authentication) {
          opts.headers['X-Token'] = opts.authentication;
      }
      if (opts.useCsrf) {
          jar.use('scratchcsrftoken', '/csrf_token/', (err, csrftoken) => {
              if (err) return log.error('Error while retrieving CSRF token', err);
              opts.headers['X-CSRFToken'] = csrftoken;
              apiRequest(opts);
          });
      } else {
          apiRequest(opts);
      }
  };
  