index.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. const VERSION = "2.17.0";
  4. function ownKeys(object, enumerableOnly) {
  5. var keys = Object.keys(object);
  6. if (Object.getOwnPropertySymbols) {
  7. var symbols = Object.getOwnPropertySymbols(object);
  8. if (enumerableOnly) {
  9. symbols = symbols.filter(function (sym) {
  10. return Object.getOwnPropertyDescriptor(object, sym).enumerable;
  11. });
  12. }
  13. keys.push.apply(keys, symbols);
  14. }
  15. return keys;
  16. }
  17. function _objectSpread2(target) {
  18. for (var i = 1; i < arguments.length; i++) {
  19. var source = arguments[i] != null ? arguments[i] : {};
  20. if (i % 2) {
  21. ownKeys(Object(source), true).forEach(function (key) {
  22. _defineProperty(target, key, source[key]);
  23. });
  24. } else if (Object.getOwnPropertyDescriptors) {
  25. Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
  26. } else {
  27. ownKeys(Object(source)).forEach(function (key) {
  28. Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
  29. });
  30. }
  31. }
  32. return target;
  33. }
  34. function _defineProperty(obj, key, value) {
  35. if (key in obj) {
  36. Object.defineProperty(obj, key, {
  37. value: value,
  38. enumerable: true,
  39. configurable: true,
  40. writable: true
  41. });
  42. } else {
  43. obj[key] = value;
  44. }
  45. return obj;
  46. }
  47. /**
  48. * Some “list” response that can be paginated have a different response structure
  49. *
  50. * They have a `total_count` key in the response (search also has `incomplete_results`,
  51. * /installation/repositories also has `repository_selection`), as well as a key with
  52. * the list of the items which name varies from endpoint to endpoint.
  53. *
  54. * Octokit normalizes these responses so that paginated results are always returned following
  55. * the same structure. One challenge is that if the list response has only one page, no Link
  56. * header is provided, so this header alone is not sufficient to check wether a response is
  57. * paginated or not.
  58. *
  59. * We check if a "total_count" key is present in the response data, but also make sure that
  60. * a "url" property is not, as the "Get the combined status for a specific ref" endpoint would
  61. * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
  62. */
  63. function normalizePaginatedListResponse(response) {
  64. // endpoints can respond with 204 if repository is empty
  65. if (!response.data) {
  66. return _objectSpread2(_objectSpread2({}, response), {}, {
  67. data: []
  68. });
  69. }
  70. const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data);
  71. if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way
  72. // to retrieve the same information.
  73. const incompleteResults = response.data.incomplete_results;
  74. const repositorySelection = response.data.repository_selection;
  75. const totalCount = response.data.total_count;
  76. delete response.data.incomplete_results;
  77. delete response.data.repository_selection;
  78. delete response.data.total_count;
  79. const namespaceKey = Object.keys(response.data)[0];
  80. const data = response.data[namespaceKey];
  81. response.data = data;
  82. if (typeof incompleteResults !== "undefined") {
  83. response.data.incomplete_results = incompleteResults;
  84. }
  85. if (typeof repositorySelection !== "undefined") {
  86. response.data.repository_selection = repositorySelection;
  87. }
  88. response.data.total_count = totalCount;
  89. return response;
  90. }
  91. function iterator(octokit, route, parameters) {
  92. const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters);
  93. const requestMethod = typeof route === "function" ? route : octokit.request;
  94. const method = options.method;
  95. const headers = options.headers;
  96. let url = options.url;
  97. return {
  98. [Symbol.asyncIterator]: () => ({
  99. async next() {
  100. if (!url) return {
  101. done: true
  102. };
  103. try {
  104. const response = await requestMethod({
  105. method,
  106. url,
  107. headers
  108. });
  109. const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format:
  110. // '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"'
  111. // sets `url` to undefined if "next" URL is not present or `link` header is not set
  112. url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1];
  113. return {
  114. value: normalizedResponse
  115. };
  116. } catch (error) {
  117. if (error.status !== 409) throw error;
  118. url = "";
  119. return {
  120. value: {
  121. status: 200,
  122. headers: {},
  123. data: []
  124. }
  125. };
  126. }
  127. }
  128. })
  129. };
  130. }
  131. function paginate(octokit, route, parameters, mapFn) {
  132. if (typeof parameters === "function") {
  133. mapFn = parameters;
  134. parameters = undefined;
  135. }
  136. return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn);
  137. }
  138. function gather(octokit, results, iterator, mapFn) {
  139. return iterator.next().then(result => {
  140. if (result.done) {
  141. return results;
  142. }
  143. let earlyExit = false;
  144. function done() {
  145. earlyExit = true;
  146. }
  147. results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data);
  148. if (earlyExit) {
  149. return results;
  150. }
  151. return gather(octokit, results, iterator, mapFn);
  152. });
  153. }
  154. const composePaginateRest = Object.assign(paginate, {
  155. iterator
  156. });
  157. const paginatingEndpoints = ["GET /app/hook/deliveries", "GET /app/installations", "GET /applications/grants", "GET /authorizations", "GET /enterprises/{enterprise}/actions/permissions/organizations", "GET /enterprises/{enterprise}/actions/runner-groups", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners", "GET /enterprises/{enterprise}/actions/runners", "GET /enterprises/{enterprise}/actions/runners/downloads", "GET /events", "GET /gists", "GET /gists/public", "GET /gists/starred", "GET /gists/{gist_id}/comments", "GET /gists/{gist_id}/commits", "GET /gists/{gist_id}/forks", "GET /installation/repositories", "GET /issues", "GET /marketplace_listing/plans", "GET /marketplace_listing/plans/{plan_id}/accounts", "GET /marketplace_listing/stubbed/plans", "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts", "GET /networks/{owner}/{repo}/events", "GET /notifications", "GET /organizations", "GET /orgs/{org}/actions/permissions/repositories", "GET /orgs/{org}/actions/runner-groups", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners", "GET /orgs/{org}/actions/runners", "GET /orgs/{org}/actions/runners/downloads", "GET /orgs/{org}/actions/secrets", "GET /orgs/{org}/actions/secrets/{secret_name}/repositories", "GET /orgs/{org}/blocks", "GET /orgs/{org}/credential-authorizations", "GET /orgs/{org}/events", "GET /orgs/{org}/failed_invitations", "GET /orgs/{org}/hooks", "GET /orgs/{org}/hooks/{hook_id}/deliveries", "GET /orgs/{org}/installations", "GET /orgs/{org}/invitations", "GET /orgs/{org}/invitations/{invitation_id}/teams", "GET /orgs/{org}/issues", "GET /orgs/{org}/members", "GET /orgs/{org}/migrations", "GET /orgs/{org}/migrations/{migration_id}/repositories", "GET /orgs/{org}/outside_collaborators", "GET /orgs/{org}/packages", "GET /orgs/{org}/projects", "GET /orgs/{org}/public_members", "GET /orgs/{org}/repos", "GET /orgs/{org}/secret-scanning/alerts", "GET /orgs/{org}/team-sync/groups", "GET /orgs/{org}/teams", "GET /orgs/{org}/teams/{team_slug}/discussions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/invitations", "GET /orgs/{org}/teams/{team_slug}/members", "GET /orgs/{org}/teams/{team_slug}/projects", "GET /orgs/{org}/teams/{team_slug}/repos", "GET /orgs/{org}/teams/{team_slug}/team-sync/group-mappings", "GET /orgs/{org}/teams/{team_slug}/teams", "GET /projects/columns/{column_id}/cards", "GET /projects/{project_id}/collaborators", "GET /projects/{project_id}/columns", "GET /repos/{owner}/{repo}/actions/artifacts", "GET /repos/{owner}/{repo}/actions/runners", "GET /repos/{owner}/{repo}/actions/runners/downloads", "GET /repos/{owner}/{repo}/actions/runs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs", "GET /repos/{owner}/{repo}/actions/secrets", "GET /repos/{owner}/{repo}/actions/workflows", "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs", "GET /repos/{owner}/{repo}/assignees", "GET /repos/{owner}/{repo}/autolinks", "GET /repos/{owner}/{repo}/branches", "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations", "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs", "GET /repos/{owner}/{repo}/code-scanning/alerts", "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", "GET /repos/{owner}/{repo}/code-scanning/analyses", "GET /repos/{owner}/{repo}/collaborators", "GET /repos/{owner}/{repo}/comments", "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/commits", "GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head", "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments", "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls", "GET /repos/{owner}/{repo}/commits/{ref}/check-runs", "GET /repos/{owner}/{repo}/commits/{ref}/check-suites", "GET /repos/{owner}/{repo}/commits/{ref}/statuses", "GET /repos/{owner}/{repo}/contributors", "GET /repos/{owner}/{repo}/deployments", "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses", "GET /repos/{owner}/{repo}/events", "GET /repos/{owner}/{repo}/forks", "GET /repos/{owner}/{repo}/git/matching-refs/{ref}", "GET /repos/{owner}/{repo}/hooks", "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", "GET /repos/{owner}/{repo}/invitations", "GET /repos/{owner}/{repo}/issues", "GET /repos/{owner}/{repo}/issues/comments", "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/issues/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/comments", "GET /repos/{owner}/{repo}/issues/{issue_number}/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/labels", "GET /repos/{owner}/{repo}/issues/{issue_number}/reactions", "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline", "GET /repos/{owner}/{repo}/keys", "GET /repos/{owner}/{repo}/labels", "GET /repos/{owner}/{repo}/milestones", "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels", "GET /repos/{owner}/{repo}/notifications", "GET /repos/{owner}/{repo}/pages/builds", "GET /repos/{owner}/{repo}/projects", "GET /repos/{owner}/{repo}/pulls", "GET /repos/{owner}/{repo}/pulls/comments", "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments", "GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", "GET /repos/{owner}/{repo}/pulls/{pull_number}/files", "GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments", "GET /repos/{owner}/{repo}/releases", "GET /repos/{owner}/{repo}/releases/{release_id}/assets", "GET /repos/{owner}/{repo}/secret-scanning/alerts", "GET /repos/{owner}/{repo}/stargazers", "GET /repos/{owner}/{repo}/subscribers", "GET /repos/{owner}/{repo}/tags", "GET /repos/{owner}/{repo}/teams", "GET /repositories", "GET /repositories/{repository_id}/environments/{environment_name}/secrets", "GET /scim/v2/enterprises/{enterprise}/Groups", "GET /scim/v2/enterprises/{enterprise}/Users", "GET /scim/v2/organizations/{org}/Users", "GET /search/code", "GET /search/commits", "GET /search/issues", "GET /search/labels", "GET /search/repositories", "GET /search/topics", "GET /search/users", "GET /teams/{team_id}/discussions", "GET /teams/{team_id}/discussions/{discussion_number}/comments", "GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /teams/{team_id}/discussions/{discussion_number}/reactions", "GET /teams/{team_id}/invitations", "GET /teams/{team_id}/members", "GET /teams/{team_id}/projects", "GET /teams/{team_id}/repos", "GET /teams/{team_id}/team-sync/group-mappings", "GET /teams/{team_id}/teams", "GET /user/blocks", "GET /user/emails", "GET /user/followers", "GET /user/following", "GET /user/gpg_keys", "GET /user/installations", "GET /user/installations/{installation_id}/repositories", "GET /user/issues", "GET /user/keys", "GET /user/marketplace_purchases", "GET /user/marketplace_purchases/stubbed", "GET /user/memberships/orgs", "GET /user/migrations", "GET /user/migrations/{migration_id}/repositories", "GET /user/orgs", "GET /user/packages", "GET /user/public_emails", "GET /user/repos", "GET /user/repository_invitations", "GET /user/starred", "GET /user/subscriptions", "GET /user/teams", "GET /users", "GET /users/{username}/events", "GET /users/{username}/events/orgs/{org}", "GET /users/{username}/events/public", "GET /users/{username}/followers", "GET /users/{username}/following", "GET /users/{username}/gists", "GET /users/{username}/gpg_keys", "GET /users/{username}/keys", "GET /users/{username}/orgs", "GET /users/{username}/packages", "GET /users/{username}/projects", "GET /users/{username}/received_events", "GET /users/{username}/received_events/public", "GET /users/{username}/repos", "GET /users/{username}/starred", "GET /users/{username}/subscriptions"];
  158. function isPaginatingEndpoint(arg) {
  159. if (typeof arg === "string") {
  160. return paginatingEndpoints.includes(arg);
  161. } else {
  162. return false;
  163. }
  164. }
  165. /**
  166. * @param octokit Octokit instance
  167. * @param options Options passed to Octokit constructor
  168. */
  169. function paginateRest(octokit) {
  170. return {
  171. paginate: Object.assign(paginate.bind(null, octokit), {
  172. iterator: iterator.bind(null, octokit)
  173. })
  174. };
  175. }
  176. paginateRest.VERSION = VERSION;
  177. exports.composePaginateRest = composePaginateRest;
  178. exports.isPaginatingEndpoint = isPaginatingEndpoint;
  179. exports.paginateRest = paginateRest;
  180. exports.paginatingEndpoints = paginatingEndpoints;
  181. //# sourceMappingURL=index.js.map