|
35 | 35 |
|
36 | 36 | function _request(method, path, data, cb, raw) { |
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 |
|
|
46 | 46 | xhr.onreadystatechange = function () { |
47 | 47 | if (this.readyState == 4) { |
48 | 48 | if (this.status >= 200 && this.status < 300 || this.status === 304) { |
49 | | - cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true); |
| 49 | + cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true, this); |
50 | 50 | } else { |
51 | | - cb({request: this, error: this.status}); |
| 51 | + cb({path: path, request: this, error: this.status}); |
52 | 52 | } |
53 | 53 | } |
54 | 54 | }; |
|
66 | 66 | data ? xhr.send(JSON.stringify(data)) : xhr.send(); |
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 | }; |
|
111 | 139 | // ------- |
112 | 140 |
|
113 | 141 | this.userRepos = function(username, cb) { |
114 | | - _request("GET", "/users/"+username+"/repos?type=all&per_page=1000&sort=updated", null, function(err, res) { |
| 142 | + // Github does not always honor the 1000 limit so we want to iterate over the data set. |
| 143 | + _requestAllPages("/users/"+username+"/repos?type=all&per_page=1000&sort=updated", function(err, res) { |
115 | 144 | cb(err, res); |
116 | 145 | }); |
117 | 146 | }; |
|
129 | 158 | // ------- |
130 | 159 |
|
131 | 160 | this.orgRepos = function(orgname, cb) { |
132 | | - _request("GET", "/orgs/"+orgname+"/repos?type=all&per_page=1000&sort=updated&direction=desc", null, function(err, res) { |
| 161 | + // Github does not always honor the 1000 limit so we want to iterate over the data set. |
| 162 | + _requestAllPages("/orgs/"+orgname+"/repos?type=all&&page_num=1000&sort=updated&direction=desc", function(err, res) { |
133 | 163 | cb(err, res); |
134 | 164 | }); |
135 | 165 | }; |
|
0 commit comments