Comparing version
62
index.js
var rest = require('superagent'); | ||
var _ = require('underscore'); | ||
var crypto = require('crypto'); | ||
var qs = require('querystring'); | ||
@@ -28,4 +29,4 @@ function KeenApi(config) { | ||
.set('Authorization', apiKey) | ||
.end(function(res) { | ||
processResponse(res, callback); | ||
.end(function(err, res) { | ||
processResponse(err, res, callback); | ||
}); | ||
@@ -39,4 +40,4 @@ }, | ||
.send(data || {}) | ||
.end(function(res) { | ||
processResponse(res, callback); | ||
.end(function(err, res) { | ||
processResponse(err, res, callback); | ||
}); | ||
@@ -49,4 +50,4 @@ }, | ||
.set('Content-Length', 0) | ||
.end(function(res) { | ||
processResponse(res, callback); | ||
.end(function(err, res) { | ||
processResponse(err, res, callback); | ||
}); | ||
@@ -58,10 +59,13 @@ } | ||
// The error handling should be strengthened over time to be more meaningful and robust | ||
function processResponse(res, callback) { | ||
function processResponse(err, res, callback) { | ||
callback = callback || function() {}; | ||
if (res.ok) { | ||
return callback(undefined, res.body); | ||
if (res && !res.ok && !err) { | ||
var is_err = res.body && res.body.error_code; | ||
err = new Error(is_err ? res.body.message : 'Unknown error occurred'); | ||
err.code = is_err ? res.body.error_code : 'UnknownError'; | ||
} | ||
var error = typeof res.body == 'object' && typeof res.body.error_code == 'string' ? res.body.error_code : 'UnknownError'; | ||
callback(new Error(error)); | ||
if (err) return callback(err); | ||
return callback(null, res.body); | ||
} | ||
@@ -135,2 +139,36 @@ | ||
this.request = function(method, keyType, path, params, callback) { | ||
method = typeof method === 'string' && method.toLowerCase(); | ||
keyType += 'Key'; | ||
callback = callback || (typeof params === 'function') && params; | ||
if (typeof path === 'string') { | ||
path = '/projects/' + this.projectId + '/' + path.replace(/^\//,''); | ||
} else { | ||
throw new Error('\'path\' must be a string.'); | ||
} | ||
if (params && typeof params !== 'function') { | ||
path += '?' + qs.stringify(params); | ||
} | ||
if ( ! request.hasOwnProperty(method)) { | ||
throw new Error('Method must be of type: GET/POST/DEL'); | ||
} | ||
if (!this.hasOwnProperty(keyType)) { | ||
throw new Error('Key must be of type: master/write/read'); | ||
} | ||
if (!this[keyType]) { | ||
throw new Error('You must specify a nun-null, non-empty \'' + keyType + '\' in your config object.'); | ||
} | ||
if(method === 'post') { | ||
return request.post(this[keyType], path, params, callback); | ||
} | ||
request[method](this[keyType], path, callback); | ||
}; | ||
this.addEvents = function(events, callback) { | ||
@@ -182,2 +220,2 @@ if (!this.writeKey) { | ||
decryptScopedKey: decryptScopedKey | ||
}; | ||
}; |
{ | ||
"name": "keen.io", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Keen IO NodeJS module. Keen IO is a hosted API to collect, analyze, and visualize your data.", | ||
@@ -34,3 +34,3 @@ "homepage": "https://github.com/keenlabs/KeenClient-Node", | ||
"engines": { | ||
"node": ">= 0.6.0" | ||
"node": ">= 0.8.0" | ||
}, | ||
@@ -50,9 +50,9 @@ "keywords": [ | ||
"superagent": "~0.13.0", | ||
"underscore": "~1.4.4" | ||
"underscore": "~1.5.2" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.9.0", | ||
"should": "~1.2.2", | ||
"nock": "~0.17.5" | ||
"mocha": "~1.16.1", | ||
"should": "~2.1.1", | ||
"nock": "~0.27.0" | ||
} | ||
} |
@@ -9,7 +9,11 @@ # Keen IO - NodeJS | ||
Use npm to install! | ||
```node | ||
`npm install keen.io` | ||
``` | ||
## Examples | ||
### Initialisation | ||
### Initialization | ||
@@ -101,16 +105,22 @@ ```javascript | ||
Future module updates are planned to introduce the remaining api calls. You can see some of the spec for that in examples/queries.js. Also as mentioned above specifying options when creating an instance to configure the behaviour of the instance (ie, batching event submissions). | ||
Future module updates are planned to introduce the remaining API calls. You can see some of the spec for that in [examples/queries.js](https://github.com/keenlabs/KeenClient-Node/blob/master/examples/queries.js). Also, as mentioned above, specifying options when creating an instance to configure the behaviour of the instance (ie, batching event submissions). | ||
## Contributing | ||
Please feel free to contribute, pull requests very welcome. The aim is to build up this module to completely represent the API provided by Keen IO which quite extensive so the more contributions the better. | ||
This is an open source project and we love involvement from the community! Hit us up with pull requests and issues. | ||
The aim is to build up this module to completely represent the API provided by Keen IO, which is quite extensive. The more contributions the better! | ||
## Further Reading | ||
Keen IO - Website: https://keen.io/ | ||
[Keen IO - Website](https://keen.io/) | ||
Keen IO - API Technical Reference: https://keen.io/docs/api/reference/ | ||
[Keen IO - API Technical Reference](https://keen.io/docs/api/reference/) | ||
## Release History | ||
### 0.0.4 | ||
- Update dependencies. | ||
### 0.0.3 | ||
@@ -117,0 +127,0 @@ |
@@ -1,2 +0,3 @@ | ||
var should = require("should") | ||
/* jshint quotmark:false,indent:4,maxlen:600 */ | ||
var should = require("should"); | ||
@@ -85,3 +86,3 @@ describe("keen", function() { | ||
keen.addEvent("eventCollection", {}, function(error, responseBody) { | ||
keen.addEvent("eventCollection", {}, function(error) { | ||
should.exist(error); | ||
@@ -99,2 +100,8 @@ error.message.should.equal("You must specify a non-null, non-empty 'writeKey' in your 'config' object when calling keen.configure()!"); | ||
var mockGetRequest = function(path, responseCode, responseBody) { | ||
nock("https://api.keen.io") | ||
.get(path) | ||
.reply(responseCode, responseBody, {"Content-Type": "application/json"}); | ||
}; | ||
it("addEvent should make correct HTTP request", function(done) { | ||
@@ -122,3 +129,3 @@ var eventCollection = "purchases"; | ||
JSON.stringify(responseBody).should.equal(JSON.stringify({"collection1": [{success: true}]})); | ||
done(); | ||
done(); | ||
}); | ||
@@ -154,9 +161,77 @@ }); | ||
var options = keen.decryptScopedKey(apiKey, scopedKey); | ||
var expected = { | ||
var expected = { | ||
filters:[ { property_name: 'account_id', | ||
operator: 'eq', | ||
property_value: '4d9a4c421d011c553e000001' } ] | ||
} | ||
property_value: '4d9a4c421d011c553e000001' } ] | ||
}; | ||
expected.should.eql(options); | ||
}); | ||
}); | ||
it("should handle API errors", function(done) { | ||
var id = 'foo'; | ||
var mockResponse = {error_code: 'FooError', message: 'no foo'}; | ||
mockPostRequest("/3.0/projects/"+projectId+"/events/"+id, 500, mockResponse); | ||
keen.addEvent(id, {}, function(err) { | ||
err.should.be.an.instanceOf(Error); | ||
err.should.have.property('message', mockResponse.message); | ||
err.should.have.property('code', mockResponse.error_code); | ||
done(); | ||
}); | ||
}); | ||
describe('request', function() { | ||
it("should expect a GET/POST/DEL method", function() { | ||
should(function() { | ||
keen.request('foo', 'write', '/'); | ||
}).throwError('Method must be of type: GET/POST/DEL'); | ||
}); | ||
it("should expect a write/read/master keytype", function() { | ||
should(function() { | ||
keen.request('get', 'foo', '/'); | ||
}).throwError('Key must be of type: master/write/read'); | ||
}); | ||
it("should require a string path", function() { | ||
should(function() { | ||
keen.request('get', 'read'); | ||
}).throwError('\'path\' must be a string.'); | ||
}); | ||
it("should expect a key to be set", function() { | ||
should(function() { | ||
keen.request('get', 'read', '/'); | ||
}).throwError('You must specify a nun-null, non-empty \'readKey\' in your config object.'); | ||
}); | ||
describe('send the request', function() { | ||
var projectId = "projectId"; | ||
var baseUrl = "https://api.keen.io/"; | ||
var apiVersion = "3.0"; | ||
var mockResponse = {result: 1}; | ||
var keen = require('../').configure({ | ||
projectId: projectId, | ||
baseUrl: baseUrl, | ||
apiVersion: apiVersion, | ||
readKey: 'foo' | ||
}); | ||
it('should send the request', function() { | ||
mockGetRequest("/3.0/projects/"+projectId+"/queries/count?event_collection=foo", 200, mockResponse); | ||
keen.request('get', 'read', '/queries/count', {event_collection:'foo'}, function(err, res) { | ||
(err === null).should.be.true; | ||
res.should.eql(mockResponse); | ||
}); | ||
}); | ||
it('has optional params', function() { | ||
mockGetRequest("/3.0/projects/"+projectId+"/queries/count?event_collection=bar", 200, mockResponse); | ||
keen.request('get', 'read', '/queries/count?event_collection=bar', function(err, res) { | ||
(err === null).should.be.true; | ||
res.should.eql(mockResponse); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
23930
24.64%13
8.33%508
27.96%144
7.46%+ Added
- Removed
Updated