http-toolkit
Version:
Well-documented toolkit for making elegant HTTP requests with JavaScript
430 lines (363 loc) • 18.1 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.baseOptions = exports.defaultOptions = void 0;
var _httpHeaders = require("../models/http-headers");
var _utils = require("../utils");
var _httpMediaTypes = require("../models/http-media-types");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var defaultOptions = {
numberOfRetries: 0,
retryWhen: function retryWhen(response) {
return !(0, _utils.isResponseOk)(response);
}
};
exports.defaultOptions = defaultOptions;
var baseOptions = function baseOptions(url, options, baseConfig) {
return {
/**
* Get the currently set url
* @returns {string}
* @memberOf HttpClientOptions
*/
getUrl: function getUrl() {
return url;
},
/**
* Get currently set options
* @returns {Object}
* @memberOf HttpClientOptions
*/
getOptions: function getOptions() {
return options;
},
/**
* Adds or overwrites header key-value pairs.
* @param {Headers|Object} headers - the object to merge with current headers. (if forceExact=true, then it replaces headers instead of merging)
* @param {boolean} [forceExact:false] - if true, ignores previously set headers and just uses the provided headers
* @returns {HttpClient} a copy of httpClient with new headers
* @memberOf HttpClientOptions
*/
withHeaders: function withHeaders(headers) {
var forceExact = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
return baseConfig(url, setHeaders(headers, forceExact, options));
},
/**
* Adds or overwrites a header.
* @param {string} name Header name
* @param {string} value Header value
* @returns {HttpClient} a copy of httpClient with new headers
* @memberOf HttpClientOptions
*/
withHeader: function withHeader(name, value) {
return baseConfig(url, addHeader(name, value, options));
},
/**
* Adds or overwrites key-value pairs with current options.
* @param {Object} options - the object to merge with current options. (if forceExact=true, then it replaces headers instead of merging)
* @param {boolean} [forceExact:false] - if true, ignores previously set headers and just uses the provided headers
* @returns {HttpClient} a copy of httpClient with new options
* @memberOf HttpClientOptions
*/
withOptions: function withOptions(options) {
var forceExact = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
return baseConfig(url, setOptions(options, forceExact, options));
},
/**
* Adds or overwrites an option.
* @param {string} name Option name
* @param {string} value Option value
* @returns {HttpClient} a copy of httpClient with new options
* @memberOf HttpClientOptions
*/
withOption: function withOption(name, value) {
return baseConfig(url, addOption(name, value, options));
},
/**
* Sets Cross-Origin Resource Sharing (CORS) policy
* @param {string} cors - policy
* @returns {HttpClient} a copy of httpClient with new options
* @memberOf HttpClientOptions
* @example withCors('no-cors')
*/
withCors: function withCors() {
var cors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'cors';
return baseConfig(url, setOptions({
cors: cors
}, false, options));
},
/**
* Sets a new url. **Note** This will also replace any path set earlier.
* @param {string} newUrl - The new url to set.
* @returns {HttpClient} - a copy of httpClient new full url
* @memberOf HttpClientOptions
*/
withUrl: function withUrl(newUrl) {
return baseConfig(newUrl, options);
},
/**
* Appends a string to the current/base url.
* @param {string} path The path to append at the end of base-url
* @returns {HttpClient} a copy of httpClient new full url
* @memberOf HttpClientOptions
*/
withPath: function withPath(path) {
return baseConfig(url + path, options);
},
/**
* Sets a value to the Authorization-header.
* @param {string} authValue The Authorization value
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
*/
withAuth: function withAuth(authValue) {
return baseConfig(url, addHeader(_httpHeaders.HttpHeader.AUTHORIZATION, authValue, options));
},
/**
* Sets Authorization-header to "Bearer <token>".
* @param {string} token The token value as a string
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
*/
withToken: function withToken(token) {
return baseConfig(url, addToken(token, options));
},
/**
* Sets Content-Type header
* @param {MediaType|string} contentType
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
*/
withContentType: function withContentType(contentType) {
return baseConfig(url, addHeader(_httpHeaders.HttpHeader.CONTENT_TYPE, contentType, options));
},
/**
* Sets Accept header
* @param {MediaType|string} acceptType
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
*/
withAcceptType: function withAcceptType(acceptType) {
return baseConfig(url, addHeader(_httpHeaders.HttpHeader.ACCEPT, acceptType, options));
},
/**
* Sets application/json to the Accept header
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
*/
acceptJson: function acceptJson() {
return baseConfig(url, addHeader(_httpHeaders.HttpHeader.ACCEPT, _httpMediaTypes.MediaType.JSON, options));
},
/**
* Sets a body to the client
* @param {Object|string} body The body to attach in the request. If it's an object, it will be stringified
* @returns {HttpClient} a copy of httpClient with updated body
* @memberOf HttpClientOptions
*/
withBody: function withBody(body) {
return baseConfig(url, setBody(body, options));
},
/**
* Adds a single key-value pair to the query. If there was no query set previously, adds a leading '?'; else a '&'.
* @param {string} key - the query-key to set.
* @param {string} value - the query-value to set.
* @returns {HttpClient} a copy of httpClient with new query
* @memberOf HttpClientOptions
* @example myClient.addQuery('foo','bar')
*/
addQuery: function addQuery(key, value) {
return baseConfig(url, addQueryParam(key, value, options));
},
/**
* Adds or overwrites the query-params defined as key-value pairs in queryObject.
* @param {Object|Array<Object>} queries - the object or array of objects to merge with current queryParams. (if forceExact=true, then it replaces previously set query instead of merging)
* @param {boolean} [forceExact:false] - if true, ignores previously set query and just uses the provided queryObject key-values
* @returns {HttpClient} a copy of httpClient with new query
* @memberOf HttpClientOptions
* @example myClient.addQueries([{key: 'value'}, {anotherKey: 'anotherValue'}]) // Guaranteed same order as array
* @example myClient.addQueries({key: 'value', anotherKey: 'anotherValue'} // Can't guarantee to be ordered
*/
addQueries: function addQueries(queries) {
var forceExact = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
return baseConfig(url, setQueryParams(queries, forceExact, options));
},
/**
* Sets the query (it will replace any previously set queries).
* @param {string} query - the query to set.
* @returns {HttpClient} a copy of httpClient with new query
* @memberOf HttpClientOptions
* @example myClient.withQuery('foo=bar&hello=world')
*/
withQuery: function withQuery(query) {
return baseConfig(url, _objectSpread({}, options, {
query: query.startsWith('?') ? query : "?".concat(query)
}));
},
/**
* Sets a timout in milliseconds. Will abort request and throw ApiError if timeout is reached before response.
* @param {number} timeout - Milliseconds to wait for response. Default is unlimited
* @returns {HttpClient} a copy of httpClient updated headers
* @throws {ApiError} if timeout is reached before response
* @memberOf HttpClientOptions
*/
withTimeout: function withTimeout(timeout) {
return baseConfig(url, setOptions({
timeout: timeout
}, false, options));
},
/**
* Sets the number the request will retry until success. Success is default 2xx status code. If the retryWhen option is set (@see {@link retryWhen}), then the negated predicate provided is considered success.
* @param {number} nbrRetries - Number of retries (default is 0)
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
*/
withRetries: function withRetries(nbrRetries) {
return baseConfig(url, setOptions({
numberOfRetries: nbrRetries
}, false, options));
},
/**
* Sets the predicate at which the request will retry if true. Default is `retryWhen(response => response.status !== 2xx )`
* @param {function} predicate - (response => bool) Check e.g. the status code, *make sure not to use the response stream - use clone()*
* @returns {HttpClient} a copy of httpClient updated headers
* @memberOf HttpClientOptions
* @example myClient.withRetries(5).retryWhen(response => isResponseStatus(response, 200)).getAsync()
*/
retryWhen: function retryWhen(predicate) {
return baseConfig(url, setOptions({
retryWhen: predicate
}, false, options));
},
/**
* @function addPrefetch
* @description Adds a pre-fetch function (function that will execute before each fetch) to the client's prefetch stack.
*
* *Prefetches are called in the order they are added.*
* @param {prefetch} func - Function to be called before requests. Signature: (url, options)
* @memberOf HttpClientOptions
* @example
* addPrefetch((url, options) => console.log(`sending a ${options.method}-request, body is ${options.body}`))
*/
addPrefetch: function addPrefetch(func) {
return baseConfig(url, _addPrefetch(func, options));
},
/**
* @function addPostfetch
* @description Adds a post-fetch function (function that will execute after each fetch) to the client's postfetch stack.
*
* *Postfetches are called in the order they are added*
* @param {postfetch} func - Function to be called after requests. Signature: (url, options, response)
* @memberOf HttpClientOptions
* @example
* addPostfetch((url, options, response) => console.log(`sent a ${options.method}-request, response was ${response}`))
*/
addPostfetch: function addPostfetch(func) {
return baseConfig(url, _addPostfetch(func, options));
}
};
};
exports.baseOptions = baseOptions;
var _addPostfetch = function _addPostfetch(func, options) {
var postfetchStack = _toConsumableArray(options.postfetchStack || []);
postfetchStack.push(func);
return _objectSpread({}, options, {
postfetchStack: postfetchStack
});
};
var _addPrefetch = function _addPrefetch(func, options) {
var prefetchStack = _toConsumableArray(options.prefetchStack || []);
prefetchStack.push(func);
return _objectSpread({}, options, {
prefetchStack: prefetchStack
});
};
var setHeaders = function setHeaders(newHeaders, force) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (force) {
return _objectSpread({}, options, {
headers: newHeaders
});
}
var headers = _objectSpread({}, options.headers || {}, {}, newHeaders);
return _objectSpread({}, options, {
headers: headers
});
};
var addHeader = function addHeader(name, value, options) {
return setHeaders(_defineProperty({}, name, value), false, options);
};
var addAuthorization = function addAuthorization(authValue, options) {
return addHeader(_httpHeaders.HttpHeader.AUTHORIZATION, authValue, options);
};
var addToken = function addToken(token, options) {
return addAuthorization("Bearer ".concat(token), options);
};
var setOptions = function setOptions(newOptions, force) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (force) {
return newOptions;
}
return _objectSpread({}, options, {}, newOptions);
};
var addOption = function addOption(name, value) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
return setOptions(_defineProperty({}, name, value), false, options);
};
var setBody = function setBody(body, options) {
var bodyString = body;
if (typeof body !== 'string') {
bodyString = JSON.stringify(body);
}
return addOption('body', bodyString, options);
};
var encodeParam = function encodeParam(key, value) {
return "".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value));
};
var addQueryParam = function addQueryParam(key, value) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var query = String(options.query || '');
var param = encodeParam(key, value);
query += query.length ? "&".concat(param) : "?".concat(param);
return _objectSpread({}, options, {
query: query
});
};
var setQueryParams = function setQueryParams() {
var queries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var force = arguments.length > 1 ? arguments[1] : undefined;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var entries = [];
if (Array.isArray(queries)) {
queries.forEach(function (q) {
var _entries;
return (_entries = entries).push.apply(_entries, _toConsumableArray(Object.entries(q)));
});
} else {
entries = Object.entries(queries);
}
var _entries$reverse$pop = entries.reverse().pop(),
_entries$reverse$pop2 = _slicedToArray(_entries$reverse$pop, 2),
firstKey = _entries$reverse$pop2[0],
firstValue = _entries$reverse$pop2[1];
var firstParam = encodeParam(firstKey, firstValue);
var query = !force && options.query ? "".concat(options.query, "&").concat(firstParam, "&") : "?".concat(firstParam, "&");
query += entries.map(function (entry) {
return encodeParam(entry[0], entry[1]);
}).join('&');
return _objectSpread({}, options, {
query: query
});
};
;