| /** |
| * 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 |
| * the list of the items which name varies from endpoint to endpoint: |
| * |
| * - https://developer.github.com/v3/search/#example (key `items`) |
| * - https://developer.github.com/v3/checks/runs/#response-3 (key: `check_runs`) |
| * - https://developer.github.com/v3/checks/suites/#response-1 (key: `check_suites`) |
| * - https://developer.github.com/v3/apps/installations/#list-repositories (key: `repositories`) |
| * - https://developer.github.com/v3/apps/installations/#list-installations-for-a-user (key `installations`) |
| * - https://developer.github.com/v3/orgs/#list-installations-for-an-organization (key `installations`) |
| * |
| * 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 |
| * paginated or not. For the exceptions with the namespace, a fallback check for the route |
| * paths has to be added in order to normalize the response. We cannot check for the total_count |
| * property because it also exists in the response of Get the combined status for a specific ref. |
| */ |
| |
| module.exports = normalizePaginatedListResponse; |
| |
| const { Deprecation } = require("deprecation"); |
| const once = require("once"); |
| |
| const deprecateIncompleteResults = once((log, deprecation) => |
| log.warn(deprecation) |
| ); |
| const deprecateTotalCount = once((log, deprecation) => log.warn(deprecation)); |
| const deprecateNamespace = once((log, deprecation) => log.warn(deprecation)); |
| |
| const REGEX_IS_SEARCH_PATH = /^\/search\//; |
| const REGEX_IS_CHECKS_PATH = /^\/repos\/[^/]+\/[^/]+\/commits\/[^/]+\/(check-runs|check-suites)/; |
| const REGEX_IS_INSTALLATION_REPOSITORIES_PATH = /^\/installation\/repositories/; |
| const REGEX_IS_USER_INSTALLATIONS_PATH = /^\/user\/installations/; |
| const REGEX_IS_ORG_INSTALLATIONS_PATH = /^\/orgs\/[^/]+\/installations/; |
| |
| function normalizePaginatedListResponse(octokit, url, response) { |
| const path = url.replace(octokit.request.endpoint.DEFAULTS.baseUrl, ""); |
| if ( |
| !REGEX_IS_SEARCH_PATH.test(path) && |
| !REGEX_IS_CHECKS_PATH.test(path) && |
| !REGEX_IS_INSTALLATION_REPOSITORIES_PATH.test(path) && |
| !REGEX_IS_USER_INSTALLATIONS_PATH.test(path) && |
| !REGEX_IS_ORG_INSTALLATIONS_PATH.test(path) |
| ) { |
| return; |
| } |
| |
| // keep the additional properties intact to avoid a breaking change, |
| // but log a deprecation warning when accessed |
| 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]; |
| |
| response.data = response.data[namespaceKey]; |
| |
| Object.defineProperty(response.data, namespaceKey, { |
| get() { |
| deprecateNamespace( |
| octokit.log, |
| new Deprecation( |
| `[@octokit/rest] "result.data.${namespaceKey}" is deprecated. Use "result.data" instead` |
| ) |
| ); |
| return response.data; |
| } |
| }); |
| |
| if (typeof incompleteResults !== "undefined") { |
| Object.defineProperty(response.data, "incomplete_results", { |
| get() { |
| deprecateIncompleteResults( |
| octokit.log, |
| new Deprecation( |
| '[@octokit/rest] "result.data.incomplete_results" is deprecated.' |
| ) |
| ); |
| return incompleteResults; |
| } |
| }); |
| } |
| |
| if (typeof repositorySelection !== "undefined") { |
| Object.defineProperty(response.data, "repository_selection", { |
| get() { |
| deprecateTotalCount( |
| octokit.log, |
| new Deprecation( |
| '[@octokit/rest] "result.data.repository_selection" is deprecated.' |
| ) |
| ); |
| return repositorySelection; |
| } |
| }); |
| } |
| |
| Object.defineProperty(response.data, "total_count", { |
| get() { |
| deprecateTotalCount( |
| octokit.log, |
| new Deprecation( |
| '[@octokit/rest] "result.data.total_count" is deprecated.' |
| ) |
| ); |
| return totalCount; |
| } |
| }); |
| } |