1 | 'use strict';
|
2 |
|
3 | var request = require('request')
|
4 | , xtendUrl = require('extend-url')
|
5 | , Stream = require('stream')
|
6 | , parseLinkHeader = require('parse-link-header')
|
7 | , withPagingParams = require('./lib/with-paging-params')
|
8 | ;
|
9 |
|
10 | function writeStream() {
|
11 | var s = new Stream();
|
12 | s.readable = true;
|
13 | return s;
|
14 | }
|
15 |
|
16 | function nextPage(opts, cb) {
|
17 | request(opts, function (err, res, body) {
|
18 | if (err) return cb(err);
|
19 | if (/^[45]\d\d/.test(res.statusCode)) return cb(body);
|
20 | cb(null, { headers: res.headers, body: body });
|
21 | });
|
22 | }
|
23 |
|
24 | function getPages (opts, current, acc, cb) {
|
25 | var stream;
|
26 |
|
27 | if (typeof cb !== 'function') {
|
28 |
|
29 | stream = cb instanceof Stream ? cb : writeStream();
|
30 | }
|
31 |
|
32 | nextPage(opts, function (err, res) {
|
33 | if (err) {
|
34 | return stream
|
35 | ? (stream.emit('error', err), stream.emit('end'))
|
36 | : cb(err);
|
37 | }
|
38 | if (stream) stream.emit('data', JSON.stringify(res));
|
39 | else acc.push(res);
|
40 |
|
41 | var links = parseLinkHeader(res.headers.link);
|
42 | if (!links || !links.next)
|
43 | return stream ? stream.emit('end') : cb(null, acc);
|
44 |
|
45 | opts.uri = xtendUrl(opts.uri, links.next.url);
|
46 |
|
47 | if (current >= links.last.page)
|
48 | return stream ? stream.emit('end') : cb(null, acc);
|
49 |
|
50 | process.nextTick(getPages.bind(null, opts, links.next.page, acc, stream || cb));
|
51 | });
|
52 |
|
53 | return stream;
|
54 | }
|
55 |
|
56 | module.exports = function (opts, startPage, perPage, cb) {
|
57 | opts.uri = withPagingParams(opts.uri, startPage, perPage);
|
58 | return getPages(opts, startPage, [], cb)
|
59 | };
|