heroku-client
Advanced tools
Comparing version 0.5.2 to 0.6.0
@@ -21,2 +21,3 @@ var https = require('https'), | ||
this.deferred = q.defer(); | ||
this.nextRange = 'id ]..; max=1000'; | ||
@@ -63,3 +64,4 @@ _.bindAll(this); | ||
'Accept': 'application/vnd.heroku+json; version=3', | ||
'Content-type': 'application/json' | ||
'Content-type': 'application/json', | ||
'Range': this.nextRange | ||
}, this.options.headers || {}); | ||
@@ -100,3 +102,3 @@ | ||
var key = this.options.path + '-' + this.options.cacheKeyPostfix; | ||
var key = this.options.path + '-' + this.nextRange + '-' + this.options.cacheKeyPostfix; | ||
@@ -119,4 +121,9 @@ cache.get(key, function (err, res) { | ||
if (res.statusCode === 304 && this.cachedResponse) { | ||
this.deferred.resolve(this.cachedResponse.body); | ||
this.callback(null, this.cachedResponse.body); | ||
if (this.cachedResponse.nextRange) { | ||
this.nextRequest(this.cachedResponse.nextRange, this.cachedResponse.body); | ||
} else { | ||
this.updateAggregate(this.cachedResponse.body); | ||
this.deferred.resolve(this.aggregate); | ||
this.callback(null, this.aggregate); | ||
} | ||
} else { | ||
@@ -252,4 +259,9 @@ buffer = ''; | ||
deferred.resolve(body); | ||
callback(null, body); | ||
if (res.headers['next-range']) { | ||
this.nextRequest(res.headers['next-range'], body); | ||
} else { | ||
this.updateAggregate(body); | ||
deferred.resolve(this.aggregate); | ||
callback(null, this.aggregate); | ||
} | ||
} | ||
@@ -259,2 +271,14 @@ | ||
/* | ||
* Since this request isn't the full response (206 or | ||
* 304 with a cached Next-Range), perform the next | ||
* request for more data. | ||
*/ | ||
Request.prototype.nextRequest = function nextRequest (nextRange, body) { | ||
this.updateAggregate(body); | ||
this.nextRange = nextRange; | ||
this.request(); | ||
} | ||
/* | ||
* If the cache client is alive, write the | ||
@@ -268,7 +292,8 @@ * provided response and body to the cache. | ||
key = path + '-' + cacheKeyPostfix; | ||
key = path + '-' + this.nextRange + '-' + cacheKeyPostfix; | ||
value = JSON.stringify({ | ||
body: body, | ||
etag: res.headers.etag | ||
etag: res.headers.etag, | ||
nextRange: res.headers['next-range'] | ||
}); | ||
@@ -281,2 +306,16 @@ | ||
/* | ||
* If given an object, sets aggregate to object, | ||
* otherwise concats array onto aggregate. | ||
*/ | ||
Request.prototype.updateAggregate = function updateAggregate (aggregate) { | ||
if (aggregate instanceof Array) { | ||
this.aggregate || (this.aggregate = []); | ||
this.aggregate = this.aggregate.concat(aggregate); | ||
} else { | ||
this.aggregate = aggregate; | ||
} | ||
} | ||
/* | ||
* Connect a cache client. | ||
@@ -283,0 +322,0 @@ */ |
{ | ||
"name": "heroku-client", | ||
"version": "0.5.2", | ||
"version": "0.6.0", | ||
"description": "A wrapper for the Heroku v3 API", | ||
@@ -22,3 +22,6 @@ "main": "./lib/heroku.js", | ||
"devDependencies": { | ||
"jasmine-node": "~1.11.0" | ||
"jasmine-node": "~1.11.0", | ||
"grunt": "~0.4.1", | ||
"grunt-contrib-watch": "~0.5.3", | ||
"grunt-shell": "~0.4.0" | ||
}, | ||
@@ -29,4 +32,5 @@ "dependencies": { | ||
"inflection": "~1.2.6", | ||
"lodash": "~1.3.1" | ||
"lodash": "~1.3.1", | ||
"grunt": "~0.4.1" | ||
} | ||
} |
@@ -11,2 +11,6 @@ # heroku-client [![Build Status](https://travis-ci.org/heroku/node-heroku-client.png?branch=master)](https://travis-ci.org/heroku/node-heroku-client) | ||
## Documentation | ||
Docs are auto-generated and live in the [docs directory](https://github.com/heroku/node-heroku-client/tree/development/docs). | ||
## Usage | ||
@@ -110,3 +114,3 @@ | ||
Documentation for node-heroku is auto-generated from [the resources manifest](https://github.com/heroku/node-heroku-client/blob/development/lib/resources.js). | ||
Documentation for heroku-client is auto-generated from [the resources manifest](https://github.com/heroku/node-heroku-client/blob/development/lib/resources.js). | ||
Docs are generated like so: | ||
@@ -122,3 +126,3 @@ | ||
node-heroku uses [jasmine-node][jasmine-node] for tests: | ||
heroku-client uses [jasmine-node][jasmine-node] for tests: | ||
@@ -125,0 +129,0 @@ ```bash |
@@ -104,3 +104,4 @@ var https = require("https"), | ||
'Accept': 'application/vnd.heroku+json; version=3', | ||
'Content-type': 'application/json' | ||
'Content-type': 'application/json', | ||
'Range': 'id ]..; max=1000' | ||
} | ||
@@ -152,2 +153,26 @@ | ||
describe('handling Range headers', function() { | ||
it('sends a default Range header', function() { | ||
makeRequest('/apps', {}, function (err, body) { | ||
expect(https.request.mostRecentCall.args[0].headers['Range']).toEqual('id ]..; max=1000'); | ||
}); | ||
}); | ||
describe('when receiving a Next-Range header', function() { | ||
it('sends the Next-Range header on the next request', function(done) { | ||
makeRequest('/apps', {}, function (err, body) { | ||
expect(https.request.mostRecentCall.args[0].headers['Range']).toEqual('id abcdefg..; max=1000'); | ||
done(); | ||
}, { response: { headers: { 'next-range': 'id abcdefg..; max=1000' } } }); | ||
}); | ||
it('aggregates response bodies', function(done) { | ||
makeRequest('/apps', {}, function (err, body) { | ||
expect(body).toEqual([{ message: 'ok' }, { message: 'ok' }]); | ||
done(); | ||
}, { returnArray: true, response: { headers: { 'next-range': 'id abcdefg..; max=1000' } } }); | ||
}); | ||
}); | ||
}); | ||
describe('caching', function() { | ||
@@ -172,3 +197,3 @@ var cache = new MockCache(); | ||
makeRequest('/apps', { cacheKeyPostfix: '123' }, function(err, body) { | ||
expect(cache.get).toHaveBeenCalledWith('/apps-123', jasmine.any(Function)); | ||
expect(cache.get).toHaveBeenCalledWith('/apps-id ]..; max=1000-123', jasmine.any(Function)); | ||
done(); | ||
@@ -194,3 +219,3 @@ }); | ||
expect(cache.set).toHaveBeenCalledWith('/apps-123', expectedCache); | ||
expect(cache.set).toHaveBeenCalledWith('/apps-id ]..; max=1000-123', expectedCache); | ||
done(); | ||
@@ -207,2 +232,6 @@ }, { response: { headers: { etag: '123' } } }); | ||
spyOn(https, 'request').andCallFake(function (options, httpsCallback) { | ||
if (options.headers.Range !== 'id ]..; max=1000') { | ||
testOptions.response.headers['next-range'] = undefined; | ||
} | ||
var req = new MockRequest(), | ||
@@ -214,3 +243,8 @@ res = new MockResponse(testOptions.response || {}); | ||
setTimeout(function () { | ||
res.emit('data', '{ "message": "ok" }'); | ||
if (testOptions.returnArray) { | ||
res.emit('data', '[{ "message": "ok" }]'); | ||
} else { | ||
res.emit('data', '{ "message": "ok" }'); | ||
} | ||
if (!req.isAborted) res.emit('end'); | ||
@@ -217,0 +251,0 @@ }, testOptions.timeout || 0); |
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
151359
40
2579
134
5
4
+ Addedgrunt@~0.4.1
+ Addedabbrev@1.1.1(transitive)
+ Addedargparse@0.1.16(transitive)
+ Addedasync@0.1.22(transitive)
+ Addedcoffee-script@1.3.3(transitive)
+ Addedcolors@0.6.2(transitive)
+ Addeddateformat@1.0.2-1.2.3(transitive)
+ Addedesprima@1.0.4(transitive)
+ Addedeventemitter2@0.4.14(transitive)
+ Addedexit@0.1.2(transitive)
+ Addedfindup-sync@0.1.3(transitive)
+ Addedgetobject@0.1.0(transitive)
+ Addedglob@3.1.213.2.11(transitive)
+ Addedgraceful-fs@1.2.3(transitive)
+ Addedgrunt@0.4.5(transitive)
+ Addedgrunt-legacy-log@0.1.3(transitive)
+ Addedgrunt-legacy-log-utils@0.1.1(transitive)
+ Addedgrunt-legacy-util@0.2.0(transitive)
+ Addedhooker@0.2.3(transitive)
+ Addediconv-lite@0.2.11(transitive)
+ Addedinherits@1.0.22.0.4(transitive)
+ Addedjs-yaml@2.0.5(transitive)
+ Addedlodash@0.9.22.4.2(transitive)
+ Addedlru-cache@2.7.3(transitive)
+ Addedminimatch@0.2.140.3.0(transitive)
+ Addednopt@1.0.10(transitive)
+ Addedrimraf@2.2.8(transitive)
+ Addedsigmund@1.0.1(transitive)
+ Addedunderscore@1.7.0(transitive)
+ Addedunderscore.string@2.2.12.3.32.4.0(transitive)
+ Addedwhich@1.0.9(transitive)