ackee-http-client
Advanced tools
Comparing version 2.0.3 to 2.1.0
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; | ||
import _objectSpread from "@babel/runtime/helpers/objectSpread"; | ||
import _regeneratorRuntime from "@babel/runtime/regenerator"; | ||
var _marked = | ||
/*#__PURE__*/ | ||
_regeneratorRuntime.mark(setAccessTokenTimeout); | ||
import axios from 'axios'; | ||
import { take } from 'redux-saga/effects'; | ||
import { delay } from 'redux-saga'; | ||
import { take, call, race } from 'redux-saga/effects'; | ||
import { actionTypes } from 'ackee-redux-token-auth'; | ||
import * as Store from './store'; | ||
import saga from './sagas'; | ||
import * as errors from './errors'; | ||
import { enhancedError } from './utilities'; | ||
import { METHODS } from 'http'; | ||
/** | ||
* setAccessTokenTimeout is called when access token isn't available (IS_AUTH is false). | ||
* If 'timeDuration' isn't falsy, set timeout for that duration. | ||
* The timeout is cancelled if access token will become available sooner than the timeout ends, | ||
* otherwise the 'errors.authRequestProxy.timeout' error is thrown. | ||
*/ | ||
function setAccessTokenTimeout() { | ||
var _Store$get, accessTokenUnavailableTimeout, enabled, duration, silent, result; | ||
return _regeneratorRuntime.wrap(function setAccessTokenTimeout$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_Store$get = Store.get(Store.keys.CONFIG), accessTokenUnavailableTimeout = _Store$get.accessTokenUnavailableTimeout; | ||
enabled = accessTokenUnavailableTimeout.enabled, duration = accessTokenUnavailableTimeout.duration, silent = accessTokenUnavailableTimeout.silent; | ||
if (enabled) { | ||
_context.next = 4; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
case 4: | ||
_context.next = 6; | ||
return race({ | ||
timeout: call(delay, duration), | ||
accessTokenAvailable: take(actionTypes.ACCESS_TOKEN_AVAILABLE) | ||
}); | ||
case 6: | ||
result = _context.sent; | ||
if (!(result.timeout && !silent)) { | ||
_context.next = 9; | ||
break; | ||
} | ||
throw enhancedError(errors.authRequestProxy.timeout); | ||
case 9: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _marked, this); | ||
} | ||
var authRequestProxy = function authRequestProxy(methodHandler) { | ||
@@ -14,33 +71,33 @@ return ( | ||
_regeneratorRuntime.mark(function _callee() { | ||
var _args = arguments; | ||
return _regeneratorRuntime.wrap(function _callee$(_context) { | ||
var _args2 = arguments; | ||
return _regeneratorRuntime.wrap(function _callee$(_context2) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (Store.get(Store.keys.IS_AUTH)) { | ||
_context.next = 5; | ||
_context2.next = 5; | ||
break; | ||
} | ||
if (Store.get(Store.keys.SAGA_INITIALIZE)) { | ||
_context.next = 3; | ||
if (Store.get(Store.keys.SAGA_INITIALIZED)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
throw new Error("ackee-http-client: The HTTP client's 'saga' must be connected among your other sagas."); | ||
throw enhancedError(errors.authRequestProxy.unconnectedSaga); | ||
case 3: | ||
_context.next = 5; | ||
return take(actionTypes.ACCESS_TOKEN_AVAILABLE); | ||
_context2.next = 5; | ||
return call(setAccessTokenTimeout); | ||
case 5: | ||
_context.next = 7; | ||
return methodHandler.apply(void 0, _args); | ||
_context2.next = 7; | ||
return methodHandler.apply(void 0, _args2); | ||
case 7: | ||
return _context.abrupt("return", _context.sent); | ||
return _context2.abrupt("return", _context2.sent); | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
return _context2.stop(); | ||
} | ||
@@ -55,3 +112,4 @@ } | ||
var axiosClient = axios.create(options); | ||
var api = {}; // - unwrap axios HTTP method handlers | ||
var api = {}; | ||
var objects = new Set(['defaults', 'interceptors']); // - unwrap axios HTTP method handlers | ||
// - add custom proxies | ||
@@ -63,4 +121,5 @@ | ||
var key = _arr[_i]; | ||
var methodHandler = axiosClient[key]; | ||
api[key] = proxy ? proxy(methodHandler) : methodHandler; | ||
var methodHandler = axiosClient[key]; // wrap only functions with proxy function | ||
api[key] = !objects.has(key) && proxy ? proxy(methodHandler) : methodHandler; | ||
} | ||
@@ -75,2 +134,8 @@ | ||
var customConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
if (Store.get(Store.keys.WAS_INITIALIZED)) { | ||
throw enhancedError(errors.create.errors); | ||
} | ||
Store.set(Store.keys.WAS_INITIALIZED, true); | ||
var defaultConfig = Store.get(Store.keys.CONFIG); | ||
@@ -77,0 +142,0 @@ Store.set(Store.keys.CONFIG, _objectSpread({}, defaultConfig, customConfig)); |
@@ -9,4 +9,9 @@ var config = { | ||
} | ||
}, | ||
accessTokenUnavailableTimeout: { | ||
enabled: false, | ||
duration: 1000 * 30, | ||
silent: true | ||
} | ||
}; | ||
export default config; |
@@ -6,2 +6,4 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty"; | ||
import defaultConfig from './defaultConfig'; | ||
import * as errors from './errors'; | ||
import { enhancedError } from './utilities'; | ||
var keys = { | ||
@@ -11,5 +13,6 @@ IS_AUTH: 'isAuth', | ||
CONFIG: 'config', | ||
SAGA_INITIALIZE: 'sagaInitialize' | ||
SAGA_INITIALIZED: 'sagaInitialized', | ||
WAS_INITIALIZED: 'wasInitialized' | ||
}; | ||
var state = (_state = {}, _defineProperty(_state, keys.IS_AUTH, false), _defineProperty(_state, keys.AUTH_AXIOS, null), _defineProperty(_state, keys.CONFIG, defaultConfig), _defineProperty(_state, keys.SAGA_INITIALIZE, false), _state); | ||
var state = (_state = {}, _defineProperty(_state, keys.IS_AUTH, false), _defineProperty(_state, keys.AUTH_AXIOS, null), _defineProperty(_state, keys.CONFIG, defaultConfig), _defineProperty(_state, keys.SAGA_INITIALIZED, false), _defineProperty(_state, keys.WAS_INITIALIZED, false), _state); | ||
/** | ||
@@ -23,3 +26,3 @@ * @param {String} key | ||
if (value === undefined) { | ||
throw new TypeError("The 'value' parameter mustn't be 'undefined', any other type is allowed."); | ||
throw enhancedError(errors.store.undefinedValue, TypeError); | ||
} | ||
@@ -26,0 +29,0 @@ |
@@ -20,2 +20,4 @@ "use strict"; | ||
var _reduxSaga = require("redux-saga"); | ||
var _effects = require("redux-saga/effects"); | ||
@@ -29,2 +31,60 @@ | ||
var errors = _interopRequireWildcard(require("./errors")); | ||
var _utilities = require("./utilities"); | ||
var _http = require("http"); | ||
var _marked = | ||
/*#__PURE__*/ | ||
_regenerator.default.mark(setAccessTokenTimeout); | ||
/** | ||
* setAccessTokenTimeout is called when access token isn't available (IS_AUTH is false). | ||
* If 'timeDuration' isn't falsy, set timeout for that duration. | ||
* The timeout is cancelled if access token will become available sooner than the timeout ends, | ||
* otherwise the 'errors.authRequestProxy.timeout' error is thrown. | ||
*/ | ||
function setAccessTokenTimeout() { | ||
var _Store$get, accessTokenUnavailableTimeout, enabled, duration, silent, result; | ||
return _regenerator.default.wrap(function setAccessTokenTimeout$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_Store$get = Store.get(Store.keys.CONFIG), accessTokenUnavailableTimeout = _Store$get.accessTokenUnavailableTimeout; | ||
enabled = accessTokenUnavailableTimeout.enabled, duration = accessTokenUnavailableTimeout.duration, silent = accessTokenUnavailableTimeout.silent; | ||
if (enabled) { | ||
_context.next = 4; | ||
break; | ||
} | ||
return _context.abrupt("return"); | ||
case 4: | ||
_context.next = 6; | ||
return (0, _effects.race)({ | ||
timeout: (0, _effects.call)(_reduxSaga.delay, duration), | ||
accessTokenAvailable: (0, _effects.take)(_ackeeReduxTokenAuth.actionTypes.ACCESS_TOKEN_AVAILABLE) | ||
}); | ||
case 6: | ||
result = _context.sent; | ||
if (!(result.timeout && !silent)) { | ||
_context.next = 9; | ||
break; | ||
} | ||
throw (0, _utilities.enhancedError)(errors.authRequestProxy.timeout); | ||
case 9: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _marked, this); | ||
} | ||
var authRequestProxy = function authRequestProxy(methodHandler) { | ||
@@ -34,33 +94,33 @@ return ( | ||
_regenerator.default.mark(function _callee() { | ||
var _args = arguments; | ||
return _regenerator.default.wrap(function _callee$(_context) { | ||
var _args2 = arguments; | ||
return _regenerator.default.wrap(function _callee$(_context2) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (Store.get(Store.keys.IS_AUTH)) { | ||
_context.next = 5; | ||
_context2.next = 5; | ||
break; | ||
} | ||
if (Store.get(Store.keys.SAGA_INITIALIZE)) { | ||
_context.next = 3; | ||
if (Store.get(Store.keys.SAGA_INITIALIZED)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
throw new Error("ackee-http-client: The HTTP client's 'saga' must be connected among your other sagas."); | ||
throw (0, _utilities.enhancedError)(errors.authRequestProxy.unconnectedSaga); | ||
case 3: | ||
_context.next = 5; | ||
return (0, _effects.take)(_ackeeReduxTokenAuth.actionTypes.ACCESS_TOKEN_AVAILABLE); | ||
_context2.next = 5; | ||
return (0, _effects.call)(setAccessTokenTimeout); | ||
case 5: | ||
_context.next = 7; | ||
return methodHandler.apply(void 0, _args); | ||
_context2.next = 7; | ||
return methodHandler.apply(void 0, _args2); | ||
case 7: | ||
return _context.abrupt("return", _context.sent); | ||
return _context2.abrupt("return", _context2.sent); | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
return _context2.stop(); | ||
} | ||
@@ -76,3 +136,4 @@ } | ||
var api = {}; // - unwrap axios HTTP method handlers | ||
var api = {}; | ||
var objects = new Set(['defaults', 'interceptors']); // - unwrap axios HTTP method handlers | ||
// - add custom proxies | ||
@@ -84,4 +145,5 @@ | ||
var key = _arr[_i]; | ||
var methodHandler = axiosClient[key]; | ||
api[key] = proxy ? proxy(methodHandler) : methodHandler; | ||
var methodHandler = axiosClient[key]; // wrap only functions with proxy function | ||
api[key] = !objects.has(key) && proxy ? proxy(methodHandler) : methodHandler; | ||
} | ||
@@ -96,2 +158,8 @@ | ||
var customConfig = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
if (Store.get(Store.keys.WAS_INITIALIZED)) { | ||
throw (0, _utilities.enhancedError)(errors.create.errors); | ||
} | ||
Store.set(Store.keys.WAS_INITIALIZED, true); | ||
var defaultConfig = Store.get(Store.keys.CONFIG); | ||
@@ -98,0 +166,0 @@ Store.set(Store.keys.CONFIG, (0, _objectSpread2.default)({}, defaultConfig, customConfig)); |
@@ -15,2 +15,7 @@ "use strict"; | ||
} | ||
}, | ||
accessTokenUnavailableTimeout: { | ||
enabled: false, | ||
duration: 1000 * 30, | ||
silent: true | ||
} | ||
@@ -17,0 +22,0 @@ }; |
@@ -5,2 +5,4 @@ "use strict"; | ||
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -15,2 +17,6 @@ value: true | ||
var errors = _interopRequireWildcard(require("./errors")); | ||
var _utilities = require("./utilities"); | ||
var _state; | ||
@@ -22,6 +28,7 @@ | ||
CONFIG: 'config', | ||
SAGA_INITIALIZE: 'sagaInitialize' | ||
SAGA_INITIALIZED: 'sagaInitialized', | ||
WAS_INITIALIZED: 'wasInitialized' | ||
}; | ||
exports.keys = keys; | ||
var state = (_state = {}, (0, _defineProperty2.default)(_state, keys.IS_AUTH, false), (0, _defineProperty2.default)(_state, keys.AUTH_AXIOS, null), (0, _defineProperty2.default)(_state, keys.CONFIG, _defaultConfig.default), (0, _defineProperty2.default)(_state, keys.SAGA_INITIALIZE, false), _state); | ||
var state = (_state = {}, (0, _defineProperty2.default)(_state, keys.IS_AUTH, false), (0, _defineProperty2.default)(_state, keys.AUTH_AXIOS, null), (0, _defineProperty2.default)(_state, keys.CONFIG, _defaultConfig.default), (0, _defineProperty2.default)(_state, keys.SAGA_INITIALIZED, false), (0, _defineProperty2.default)(_state, keys.WAS_INITIALIZED, false), _state); | ||
/** | ||
@@ -35,3 +42,3 @@ * @param {String} key | ||
if (value === undefined) { | ||
throw new TypeError("The 'value' parameter mustn't be 'undefined', any other type is allowed."); | ||
throw (0, _utilities.enhancedError)(errors.store.undefinedValue, TypeError); | ||
} | ||
@@ -38,0 +45,0 @@ |
{ | ||
"name": "ackee-http-client", | ||
"version": "2.0.3", | ||
"version": "2.1.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -83,4 +83,6 @@ # ackee-http-client | ||
By using methods under `authApi` object, it's guarantee that each HTTP request is going to have access token in its `Authorization` header. | ||
By using methods under `authApi` object, it's guaranteed that each HTTP request is going to have access token in its `Authorization` header. | ||
If the access token isn't available at the moment, the request is paused by `take(ACCESS_TOKEN_AVAILABLE)` effect, and timeout, if enabled, is set. See [`accessTokenUnavailableTimeout` at create method](#api-create-customConfig) for more details. | ||
See [available properties](#api-create-http-client) of the `authApi` object. | ||
@@ -98,2 +100,6 @@ | ||
> ### Shared `defaults` | ||
> | ||
> Even though `api` and `authApi` are created as separated axios instances, they share the same default request config object - [`api.defaults` and `authApi.defaults`](https://github.com/axios/axios#request-config). This issue/feature is caused by how axios is implemented and `ackee-http-client` won't change it. Just don't be surprised, when you see the `Authorization` header also in requests created by the `api`. | ||
--- | ||
@@ -111,3 +117,3 @@ | ||
- `customConfig: Object` | ||
- <a name="api-create-customConfig"></a>`customConfig: Object` | ||
@@ -123,5 +129,5 @@ The `customConfig` object offers following default options: | ||
// If `manageAuthHeader` is enabled, `setAuthHeader` receives object with default headers, | ||
// when access token state changes. | ||
/** | ||
* If `manageAuthHeader` is enabled, `setAuthHeader` receives | ||
* object with default headers, when access token state changes. | ||
* @param {Object} headers - reference to axios default request headers object (https://github.com/axios/axios#custom-instance-defaults) | ||
@@ -137,3 +143,16 @@ * @param {String|null} accessToken | ||
} | ||
} | ||
}, | ||
// If it's used `authApi` and access token isn't available, | ||
// there is optionable timeout with following default values: | ||
accessTokenUnavailableTimeout: { | ||
// enable / disable the timeout | ||
enabled: false, | ||
// set timeout duration for 30s | ||
duration: 1000 * 30, | ||
// if silent is true, then throw a custom error, | ||
// othewise API request will be made that fails, | ||
// and throws a server error | ||
silent: false, | ||
}, | ||
} | ||
@@ -140,0 +159,0 @@ ``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
43549
29
946
210
2