All files / src baseRequest.js

75.86% Statements 22/29
64.86% Branches 24/37
100% Functions 2/2
75% Lines 21/28
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 824x 4x 4x   4x   4x     4x                                                           312x 78x   78x 15x     15x     15x             78x 48x   48x 48x             78x 14x     78x       77x     77x      
import { Promise } from 'es6-promise'
import fetchPonyfill from 'fetch-ponyfill'
import { vsprintf } from 'sprintf-js'
 
import formatText from './format_text'
 
import stringifyAsQueryParam from './stringify_as_query_param'
 
 
const fetch = fetchPonyfill(Promise)
 
 
/**
 * imported from https://github.com/bigchaindb/js-utility-belt/
 *
 * Global fetch wrapper that adds some basic error handling and ease of use enhancements.
 * Considers any non-2xx response as an error.
 *
 * For more information on fetch, see https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch.
 *
 * Expects fetch to already be available (either in a ES6 environment, bundled through webpack, or
 * injected through a polyfill).
 *
 * @param  {string}  url    Url to request. Can be specified as a sprintf format string (see
 *                          https://github.com/alexei/sprintf.js) that will be resolved using
 *                          `config.urlTemplateSpec`.
 * @param  {object}  config Additional configuration, mostly passed to fetch as its 'init' config
 *                          (see https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch#Parameters).
 * @param  {*}             config.jsonBody        Json payload to the request. Will automatically be
 *                                                JSON.stringify()-ed and override `config.body`.
 * @param  {string|object} config.query           Query parameter to append to the end of the url.
 *                                                If specified as an object, keys will be
 *                                                decamelized into snake case first.
 * @param  {*[]|object}    config.urlTemplateSpec Format spec to use to expand the url (see sprintf).
 * @param  {*}             config.*               All other options are passed through to fetch.
 *
 * @return {Promise}        Promise that will resolve with the response if its status was 2xx;
 *                          otherwise rejects with the response
 */
export default function baseRequest(url, { jsonBody, query, urlTemplateSpec, ...fetchConfig } = {}) {
    let expandedUrl = url
 
    if (urlTemplateSpec != null) {
        Iif (Array.isArray(urlTemplateSpec) && urlTemplateSpec.length) {
            // Use vsprintf for the array call signature
            expandedUrl = vsprintf(url, urlTemplateSpec)
        } else Eif (urlTemplateSpec &&
                   typeof urlTemplateSpec === 'object' &&
                   Object.keys(urlTemplateSpec).length) {
            expandedUrl = formatText(url, urlTemplateSpec)
        } else if (process.env.NODE_ENV !== 'production') {
            // eslint-disable-next-line no-console
            console.warn('Supplied urlTemplateSpec was not an array or object. Ignoring...')
        }
    }
 
    if (query != null) {
        Iif (typeof query === 'string') {
            expandedUrl += query
        } else Eif (query && typeof query === 'object') {
            expandedUrl += stringifyAsQueryParam(query)
        } else if (process.env.NODE_ENV !== 'production') {
            // eslint-disable-next-line no-console
            console.warn('Supplied query was not a string or object. Ignoring...')
        }
    }
 
    if (jsonBody != null) {
        fetchConfig.body = JSON.stringify(jsonBody)
    }
 
    return fetch.fetch(expandedUrl, fetchConfig)
        .then((res) => {
            // If status is not a 2xx (based on Response.ok), assume it's an error
            // See https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
            Iif (!(res && res.ok)) {
                throw res
            }
            return res
        })
}