2020-03-02 21:16:42 +08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
|
2020-07-05 03:43:39 +08:00
|
|
|
const VERSION = "2.2.3";
|
2020-03-02 21:16:42 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Some “list” response that can be paginated have a different response structure
|
|
|
|
*
|
|
|
|
* They have a `total_count` key in the response (search also has `incomplete_results`,
|
|
|
|
* /installation/repositories also has `repository_selection`), as well as a key with
|
2020-07-05 03:43:39 +08:00
|
|
|
* the list of the items which name varies from endpoint to endpoint.
|
2020-03-02 21:16:42 +08:00
|
|
|
*
|
|
|
|
* Octokit normalizes these responses so that paginated results are always returned following
|
|
|
|
* the same structure. One challenge is that if the list response has only one page, no Link
|
|
|
|
* header is provided, so this header alone is not sufficient to check wether a response is
|
2020-07-05 03:43:39 +08:00
|
|
|
* paginated or not.
|
|
|
|
*
|
|
|
|
* We check if a "total_count" key is present in the response data, but also make sure that
|
|
|
|
* a "url" property is not, as the "Get the combined status for a specific ref" endpoint would
|
|
|
|
* otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
|
2020-03-02 21:16:42 +08:00
|
|
|
*/
|
2020-07-05 03:43:39 +08:00
|
|
|
function normalizePaginatedListResponse(response) {
|
|
|
|
const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data);
|
|
|
|
if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way
|
2020-03-02 21:16:42 +08:00
|
|
|
// to retrieve the same information.
|
|
|
|
|
|
|
|
const incompleteResults = response.data.incomplete_results;
|
|
|
|
const repositorySelection = response.data.repository_selection;
|
|
|
|
const totalCount = response.data.total_count;
|
|
|
|
delete response.data.incomplete_results;
|
|
|
|
delete response.data.repository_selection;
|
|
|
|
delete response.data.total_count;
|
|
|
|
const namespaceKey = Object.keys(response.data)[0];
|
|
|
|
const data = response.data[namespaceKey];
|
|
|
|
response.data = data;
|
|
|
|
|
|
|
|
if (typeof incompleteResults !== "undefined") {
|
|
|
|
response.data.incomplete_results = incompleteResults;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof repositorySelection !== "undefined") {
|
|
|
|
response.data.repository_selection = repositorySelection;
|
|
|
|
}
|
|
|
|
|
|
|
|
response.data.total_count = totalCount;
|
2020-07-05 03:43:39 +08:00
|
|
|
return response;
|
2020-03-02 21:16:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function iterator(octokit, route, parameters) {
|
2020-07-05 03:43:39 +08:00
|
|
|
const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);
|
|
|
|
const requestMethod = typeof route === "function" ? route : octokit.request;
|
2020-03-02 21:16:42 +08:00
|
|
|
const method = options.method;
|
|
|
|
const headers = options.headers;
|
|
|
|
let url = options.url;
|
|
|
|
return {
|
|
|
|
[Symbol.asyncIterator]: () => ({
|
|
|
|
next() {
|
|
|
|
if (!url) {
|
|
|
|
return Promise.resolve({
|
|
|
|
done: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-07-05 03:43:39 +08:00
|
|
|
return requestMethod({
|
2020-03-02 21:16:42 +08:00
|
|
|
method,
|
|
|
|
url,
|
|
|
|
headers
|
2020-07-05 03:43:39 +08:00
|
|
|
}).then(normalizePaginatedListResponse).then(response => {
|
|
|
|
// `response.headers.link` format:
|
2020-03-02 21:16:42 +08:00
|
|
|
// '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
|
|
|
|
// sets `url` to undefined if "next" URL is not present or `link` header is not set
|
|
|
|
url = ((response.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
|
|
|
|
return {
|
|
|
|
value: response
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function paginate(octokit, route, parameters, mapFn) {
|
|
|
|
if (typeof parameters === "function") {
|
|
|
|
mapFn = parameters;
|
|
|
|
parameters = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);
|
|
|
|
}
|
|
|
|
|
|
|
|
function gather(octokit, results, iterator, mapFn) {
|
|
|
|
return iterator.next().then(result => {
|
|
|
|
if (result.done) {
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
let earlyExit = false;
|
|
|
|
|
|
|
|
function done() {
|
|
|
|
earlyExit = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);
|
|
|
|
|
|
|
|
if (earlyExit) {
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gather(octokit, results, iterator, mapFn);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param octokit Octokit instance
|
|
|
|
* @param options Options passed to Octokit constructor
|
|
|
|
*/
|
|
|
|
|
|
|
|
function paginateRest(octokit) {
|
|
|
|
return {
|
|
|
|
paginate: Object.assign(paginate.bind(null, octokit), {
|
|
|
|
iterator: iterator.bind(null, octokit)
|
|
|
|
})
|
|
|
|
};
|
|
|
|
}
|
|
|
|
paginateRest.VERSION = VERSION;
|
|
|
|
|
|
|
|
exports.paginateRest = paginateRest;
|
|
|
|
//# sourceMappingURL=index.js.map
|