|
35 | 35 |
|
36 | 36 | function _request(method, path, data, cb, raw, sync) { |
37 | 37 | function getURL() { |
38 | | - var url = API_URL + path; |
| 38 | + var url = path.indexOf('//') >= 0 ? path : API_URL + path; |
39 | 39 | return url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime(); |
40 | 40 | } |
41 | 41 |
|
|
47 | 47 | xhr.onreadystatechange = function () { |
48 | 48 | if (this.readyState == 4) { |
49 | 49 | if (this.status >= 200 && this.status < 300 || this.status === 304) { |
50 | | - cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true); |
| 50 | + cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true, this); |
51 | 51 | } else { |
52 | | - cb({request: this, error: this.status}); |
| 52 | + cb({path: path, request: this, error: this.status}); |
53 | 53 | } |
54 | 54 | } |
55 | 55 | } |
|
66 | 66 | if (sync) return xhr.response; |
67 | 67 | } |
68 | 68 |
|
| 69 | + function _requestAllPages(path, cb) { |
| 70 | + var results = []; |
| 71 | + (function iterate() { |
| 72 | + _request("GET", path, null, function(err, res, xhr) { |
| 73 | + if (err) { |
| 74 | + return cb(err); |
| 75 | + } |
| 76 | + |
| 77 | + results.push.apply(results, res); |
| 78 | + |
| 79 | + var links = (xhr.getResponseHeader('link') || '').split(/\s*,\s*/g), |
| 80 | + next = _.find(links, function(link) { return /rel="next"/.test(link); }); |
| 81 | + |
| 82 | + if (next) { |
| 83 | + next = (/<(.*)>/.exec(next) || [])[1]; |
| 84 | + } |
| 85 | + |
| 86 | + if (!next) { |
| 87 | + cb(err, results); |
| 88 | + } else { |
| 89 | + path = next; |
| 90 | + iterate(); |
| 91 | + } |
| 92 | + }); |
| 93 | + })(); |
| 94 | + } |
| 95 | + |
69 | 96 |
|
70 | 97 |
|
71 | 98 | // User API |
72 | 99 | // ======= |
73 | 100 |
|
74 | 101 | Github.User = function() { |
75 | 102 | this.repos = function(cb) { |
76 | | - _request("GET", "/user/repos?type=all&per_page=1000&sort=updated", null, function(err, res) { |
| 103 | + // Github does not always honor the 1000 limit so we want to iterate over the data set. |
| 104 | + _requestAllPages("/user/repos?type=all&per_page=1000&sort=updated", function(err, res) { |
77 | 105 | cb(err, res); |
78 | 106 | }); |
79 | 107 | }; |
|
120 | 148 | // ------- |
121 | 149 |
|
122 | 150 | this.userRepos = function(username, cb) { |
123 | | - _request("GET", "/users/"+username+"/repos?type=all&per_page=1000&sort=updated", null, function(err, res) { |
| 151 | + // Github does not always honor the 1000 limit so we want to iterate over the data set. |
| 152 | + _requestAllPages("/users/"+username+"/repos?type=all&per_page=1000&sort=updated", function(err, res) { |
124 | 153 | cb(err, res); |
125 | 154 | }); |
126 | 155 | }; |
|
138 | 167 | // ------- |
139 | 168 |
|
140 | 169 | this.orgRepos = function(orgname, cb) { |
141 | | - _request("GET", "/orgs/"+orgname+"/repos?type=all&per_page=1000&sort=updated&direction=desc", null, function(err, res) { |
| 170 | + // Github does not always honor the 1000 limit so we want to iterate over the data set. |
| 171 | + _requestAllPages("/orgs/"+orgname+"/repos?type=all&&page_num=1000&sort=updated&direction=desc", function(err, res) { |
142 | 172 | cb(err, res); |
143 | 173 | }); |
144 | 174 | }; |
|
0 commit comments