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 ` ,
* / i n s t a l l a t i o n / r e p o s i t o r i e s a l s o h a s ` r e p o s i t o r y _ s e l e c t i o n ` ) , a s w e l l a s a k e y w i t h
2020-06-07 00:27:02 +08:00
* 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`)
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-06-07 00:27:02 +08:00
* 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 .
2020-03-02 21:16:42 +08:00
* /
2020-06-07 00:27:02 +08:00
const REGEX = [
/^\/search\// ,
/^\/repos\/[^/]+\/[^/]+\/commits\/[^/]+\/(check-runs|check-suites)([^/]|$)/ ,
/^\/installation\/repositories([^/]|$)/ ,
/^\/user\/installations([^/]|$)/ ,
/^\/repos\/[^/]+\/[^/]+\/actions\/secrets([^/]|$)/ ,
/^\/repos\/[^/]+\/[^/]+\/actions\/workflows(\/[^/]+\/runs)?([^/]|$)/ ,
/^\/repos\/[^/]+\/[^/]+\/actions\/runs(\/[^/]+\/(artifacts|jobs))?([^/]|$)/
] ;
export function normalizePaginatedListResponse ( octokit , url , response ) {
const path = url . replace ( octokit . request . endpoint . DEFAULTS . baseUrl , "" ) ;
const responseNeedsNormalization = REGEX . find ( regex => regex . test ( path ) ) ;
2020-03-02 21:16:42 +08:00
if ( ! responseNeedsNormalization )
2020-06-07 00:27:02 +08:00
return ;
2020-03-02 21:16:42 +08:00
// keep the additional properties intact as there is currently no other way
// 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-06-07 00:27:02 +08:00
Object . defineProperty ( response . data , namespaceKey , {
get ( ) {
octokit . log . warn ( ` [@octokit/paginate-rest] "response.data. ${ namespaceKey } " is deprecated for "GET ${ path } ". Get the results directly from "response.data" ` ) ;
return Array . from ( data ) ;
}
} ) ;
2020-03-02 21:16:42 +08:00
}