Code coverage report for lib/deps/ajax.js

Statements: 86.49% (64 / 74)      Branches: 84.85% (56 / 66)      Functions: 100% (7 / 7)      Lines: 86.49% (64 / 74)      Ignored: none     

All files » lib/deps/ » ajax.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146    1   1 1 1 1   1   21873 21873 21762     21762 21762     21873         21873   21873                 21873     1 17984     17984 12 12     12     17972 1760 4953 71   4882       17972   592   17972     1 15 15 15 15 15                         21873 21873 21273   21873       21873 600 600     21873 198     1 16     16     21873 21762 15 15     21747 21747 21747       21747       198     21747 17984   3763       3763   3763 3763 3763         1  
"use strict";
 
var request = require('request');
 
var buffer = require('./binary/buffer');
var errors = require('./errors');
var utils = require('../utils');
var isBrowser = typeof process === 'undefined' || process.browser;
 
function ajax(options, adapterCallback) {
 
  var requestCompleted = false;
  var callback = utils.getArguments(function (args) {
    Iif (requestCompleted) {
      return;
    }
    adapterCallback.apply(this, args);
    requestCompleted = true;
  });
 
  Iif (typeof options === "function") {
    callback = options;
    options = {};
  }
 
  options = utils.clone(options);
 
  var defaultOptions = {
    method : "GET",
    headers: {},
    json: true,
    processData: true,
    timeout: 10000,
    cache: false
  };
 
  options = utils.extend(true, defaultOptions, options);
 
 
  function onSuccess(obj, resp, cb) {
    Iif (!options.binary && !options.json && options.processData &&
      typeof obj !== 'string') {
      obj = JSON.stringify(obj);
    } else if (!options.binary && options.json && typeof obj === 'string') {
      try {
        obj = JSON.parse(obj);
      } catch (e) {
        // Probably a malformed JSON from server
        return cb(e);
      }
    }
    if (Array.isArray(obj)) {
      obj = obj.map(function (v) {
        if (v.error || v.missing) {
          return errors.generateErrorFromResponse(v);
        } else {
          return v;
        }
      });
    }
    if (!isBrowser && options.binary) {
      // non-standard buffer.type for consistency with the browser
      obj.type = resp.headers['content-type'];
    }
    cb(null, obj, resp);
  }
 
  function onError(err, cb) {
    var errParsed, errObj;
    Eif (err.code && err.status) {
      var err2 = new Error(err.message || err.code);
      err2.status = err.status;
      return cb(err2);
    }
    try {
      errParsed = JSON.parse(err.responseText);
      //would prefer not to have a try/catch clause
      errObj = errors.generateErrorFromResponse(errParsed);
    } catch (e) {
      errObj = errors.generateErrorFromResponse(err);
    }
    cb(errObj);
  }
 
 
  Eif (options.json) {
    if (!options.binary) {
      options.headers.Accept = 'application/json';
    }
    options.headers['Content-Type'] = options.headers['Content-Type'] ||
      'application/json';
  }
 
  if (options.binary) {
    options.encoding = null;
    options.json = false;
  }
 
  if (!options.processData) {
    options.json = false;
  }
 
  function defaultBody(data) {
    Iif (process.browser) {
      return '';
    }
    return new buffer('', 'binary');
  }
 
  return request(options, function (err, response, body) {
    if (err) {
      err.status = response ? response.statusCode : 400;
      return onError(err, callback);
    }
 
    var error;
    var content_type = response.headers && response.headers['content-type'];
    var data = body || defaultBody();
 
    // CouchDB doesn't always return the right content-type for JSON data, so
    // we check for ^{ and }$ (ignoring leading/trailing whitespace)
    if (!options.binary && (options.json || !options.processData) &&
        typeof data !== 'object' &&
        (/json/.test(content_type) ||
         (/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
      data = JSON.parse(data);
    }
 
    if (response.statusCode >= 200 && response.statusCode < 300) {
      onSuccess(data, response, callback);
    } else {
      try {
        // See if we received an error message from the server
        // If the connection was interrupted, the data might be nothing
        // that's why we have the try/catch
        data = JSON.parse(data.toString());
      } catch(e) {}
      error = errors.generateErrorFromResponse(data);
      error.status = response.statusCode;
      callback(error);
    }
  });
}
 
module.exports = ajax;