|
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