import { PullRequestState , PullRequestSort , SortDirection } from "./../github/client/types" ; import url from "url" ; import transformPullRequest from "./transforms/pull-request" ; import statsd from "../config/statsd" ; import { GitHubAPI } from "probot" ; import { metricHttpRequest } from "../config/metric-names" ; import { Repository } from "../models/subscription" ; import GitHubClient from "../github/client/github-client" ; import { getGithubUser , getGithubUserNew } from "../services/github/user" ; import { booleanFlag , BooleanFlags } from "../config/feature-flags" ; import { LoggerWithTarget } from "probot/lib/wrap-logger" ; /**
 * Find the next page number from the response headers.
 */ export const getNextPage = ( logger , headers = { } ) : number | undefined => { const nextUrl = ( ( headers . link || "" ) . match ( /<([^>]+)>;\s*rel="next"/ ) || [ ] ) [ 1 ] ; if ( ! nextUrl ) { return undefined ; } logger . debug ( "Extracting next PRs page url" ) ; const parsed = url . parse ( nextUrl ) ?. query ?. split ( "&" ) ; let nextPage ; parsed ?. forEach ( ( query ) => { const [ key , value ] = query . split ( "=" ) ; if ( key === "page" ) { nextPage = Number ( value ) ; } } ) ; return nextPage ; } ; interface Headers { link ? : string ; } export default async function ( logger , github , newGithub , jiraHost , repository , cursor ? , perPage ? ) { logger . info ( "Syncing PRs: started" ) ; let status ; let headers = { } ; let edges ; const useNewGHClient = await booleanFlag ( BooleanFlags . USE_NEW_GITHUB_CLIENT__FOR_PR , false , jiraHost ) ; cursor = ! cursor ? cursor = 1 : Number ( cursor ) ; const vars = { owner : repository . owner . login , repo : repository . name , per_page : perPage , page : cursor } ; const asyncTags = [ ] ; await statsd . asyncTimer ( async ( ) => { ( { data : edges , status , headers } = useNewGHClient ? await newGithub . getPullRequests ( repository . owner . login , repository . name , { per_page : perPage , page : Number ( cursor ) , state : PullRequestState . ALL , sort : PullRequestSort . CREATED , direction : SortDirection . DES } ) : await github . pulls . list ( { ... vars , state : "all" , sort : "created" , direction : "desc" } ) ) ; asyncTags . push ( `status:${ status }` ) ; } , metricHttpRequest . syncPullRequest , 1 , asyncTags ) ( ) ; const nextPage = getNextPage ( logger , headers ) || cursor + 1 ; edges . forEach ( ( edge ) => ( edge . cursor = nextPage ) ) ; const pullRequests = ( await Promise . all ( edges . map ( async ( pull ) => { const prDetails = useNewGHClient ? ( await newGithub . getPullRequest ( repository . owner . login , repository . name , pull . number ) ) . data : ( await github ?. pulls ?. get ( { owner : repository . owner . login , repo : repository . name , pull_number : pull . number } ) ) . data ; const ghUser = useNewGHClient ? await getGithubUserNew ( newGithub , prDetails . user . login ) : await getGithubUser ( github , prDetails . user . login ) ; const data = await transformPullRequest ( { pullRequest : pull , repository } , prDetails , ghUser ) ; return data ?. pullRequests [ 0 ] ; } ) ) ) . filter ( ( value ) => ! ! value ) ; logger . info ( "Syncing PRs: finished" ) ; return { edges , jiraPayload : pullRequests ?. length ? { id : repository . id , name : repository . full_name , pullRequests , url : repository . html_url , updateSequenceId : Date . now ( ) } : undefined } ; }