@neoskop/aviation-client
Advanced tools
Comparing version 0.2.2 to 0.2.3
@@ -8,2 +8,3 @@ import { AviationClient } from "./aviation-client"; | ||
private _cacheTime; | ||
private _webSocketEnabled; | ||
endpoint(endpointUrl: string): AviationClientBuilder; | ||
@@ -13,3 +14,4 @@ token(token: string): AviationClientBuilder; | ||
meta(meta: any): AviationClientBuilder; | ||
websocket(webSocketEnabled: boolean): AviationClientBuilder; | ||
mix(): AviationClient; | ||
} |
@@ -11,3 +11,4 @@ "use strict"; | ||
this._meta = {}; | ||
this._cacheTime = 10; | ||
this._cacheTime = 3600; | ||
this._webSocketEnabled = true; | ||
} | ||
@@ -30,4 +31,8 @@ AviationClientBuilder.prototype.endpoint = function (endpointUrl) { | ||
}; | ||
AviationClientBuilder.prototype.websocket = function (webSocketEnabled) { | ||
this._webSocketEnabled = webSocketEnabled; | ||
return this; | ||
}; | ||
AviationClientBuilder.prototype.mix = function () { | ||
return new aviation_client_1.AviationClient(this._endpointUrl, this._token, this._cacheTime, this._meta); | ||
return new aviation_client_1.AviationClient(this._endpointUrl, this._token, this._cacheTime, this._meta, this._webSocketEnabled); | ||
}; | ||
@@ -34,0 +39,0 @@ return AviationClientBuilder; |
import { AviationFeature } from "./model/aviation-feature"; | ||
import { AviationConnectionInfo } from "./aviation-connection-info"; | ||
export declare class AviationClient { | ||
static _featureCaches: Object; | ||
private _meta; | ||
private _endpointUrl; | ||
private _token; | ||
private _featureMap; | ||
private _connectionInfo; | ||
private _cachingTime; | ||
private _featureLoadingTime; | ||
constructor(endpointUrl: string, token: string, cachingTime?: number, meta?: any); | ||
constructor(endpointUrl: string, token: string, cachingTime?: number, meta?: any, webSocketEnabled?: boolean); | ||
feature(name: string): Promise<AviationFeature>; | ||
private cacheIsStale(); | ||
readonly connectionInfo: AviationConnectionInfo; | ||
updateFeature(updatedFeature: AviationFeature): void; | ||
} |
@@ -42,21 +42,26 @@ "use strict"; | ||
var request = require("superagent"); | ||
var aviation_connection_info_1 = require("./aviation-connection-info"); | ||
var aviation_feature_monitor_1 = require("./aviation-feature-monitor"); | ||
var aviation_cache_1 = require("./model/aviation-cache"); | ||
var AviationClient = (function () { | ||
function AviationClient(endpointUrl, token, cachingTime, meta) { | ||
if (cachingTime === void 0) { cachingTime = 10; } | ||
this._endpointUrl = endpointUrl; | ||
this._token = token; | ||
function AviationClient(endpointUrl, token, cachingTime, meta, webSocketEnabled) { | ||
if (cachingTime === void 0) { cachingTime = 3600; } | ||
if (webSocketEnabled === void 0) { webSocketEnabled = true; } | ||
this._cachingTime = cachingTime; | ||
this._connectionInfo = new aviation_connection_info_1.AviationConnectionInfo(endpointUrl, token); | ||
this._meta = meta; | ||
if (webSocketEnabled) { | ||
aviation_feature_monitor_1.AviationFeatureMonitor.subscribe(this); | ||
} | ||
} | ||
AviationClient.prototype.feature = function (name) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _this = this; | ||
var res; | ||
var res, featureMap_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!(this._featureMap == null || this.cacheIsStale())) return [3 /*break*/, 2]; | ||
if (!(AviationClient._featureCaches[this._connectionInfo.key] == null || AviationClient._featureCaches[this._connectionInfo.key].isStale())) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, request | ||
.get(this._endpointUrl + '/features') | ||
.set('Authorization', 'Bearer ' + this._token) | ||
.get(this._connectionInfo.url + '/features') | ||
.set('Authorization', 'Bearer ' + this._connectionInfo.token) | ||
.set('Accept', 'application/json') | ||
@@ -67,8 +72,8 @@ .accept('json')]; | ||
if (res.status == 200) { | ||
this._featureMap = new Map(); | ||
this._featureLoadingTime = new Date().getTime(); | ||
featureMap_1 = {}; | ||
res.body.forEach(function (f) { | ||
var feature = new aviation_feature_1.AviationFeature(f); | ||
_this._featureMap.set(feature.name, feature); | ||
featureMap_1[feature.name] = feature; | ||
}); | ||
AviationClient._featureCaches[this._connectionInfo.key] = new aviation_cache_1.AviationCache(featureMap_1, this._cachingTime); | ||
} | ||
@@ -79,3 +84,7 @@ else { | ||
_a.label = 2; | ||
case 2: return [2 /*return*/, this._featureMap.has(name) ? this._featureMap.get(name) : Promise.reject(new feature_unmanaged_error_1.FeatureUnmanagedError())]; | ||
case 2: | ||
if (AviationClient._featureCaches[this._connectionInfo.key] != null && AviationClient._featureCaches[this._connectionInfo.key].has(name)) { | ||
return [2 /*return*/, AviationClient._featureCaches[this._connectionInfo.key].get(name)]; | ||
} | ||
return [2 /*return*/, Promise.reject(new feature_unmanaged_error_1.FeatureUnmanagedError())]; | ||
} | ||
@@ -85,5 +94,14 @@ }); | ||
}; | ||
AviationClient.prototype.cacheIsStale = function () { | ||
return this._featureLoadingTime + this._cachingTime < new Date().getTime() * 1000; | ||
Object.defineProperty(AviationClient.prototype, "connectionInfo", { | ||
get: function () { | ||
return this._connectionInfo; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
AviationClient.prototype.updateFeature = function (updatedFeature) { | ||
var featureCache = AviationClient._featureCaches[this._connectionInfo.key]; | ||
featureCache.update(updatedFeature); | ||
}; | ||
AviationClient._featureCaches = {}; | ||
return AviationClient; | ||
@@ -90,0 +108,0 @@ }()); |
@@ -5,2 +5,3 @@ /// <reference types="node" /> | ||
private _name; | ||
private _title; | ||
private _enabled; | ||
@@ -10,2 +11,3 @@ private _functionCode; | ||
constructor(feature: any); | ||
title: string; | ||
readonly name: string; | ||
@@ -12,0 +14,0 @@ readonly enabled: boolean; |
@@ -7,2 +7,3 @@ "use strict"; | ||
this._name = feature['name']; | ||
this._title = feature['title']; | ||
this._enabled = feature['enabled']; | ||
@@ -12,2 +13,12 @@ this._functionCode = feature['functionCode']; | ||
} | ||
Object.defineProperty(AviationFeature.prototype, "title", { | ||
get: function () { | ||
return this._title; | ||
}, | ||
set: function (value) { | ||
this._title = value; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(AviationFeature.prototype, "name", { | ||
@@ -14,0 +25,0 @@ get: function () { |
@@ -43,27 +43,43 @@ "use strict"; | ||
var sinon = require("sinon"); | ||
var mongodb_1 = require("mongodb"); | ||
var request = require("superagent"); | ||
var aviation_feature_1 = require("../model/aviation-feature"); | ||
beforeEach(function () { | ||
_this.clock = sinon.useFakeTimers(); | ||
aviation_client_1.AviationClient._featureCaches = {}; | ||
}); | ||
before(function () { | ||
chai.should(); | ||
chai.use(chaiAsPromised); | ||
_this.clock = sinon.useFakeTimers(); | ||
}); | ||
after(function () { | ||
afterEach(function () { | ||
_this.clock.restore(); | ||
}); | ||
var endpointTestUrl = process.env['ENDPOINT_TEST_URL'] || 'http://localhost:8080'; | ||
var changeFeatureTitle = function (sut, newTitle) { | ||
return sut.feature('test-feature-1').catch(function (err) { return console.log(err); }).then(function (feature) { | ||
var clonedFeature = new aviation_feature_1.AviationFeature(feature); | ||
clonedFeature.title = newTitle; | ||
return request | ||
.put(endpointTestUrl + '/projects/example-1/features/test-feature-1') | ||
.set('X-Authenticated', 'true') | ||
.set('Accept', 'application/json') | ||
.accept('json') | ||
.send(clonedFeature); | ||
}); | ||
}; | ||
describe('Aviation client', function () { | ||
it('should fail to return a feature for wrong endpoints', function () { | ||
var sut = new aviation_client_1.AviationClient('http://localhost:1234', 'wrongtoken'); | ||
var sut = new aviation_client_1.AviationClient('http://localhost:1234', 'wrongtoken', 3600, {}, false); | ||
return sut.feature('test').should.eventually.be.rejected; | ||
}); | ||
it('should fail to return a feature for wrong token', function () { | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'wrongtoken'); | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'wrongtoken', 3600, {}, false); | ||
return sut.feature('test').should.eventually.be.rejected; | ||
}); | ||
it('should fail to return a feature for non-managed feature', function () { | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t'); | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t', 3600, {}, false); | ||
return sut.feature('test').should.eventually.be.rejected; | ||
}); | ||
it('should return feature', function () { | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t'); | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t', 3600, {}, false); | ||
sut.feature('test-feature-1').catch(function (err) { return console.log(err); }); | ||
@@ -73,3 +89,3 @@ return sut.feature('test-feature-1').should.eventually.be.fulfilled; | ||
it('should return feature that can be evaluated', function () { | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t'); | ||
var sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t', 3600, {}, false); | ||
sut.feature('test-feature-1').catch(function (err) { return console.log(err); }); | ||
@@ -80,25 +96,29 @@ return sut.feature('test-feature-1').should.eventually.be.fulfilled.and.then(function (f) { | ||
}); | ||
it('should pickup feature changes after 10 seconds per default', function () { return __awaiter(_this, void 0, void 0, function () { | ||
var sut, db, project; | ||
it('should pickup feature changes after cache timeout', function () { return __awaiter(_this, void 0, void 0, function () { | ||
var sut; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t'); | ||
return [4 /*yield*/, sut.feature('test-feature-1').catch(function (err) { return console.log(err); })]; | ||
sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t', 3600, {}, false); | ||
return [4 /*yield*/, changeFeatureTitle(sut, 'test 1')]; | ||
case 1: | ||
_a.sent(); | ||
return [4 /*yield*/, mongodb_1.MongoClient.connect('mongodb://mongo:27017/aviation')]; | ||
case 2: | ||
db = _a.sent(); | ||
return [4 /*yield*/, db.collection('projects').findOne({ token: 'sup3rs3cr3t' })]; | ||
case 3: | ||
project = _a.sent(); | ||
project.features[0].enabled = false; | ||
return [4 /*yield*/, db.collection('projects').findOneAndUpdate({ token: 'sup3rs3cr3t' }, project)]; | ||
case 4: | ||
this.clock.tick(60 * 60 * 1000); | ||
return [2 /*return*/, sut.feature('test-feature-1').should.eventually.be.fulfilled.and.then(function (f) { | ||
return f.title.should.equal('test 1'); | ||
})]; | ||
} | ||
}); | ||
}); }); | ||
it('should not pickup feature changes before cache timeout', function () { return __awaiter(_this, void 0, void 0, function () { | ||
var sut; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t', 3600, {}, false); | ||
return [4 /*yield*/, changeFeatureTitle(sut, 'test 2')]; | ||
case 1: | ||
_a.sent(); | ||
this.clock.tick(10000); | ||
return [2 /*return*/, sut.feature('test-feature-1').should.eventually.be.fulfilled.and.then(function (f) { | ||
sut.feature('test-feature-1').catch(function (err) { return console.log(err); }); | ||
return f.evaluate().should.be.false; | ||
return f.title.should.not.equal('test 2'); | ||
})]; | ||
@@ -108,3 +128,18 @@ } | ||
}); }); | ||
it('should pickup feature changes immediately via WebSockets', function () { return __awaiter(_this, void 0, void 0, function () { | ||
var sut; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
sut = new aviation_client_1.AviationClient(endpointTestUrl, 'sup3rs3cr3t'); | ||
return [4 /*yield*/, changeFeatureTitle(sut, 'test 3')]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/, sut.feature('test-feature-1').should.eventually.be.fulfilled.and.then(function (f) { | ||
return f.title.should.equal('test 3'); | ||
})]; | ||
} | ||
}); | ||
}); }); | ||
}); | ||
//# sourceMappingURL=aviation-client.spec.js.map |
{ | ||
"name": "@neoskop/aviation-client", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"main": "dist/index.js", | ||
@@ -17,5 +17,4 @@ "typings": "dist/index.d.ts", | ||
"dependencies": { | ||
"@types/node": "^7.0.29", | ||
"@types/superagent": "^2.0.37", | ||
"superagent": "^3.5.2" | ||
"superagent": "^3.5.2", | ||
"ws": "^3.0.0" | ||
}, | ||
@@ -28,4 +27,6 @@ "devDependencies": { | ||
"@types/mocha": "^2.2.41", | ||
"@types/mongodb": "^2.2.7", | ||
"@types/node": "^7.0.29", | ||
"@types/sinon": "^2.3.2", | ||
"@types/superagent": "^2.0.37", | ||
"@types/ws": "^3.0.1", | ||
"chai": "3.x.x", | ||
@@ -36,3 +37,2 @@ "chai-as-promised": "^6.0.0", | ||
"mocha": "^3.4.2", | ||
"mongodb": "^2.2.29", | ||
"node-localstorage": "^1.3.0", | ||
@@ -44,3 +44,7 @@ "node-mocks-http": "^1.6.3", | ||
"typescript": "^2.4.1" | ||
}, | ||
"optionalDependencies": { | ||
"bufferutil": "^3.0.2", | ||
"utf-8-validate": "^3.0.3" | ||
} | ||
} |
@@ -36,3 +36,3 @@ ![Aviation](https://bytebucket.org/neoskop/aviation-client-typescript/raw/master/logo.png) | ||
```sh | ||
$ docker-compose -f docker-compose.test.yml up --abort-on-container-exit --build | ||
$ docker pull neoskop/aviation:backend && docker-compose -f docker-compose.test.yml up --abort-on-container-exit --build | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
55849
41
796
4
20
+ Addedws@^3.0.0
+ Addedansi-regex@2.1.1(transitive)
+ Addedaproba@1.2.0(transitive)
+ Addedare-we-there-yet@1.1.7(transitive)
+ Addedasync-limiter@1.0.1(transitive)
+ Addedbindings@1.3.1(transitive)
+ Addedbl@1.2.3(transitive)
+ Addedbuffer-alloc@1.2.0(transitive)
+ Addedbuffer-alloc-unsafe@1.1.0(transitive)
+ Addedbuffer-fill@1.0.0(transitive)
+ Addedbufferutil@3.0.5(transitive)
+ Addedchownr@1.1.4(transitive)
+ Addedcode-point-at@1.1.0(transitive)
+ Addedconsole-control-strings@1.1.0(transitive)
+ Addeddecompress-response@3.3.0(transitive)
+ Addeddeep-extend@0.6.0(transitive)
+ Addeddelegates@1.0.0(transitive)
+ Addeddetect-libc@1.0.3(transitive)
+ Addedend-of-stream@1.4.4(transitive)
+ Addedexpand-template@1.1.1(transitive)
+ Addedfs-constants@1.0.0(transitive)
+ Addedgauge@2.7.4(transitive)
+ Addedgithub-from-package@0.0.0(transitive)
+ Addedhas-unicode@2.0.1(transitive)
+ Addedini@1.3.8(transitive)
+ Addedis-fullwidth-code-point@1.0.0(transitive)
+ Addedmimic-response@1.0.1(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addednan@2.10.02.7.0(transitive)
+ Addednode-abi@2.30.1(transitive)
+ Addednoop-logger@0.1.1(transitive)
+ Addednpmlog@4.1.2(transitive)
+ Addednumber-is-nan@1.0.1(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-homedir@1.0.2(transitive)
+ Addedprebuild-install@2.3.04.0.0(transitive)
+ Addedpump@1.0.32.0.1(transitive)
+ Addedrc@1.2.8(transitive)
+ Addedsemver@5.7.2(transitive)
+ Addedset-blocking@2.0.0(transitive)
+ Addedsignal-exit@3.0.7(transitive)
+ Addedsimple-concat@1.0.1(transitive)
+ Addedsimple-get@1.4.32.8.2(transitive)
+ Addedstring-width@1.0.2(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedstrip-json-comments@2.0.1(transitive)
+ Addedtar-fs@1.16.4(transitive)
+ Addedtar-stream@1.6.2(transitive)
+ Addedto-buffer@1.1.1(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedultron@1.1.1(transitive)
+ Addedunzip-response@1.0.2(transitive)
+ Addedutf-8-validate@3.0.4(transitive)
+ Addedwhich-pm-runs@1.1.0(transitive)
+ Addedwide-align@1.1.5(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedws@3.3.3(transitive)
+ Addedxtend@4.0.14.0.2(transitive)
- Removed@types/node@^7.0.29
- Removed@types/superagent@^2.0.37
- Removed@types/node@7.10.14(transitive)
- Removed@types/superagent@2.3.5(transitive)