all files / src/ ajax.js

100% Statements 77/77
92% Branches 46/50
100% Functions 23/23
100% Lines 77/77
2 statements, 3 branches Ignored     
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               18× 18× 18× 18×             17× 68× 19×             68×       20×     20× 20× 60× 41× 41×   60×   20× 20× 20× 20× 20× 20× 20× 20×   20×     20× 18×       20× 20× 18×       20× 20×       20×       20× 60× 20× 20×   20× 12×             40× 40× 40×   14×   40×         40×                        
;(function (root, factory) {
  'use strict'
  /* istanbul ignore next */
  Iif (typeof define === 'function' && define.amd) {
    define('ajax', factory)
  } else Iif (typeof exports === 'object') {
    exports = module.exports = factory()
  } else {
    root.ajax = factory()
  }
})(this, function () {
  'use strict'
 
  function ajax (options) {
    var methods = ['get', 'post', 'put', 'delete']
    options = options || {}
    options.baseUrl = options.baseUrl || ''
    if (options.method && options.url) {
      return xhrConnection(
        options.method,
        options.baseUrl + options.url,
        maybeData(options.data),
        options
      )
    }
    return methods.reduce(function (acc, method) {
      acc[method] = function (url, data) {
        return xhrConnection(
          method,
          options.baseUrl + url,
          maybeData(data),
          options
        )
      }
      return acc
    }, {})
  }
 
  function maybeData (data) {
    return data || null
  }
 
  function xhrConnection (type, url, data, options) {
    var returnMethods = ['then', 'catch', 'always']
    var promiseMethods = returnMethods.reduce(function (promise, method) {
      promise[method] = function (callback) {
        promise[method] = callback
        return promise
      }
      return promise
    }, {})
    var xhr = new XMLHttpRequest()
    var featuredUrl = getUrlWithData(url, data, type)
    xhr.open(type, featuredUrl, true)
    xhr.withCredentials = options.hasOwnProperty('withCredentials')
    setHeaders(xhr, options.headers, data)
    xhr.addEventListener('readystatechange', ready(promiseMethods, xhr), false)
    xhr.send(isObject(data) ? JSON.stringify(data) : data)
    promiseMethods.abort = function () {
      return xhr.abort()
    }
    return promiseMethods
  }
 
  function getUrlWithData (url, data, type) {
    if (type.toLowerCase() !== 'get' || !data) {
      return url
    }
    var dataAsQueryString = objectToQueryString(data)
    var queryStringSeparator = url.indexOf('?') > -1 ? '&' : '?'
    return url + queryStringSeparator + dataAsQueryString
  }
 
  function setHeaders (xhr, headers, data) {
    headers = headers || {}
    if (!hasContentType(headers)) {
      headers['Content-Type'] = isObject(data)
        ? 'application/json'
        : 'application/x-www-form-urlencoded'
    }
    Object.keys(headers).forEach(function (name) {
      (headers[name] && xhr.setRequestHeader(name, headers[name]))
    })
  }
 
  function hasContentType (headers) {
    return Object.keys(headers).some(function (name) {
      return name.toLowerCase() === 'content-type'
    })
  }
 
  function ready (promiseMethods, xhr) {
    return function handleReady () {
      if (xhr.readyState === xhr.DONE) {
        xhr.removeEventListener('readystatechange', handleReady, false)
        promiseMethods.always.apply(promiseMethods, parseResponse(xhr))
 
        if (xhr.status >= 200 && xhr.status < 300) {
          promiseMethods.then.apply(promiseMethods, parseResponse(xhr))
        } else {
          promiseMethods.catch.apply(promiseMethods, parseResponse(xhr))
        }
      }
    }
  }
 
  function parseResponse (xhr) {
    var result
    try {
      result = JSON.parse(xhr.responseText)
    } catch (e) {
      result = xhr.responseText
    }
    return [ result, xhr ]
  }
 
  function objectToQueryString (data) {
    return isObject(data) ? getQueryString(data) : data
  }
 
  function isObject (data) {
    return Object.prototype.toString.call(data) === '[object Object]'
  }
 
  function getQueryString (obj, prefix) {
    return Object.keys(obj).map(function (key) {
      Eif (obj.hasOwnProperty(key) && undefined !== obj[key]) {
        var val = obj[key]
        key = prefix ? prefix + '[' + key + ']' : key
        return val !== null && typeof val === 'object' ? getQueryString(val, key) : encode(key) + '=' + encode(val)
      }
    })
      .filter(Boolean)
      .join('&')
  }
 
  function encode (value) {
    return encodeURIComponent(value)
  }
 
  return ajax
})