@ndustrial/contxt-sdk
Advanced tools
Comparing version 0.0.12 to 0.0.13
@@ -1,3 +0,7 @@ | ||
## [v0.0.12](http://github.com/ndustrialio/contxt-sdk-js/tree/v0.0.12) (2018-06-13) | ||
## [v0.0.13](http://github.com/ndustrialio/contxt-sdk-js/tree/v0.0.13) (2018-06-16) | ||
* Adds the ability to set up custom axios interceptors to be used on each request and response made to an API. (More information available at at {@link https://github.com/axios/axios#interceptors axios Interceptors}) | ||
## [v0.0.12](http://github.com/ndustrialio/contxt-sdk-js/tree/v0.0.12) (2018-06-14) | ||
**Changed** | ||
@@ -4,0 +8,0 @@ |
@@ -48,2 +48,6 @@ ## Classes | ||
<dd></dd> | ||
<dt><a href="./Typedefs.md#AxiosInterceptor">AxiosInterceptor</a> : <code>Object</code></dt> | ||
<dd><p>An object of interceptors that get called on every request or response. | ||
More information at <a href="https://github.com/axios/axios#interceptors">axios Interceptors</a></p> | ||
</dd> | ||
<dt><a href="./Typedefs.md#CostCenter">CostCenter</a> : <code>Object</code></dt> | ||
@@ -50,0 +54,0 @@ <dd></dd> |
@@ -25,2 +25,15 @@ <a name="Audience"></a> | ||
<a name="AxiosInterceptor"></a> | ||
## AxiosInterceptor : <code>Object</code> | ||
An object of interceptors that get called on every request or response. | ||
More information at [axios Interceptors](https://github.com/axios/axios#interceptors) | ||
**Kind**: global typedef | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| interceptor.fulfilled | <code>function</code> | A function that is run on every successful request or response | | ||
| interceptor.rejected | <code>function</code> | A function that is run on every failed request or response | | ||
<a name="CostCenter"></a> | ||
@@ -202,2 +215,5 @@ | ||
| [auth.tokenExpiresAtBufferMs] | <code>number</code> | <code>300000</code> | The time (in milliseconds) before a token truly expires that we consider it expired (i.e. the token's expiresAt - this = calculated expiresAt). Defaults to 5 minutes. | | ||
| [interceptors] | <code>Object</code> | | Axios interceptors that can transform requests and responses. More information at [axios Interceptors](https://github.com/axios/axios#interceptors) | | ||
| [interceptors.request] | [<code>Array.<AxiosInterceptor></code>](#AxiosInterceptor) | | Interceptors that act on every request | | ||
| [intercepotrs.response] | [<code>Array.<AxiosInterceptor></code>](#AxiosInterceptor) | | Intereptors that act on every response | | ||
@@ -204,0 +220,0 @@ <a name="UserProfile"></a> |
@@ -31,2 +31,6 @@ import axios from 'axios'; | ||
tokenExpiresAtBufferMs: 5 * 60 * 1000 | ||
}, | ||
interceptors: { | ||
request: [], | ||
response: [] | ||
} | ||
@@ -150,2 +154,24 @@ }; | ||
var toConsumableArray = function (arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
}; | ||
var Config = function () { | ||
@@ -165,2 +191,4 @@ | ||
this.auth = _extends({}, defaultConfigs.auth, userConfig.auth); | ||
this.interceptors = _extends({}, defaultConfigs.interceptors, userConfig.interceptors); | ||
} | ||
@@ -863,19 +891,10 @@ | ||
function Request(sdk, audienceName) { | ||
var _this = this; | ||
classCallCheck(this, Request); | ||
this._insertHeaders = function (config) { | ||
return _this._sdk.auth.getCurrentApiToken(_this._audienceName).then(function (apiToken) { | ||
config.headers.common.Authorization = 'Bearer ' + apiToken; | ||
return config; | ||
}); | ||
}; | ||
this._audienceName = audienceName; | ||
this._axios = axios.create(); | ||
this._insertHeaders = this._insertHeaders.bind(this); | ||
this._sdk = sdk; | ||
this._axios = axios.create(); | ||
this._axios.interceptors.request.use(this._insertHeaders); | ||
this._attachInterceptors(); | ||
} | ||
@@ -971,2 +990,33 @@ | ||
}, { | ||
key: '_attachInterceptors', | ||
value: function _attachInterceptors() { | ||
var _this = this; | ||
var requestInterceptors = [{ fulfilled: this._insertHeaders }].concat(toConsumableArray(this._sdk.config.interceptors.request)); | ||
var responseInterceptors = [].concat(toConsumableArray(this._sdk.config.interceptors.response)); | ||
requestInterceptors.forEach(function (_ref9) { | ||
var fulfilled = _ref9.fulfilled, | ||
rejected = _ref9.rejected; | ||
_this._axios.interceptors.request.use(fulfilled, rejected); | ||
}); | ||
responseInterceptors.forEach(function (_ref10) { | ||
var fulfilled = _ref10.fulfilled, | ||
rejected = _ref10.rejected; | ||
_this._axios.interceptors.response.use(fulfilled, rejected); | ||
}); | ||
} | ||
}, { | ||
key: '_insertHeaders', | ||
value: function _insertHeaders(config) { | ||
return this._sdk.auth.getCurrentApiToken(this._audienceName).then(function (apiToken) { | ||
config.headers.common.Authorization = 'Bearer ' + apiToken; | ||
return config; | ||
}); | ||
} | ||
}]); | ||
@@ -973,0 +1023,0 @@ return Request; |
@@ -35,2 +35,6 @@ 'use strict'; | ||
tokenExpiresAtBufferMs: 5 * 60 * 1000 | ||
}, | ||
interceptors: { | ||
request: [], | ||
response: [] | ||
} | ||
@@ -154,2 +158,24 @@ }; | ||
var toConsumableArray = function (arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
}; | ||
var Config = function () { | ||
@@ -169,2 +195,4 @@ | ||
this.auth = _extends({}, defaultConfigs.auth, userConfig.auth); | ||
this.interceptors = _extends({}, defaultConfigs.interceptors, userConfig.interceptors); | ||
} | ||
@@ -867,19 +895,10 @@ | ||
function Request(sdk, audienceName) { | ||
var _this = this; | ||
classCallCheck(this, Request); | ||
this._insertHeaders = function (config) { | ||
return _this._sdk.auth.getCurrentApiToken(_this._audienceName).then(function (apiToken) { | ||
config.headers.common.Authorization = 'Bearer ' + apiToken; | ||
return config; | ||
}); | ||
}; | ||
this._audienceName = audienceName; | ||
this._axios = axios.create(); | ||
this._insertHeaders = this._insertHeaders.bind(this); | ||
this._sdk = sdk; | ||
this._axios = axios.create(); | ||
this._axios.interceptors.request.use(this._insertHeaders); | ||
this._attachInterceptors(); | ||
} | ||
@@ -975,2 +994,33 @@ | ||
}, { | ||
key: '_attachInterceptors', | ||
value: function _attachInterceptors() { | ||
var _this = this; | ||
var requestInterceptors = [{ fulfilled: this._insertHeaders }].concat(toConsumableArray(this._sdk.config.interceptors.request)); | ||
var responseInterceptors = [].concat(toConsumableArray(this._sdk.config.interceptors.response)); | ||
requestInterceptors.forEach(function (_ref9) { | ||
var fulfilled = _ref9.fulfilled, | ||
rejected = _ref9.rejected; | ||
_this._axios.interceptors.request.use(fulfilled, rejected); | ||
}); | ||
responseInterceptors.forEach(function (_ref10) { | ||
var fulfilled = _ref10.fulfilled, | ||
rejected = _ref10.rejected; | ||
_this._axios.interceptors.response.use(fulfilled, rejected); | ||
}); | ||
} | ||
}, { | ||
key: '_insertHeaders', | ||
value: function _insertHeaders(config) { | ||
return this._sdk.auth.getCurrentApiToken(this._audienceName).then(function (apiToken) { | ||
config.headers.common.Authorization = 'Bearer ' + apiToken; | ||
return config; | ||
}); | ||
} | ||
}]); | ||
@@ -977,0 +1027,0 @@ return Request; |
{ | ||
"name": "@ndustrial/contxt-sdk", | ||
"version": "0.0.12", | ||
"version": "0.0.13", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -5,3 +5,7 @@ export default { | ||
tokenExpiresAtBufferMs: 5 * 60 * 1000 // 5 minutes | ||
}, | ||
interceptors: { | ||
request: [], | ||
response: [] | ||
} | ||
}; |
@@ -44,2 +44,12 @@ import defaultAudiences from './audiences'; | ||
/** | ||
* An object of interceptors that get called on every request or response. | ||
* More information at {@link https://github.com/axios/axios#interceptors axios Interceptors} | ||
* | ||
* @typedef {Object} AxiosInterceptor | ||
* @param {function} interceptor.fulfilled A function that is run on every successful request or | ||
* response | ||
* @param {function} interceptor.rejected A function that is run on every failed request or response | ||
*/ | ||
/** | ||
* User provided configuration options | ||
@@ -63,2 +73,6 @@ * | ||
* expiresAt). Defaults to 5 minutes. | ||
* @property {Object} [interceptors] Axios interceptors that can transform requests and responses. | ||
* More information at {@link https://github.com/axios/axios#interceptors axios Interceptors} | ||
* @property {AxiosInterceptor[]} [interceptors.request] Interceptors that act on every request | ||
* @property {AxiosInterceptor[]} [intercepotrs.response] Intereptors that act on every response | ||
*/ | ||
@@ -90,2 +104,7 @@ | ||
}; | ||
this.interceptors = { | ||
...defaultConfigs.interceptors, | ||
...userConfig.interceptors | ||
}; | ||
} | ||
@@ -92,0 +111,0 @@ |
@@ -16,3 +16,3 @@ import times from 'lodash.times'; | ||
describe('constructor', function() { | ||
let baseAuthConfigs; | ||
let authConfigs; | ||
let baseConfigs; | ||
@@ -23,5 +23,6 @@ let config; | ||
let getAudiences; | ||
let interceptorConfigs; | ||
beforeEach(function() { | ||
baseAuthConfigs = { | ||
authConfigs = { | ||
clientId: faker.internet.password(), | ||
@@ -43,2 +44,10 @@ customModuleConfigs: { | ||
}; | ||
interceptorConfigs = { | ||
[faker.lorem.word()]: [ | ||
{ | ||
fulfilled: function() {}, | ||
rejected: function() {} | ||
} | ||
] | ||
}; | ||
@@ -50,3 +59,3 @@ getAudiences = this.sandbox | ||
config = new Config( | ||
{ ...baseConfigs, auth: baseAuthConfigs }, | ||
{ ...baseConfigs, auth: authConfigs, interceptors: interceptorConfigs }, | ||
expectedExternalModules | ||
@@ -62,4 +71,4 @@ ); | ||
expect(getAudiences).to.be.calledWith({ | ||
customModuleConfigs: baseAuthConfigs.customModuleConfigs, | ||
env: baseAuthConfigs.env, | ||
customModuleConfigs: authConfigs.customModuleConfigs, | ||
env: authConfigs.env, | ||
externalModules: expectedExternalModules | ||
@@ -78,4 +87,12 @@ }); | ||
it('assigns the provided user auth configurations to the new config', function() { | ||
expect(config.auth).to.include(baseAuthConfigs); | ||
expect(config.auth).to.include(authConfigs); | ||
}); | ||
it('assigns the default interceptors to the new config', function() { | ||
expect(config.interceptors).to.include(defaultConfigs.interceptors); | ||
}); | ||
it('assings the provided user interceptors to the new config', function() { | ||
expect(config.interceptors).to.include(interceptorConfigs); | ||
}); | ||
}); | ||
@@ -82,0 +99,0 @@ |
@@ -130,3 +130,10 @@ import times from 'lodash.times'; | ||
expectedAudienceName = faker.hacker.noun(); | ||
expectedInstance = {}; | ||
expectedInstance = { | ||
config: { | ||
interceptors: { | ||
request: [], | ||
response: [] | ||
} | ||
} | ||
}; | ||
@@ -133,0 +140,0 @@ request = ContxtSdk.prototype._createRequest.call( |
@@ -11,6 +11,7 @@ import axios from 'axios'; | ||
this._audienceName = audienceName; | ||
this._axios = axios.create(); | ||
this._insertHeaders = this._insertHeaders.bind(this); | ||
this._sdk = sdk; | ||
this._axios = axios.create(); | ||
this._axios.interceptors.request.use(this._insertHeaders); | ||
this._attachInterceptors(); | ||
} | ||
@@ -107,2 +108,23 @@ | ||
/** | ||
* Sets up axios interceptors for the request instance | ||
* More information at {@link https://github.com/axios/axios#interceptors axios Interceptors} | ||
* | ||
* @private | ||
*/ | ||
_attachInterceptors() { | ||
const requestInterceptors = [ | ||
{ fulfilled: this._insertHeaders }, | ||
...this._sdk.config.interceptors.request | ||
]; | ||
const responseInterceptors = [...this._sdk.config.interceptors.response]; | ||
requestInterceptors.forEach(({ fulfilled, rejected }) => { | ||
this._axios.interceptors.request.use(fulfilled, rejected); | ||
}); | ||
responseInterceptors.forEach(({ fulfilled, rejected }) => { | ||
this._axios.interceptors.response.use(fulfilled, rejected); | ||
}); | ||
} | ||
/** | ||
* Decorates custom modules onto the SDK instance so they behave as first-class citizens. | ||
@@ -119,3 +141,3 @@ * | ||
*/ | ||
_insertHeaders = (config) => { | ||
_insertHeaders(config) { | ||
return this._sdk.auth | ||
@@ -128,5 +150,5 @@ .getCurrentApiToken(this._audienceName) | ||
}); | ||
}; | ||
} | ||
} | ||
export default Request; |
@@ -16,6 +16,16 @@ import axios from 'axios'; | ||
use: this.sandbox.stub() | ||
}, | ||
response: { | ||
use: this.sandbox.stub() | ||
} | ||
} | ||
}; | ||
baseSdk = {}; | ||
baseSdk = { | ||
config: { | ||
interceptors: { | ||
request: [], | ||
response: [] | ||
} | ||
} | ||
}; | ||
}); | ||
@@ -28,2 +38,3 @@ | ||
describe('constructor', function() { | ||
let attachInterceptors; | ||
let create; | ||
@@ -36,2 +47,6 @@ let expectedAudienceName; | ||
attachInterceptors = this.sandbox.stub( | ||
Request.prototype, | ||
'_attachInterceptors' | ||
); | ||
create = this.sandbox.stub(axios, 'create').returns(baseAxiosInstance); | ||
@@ -46,6 +61,2 @@ | ||
it('appends the supplied sdk to the class instance', function() { | ||
expect(request._sdk).to.equal(baseSdk); | ||
}); | ||
it('creates an axios instance and appends it to the class instance', function() { | ||
@@ -56,9 +67,12 @@ expect(create).to.be.calledOnce; | ||
it('binds and appends the `insertHeaders` method to the class instance', function() { | ||
expect(request._insertHeaders.name).to.equal('bound _insertHeaders'); | ||
}); | ||
it('appends the supplied sdk to the class instance', function() { | ||
expect(request._sdk).to.equal(baseSdk); | ||
}); | ||
it("sets up axios's interceptors", function() { | ||
expect(baseAxiosInstance.interceptors.request.use).to.be.calledOnce; | ||
const [ | ||
requestInterceptor | ||
] = baseAxiosInstance.interceptors.request.use.firstCall.args; | ||
expect(requestInterceptor).to.be.a('function'); | ||
expect(requestInterceptor).to.equal(request._insertHeaders); | ||
expect(attachInterceptors).to.be.calledOnce; | ||
}); | ||
@@ -113,2 +127,67 @@ }); | ||
describe('_attachInterceptors', function() { | ||
let expectedRequestInterceptors; | ||
let expectedResponseInterceptors; | ||
let requestUse; | ||
let responseUse; | ||
beforeEach(function() { | ||
const requestInterceptors = times( | ||
faker.random.number({ min: 0, max: 10 }), | ||
() => { | ||
return { | ||
fulfilled: this.sandbox.stub(), | ||
rejected: this.sandbox.stub() | ||
}; | ||
} | ||
); | ||
const responseInterceptors = times( | ||
faker.random.number({ min: 0, max: 10 }), | ||
() => { | ||
return { | ||
fulfilled: this.sandbox.stub(), | ||
rejected: this.sandbox.stub() | ||
}; | ||
} | ||
); | ||
expectedRequestInterceptors = [ | ||
{ fulfilled: Request.prototype._insertHeaders } | ||
].concat(requestInterceptors); | ||
expectedResponseInterceptors = responseInterceptors; | ||
requestUse = this.sandbox.stub(); | ||
responseUse = this.sandbox.stub(); | ||
Request.prototype._attachInterceptors.call({ | ||
_axios: { | ||
interceptors: { | ||
request: { use: requestUse }, | ||
response: { use: responseUse } | ||
} | ||
}, | ||
_insertHeaders: Request.prototype._insertHeaders, | ||
_sdk: { | ||
config: { | ||
interceptors: { | ||
request: requestInterceptors, | ||
response: responseInterceptors | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
it('sets up the request interceptors', function() { | ||
expectedRequestInterceptors.forEach(({ fulfilled, rejected }) => { | ||
expect(requestUse).to.be.calledWith(fulfilled, rejected); | ||
}); | ||
}); | ||
it('sets up the response interceptors', function() { | ||
expectedResponseInterceptors.forEach(({ fulfilled, rejected }) => { | ||
expect(responseUse).to.be.calledWith(fulfilled, rejected); | ||
}); | ||
}); | ||
}); | ||
describe('_insertHeaders', function() { | ||
@@ -115,0 +194,0 @@ let expectedAudienceName; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
625802
9051