diff --git a/lib/Requestable.js b/lib/Requestable.js index 4d6e8d9d..389947c2 100644 --- a/lib/Requestable.js +++ b/lib/Requestable.js @@ -255,7 +255,7 @@ class Requestable { } results.push(...thisGroup); - const nextUrl = getNextPage(response.headers.link); + let nextUrl = getNextPage(response.headers.link); if(nextUrl) { if (!options) { options = {}; @@ -266,6 +266,8 @@ class Requestable { .split('=') .pop() ); + // Strip out query string, as we'll use 'options'. + nextUrl = nextUrl.split('?', 1)[0]; if (!(options && typeof options.page !== 'number')) { log(`getting next page: ${nextUrl}`); return this._requestAllPages(nextUrl, options, cb, results); @@ -280,6 +282,44 @@ class Requestable { return response; }).catch(callbackErrorOrThrow(cb, path)); } + + /** + * Make a request and fetch a specific page. Use this to override the paging provided + * by {@link Requestable#requestAllPages}. + * @param {string} path - the path to request + * @param {string} perPage - the maximum number of results to return + * @param {string} page - the page number + * @param {Object} options - the query parameters to include. It doesn't matter if this includes 'per_page' or + * 'page'. + * @param {Requestable.callback} [cb] - the function to receive the data. The returned data will always be an array. + * @return {Promise} - a promise which will resolve the page has been fetched + */ + _requestPage(path, perPage, page, options, cb) { + options['page'] = page; + options['per_page'] = perPage; + + let results = []; + return this._request('GET', path, options) + .then((response) => { + let thisGroup; + if (response.data instanceof Array) { + thisGroup = response.data; + } else if (response.data.items instanceof Array) { + thisGroup = response.data.items; + } else { + let message = `cannot figure out how to append ${response.data} to the result set`; + throw new ResponseError(message, path, response); + } + results.push(...thisGroup); + + if (cb) { + cb(null, results, response); + } + + response.data = results; + return response; + }).catch(callbackErrorOrThrow(cb, path)); + } } module.exports = Requestable; @@ -306,7 +346,7 @@ function getNextPage(linksHeader = '') { function callbackErrorOrThrow(cb, path) { return function handler(object) { let error; - if (object.hasOwnProperty('config')) { + if (object.hasOwnProperty('config') && object.response) { const {response: {status, statusText}, config: {method, url}} = object; let message = (`${status} error making request ${method} ${url}: "${statusText}"`); error = new ResponseError(message, path, object); diff --git a/lib/Search.js b/lib/Search.js index e0bde4fb..2f9d69fd 100644 --- a/lib/Search.js +++ b/lib/Search.js @@ -51,7 +51,11 @@ class Search extends Requestable { }); log(`searching ${path} with options:`, requestOptions); - return this._requestAllPages(`/search/${path}`, requestOptions, cb); + if (requestOptions.page && requestOptions.per_page) { + return this._requestPage(`/search/${path}`, requestOptions.per_page, requestOptions.page, requestOptions, cb); + } else { + return this._requestAllPages(`/search/${path}`, requestOptions, cb); + } } /** diff --git a/test/fixtures/search.json b/test/fixtures/search.json index e87ad025..9a599a79 100644 --- a/test/fixtures/search.json +++ b/test/fixtures/search.json @@ -8911,7 +8911,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:11 GMT", "content-type": "application/json; charset=utf-8", @@ -8939,7 +8939,7 @@ { "scope": "https://api.github.com:443", "method": "GET", - "path": "/search/repositories?q=tetris+language%3Aassembly&sort=stars&order=desc&type=all&per_page=100&page=2&q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100", + "path": "/search/repositories?q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100&page=2", "body": "", "status": 200, "response": { @@ -17848,7 +17848,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:14 GMT", "content-type": "application/json; charset=utf-8", @@ -17876,7 +17876,7 @@ { "scope": "https://api.github.com:443", "method": "GET", - "path": "/search/repositories?q=tetris+language%3Aassembly&sort=stars&order=desc&type=all&per_page=100&page=3&q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100", + "path": "/search/repositories?q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100&page=3", "body": "", "status": 200, "response": { @@ -26785,7 +26785,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:17 GMT", "content-type": "application/json; charset=utf-8", @@ -26813,7 +26813,7 @@ { "scope": "https://api.github.com:443", "method": "GET", - "path": "/search/repositories?q=tetris+language%3Aassembly&sort=stars&order=desc&type=all&per_page=100&page=4&q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100", + "path": "/search/repositories?q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100&page=4", "body": "", "status": 200, "response": { @@ -35722,7 +35722,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:20 GMT", "content-type": "application/json; charset=utf-8", @@ -35750,7 +35750,7 @@ { "scope": "https://api.github.com:443", "method": "GET", - "path": "/search/repositories?q=tetris+language%3Aassembly&sort=stars&order=desc&type=all&per_page=100&page=5&q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100", + "path": "/search/repositories?q=tetris+language:assembly&sort=stars&order=desc&type=all&per_page=100&page=5", "body": "", "status": 200, "response": { @@ -42256,7 +42256,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:22 GMT", "content-type": "application/json; charset=utf-8", @@ -42885,7 +42885,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:23 GMT", "content-type": "application/json; charset=utf-8", @@ -48918,7 +48918,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:24 GMT", "content-type": "application/json; charset=utf-8", @@ -48946,7 +48946,7 @@ { "scope": "https://api.github.com:443", "method": "GET", - "path": "/search/issues?q=windows+pip+label%3Abug+language%3Apython+state%3Aopen+&sort=created&order=asc&type=all&per_page=100&page=2&q=windows+pip+label:bug+language:python+state:open+&sort=created&order=asc&type=all&per_page=100", + "path": "/search/issues?q=windows+pip+label:bug+language:python+state:open+&sort=created&order=asc&type=all&per_page=100&page=2", "body": "", "status": 200, "response": { @@ -53447,7 +53447,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:26 GMT", "content-type": "application/json; charset=utf-8", @@ -53564,7 +53564,7 @@ } ] }, - "headers": { + "rawHeaders": { "server": "GitHub.com", "date": "Wed, 22 Jun 2016 02:15:27 GMT", "content-type": "application/json; charset=utf-8", diff --git a/test/search.spec.js b/test/search.spec.js index 11614e4e..21a3ec1e 100644 --- a/test/search.spec.js +++ b/test/search.spec.js @@ -29,6 +29,27 @@ describe('Search', function() { .then(function({data}) { expect(data).to.be.an.array(); expect(data.length).to.be.above(0); + expect(data.length).to.be.equal(473); + }); + }); + + it('should search repositories for specific page', function() { + let options; + let search = github.search({ + q: 'tetris language:assembly', + sort: 'stars', + order: 'desc', + type: 'all', + per_page: '100', + page: '2', + }); + + return search.forRepositories(options) + .then(function({data}) { + expect(data).to.be.an.array(); + expect(data.length).to.be.above(0); + expect(data.length).to.be.equal(100); + expect(data[0].name).to.be.equal('nand2tetris'); }); }); @@ -42,6 +63,7 @@ describe('Search', function() { .then(function({data}) { expect(data).to.be.an.array(); expect(data.length).to.be.above(0); + expect(data.length).to.be.equal(8); }); }); @@ -57,6 +79,7 @@ describe('Search', function() { .then(function({data}) { expect(data).to.be.an.array(); expect(data.length).to.be.above(0); + expect(data.length).to.be.equal(161); }); }); @@ -70,6 +93,7 @@ describe('Search', function() { .then(function({data}) { expect(data).to.be.an.array(); expect(data.length).to.be.above(0); + expect(data.length).to.be.equal(4); }); }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy