@@ -17,6 +17,12 @@ export type APIToken = string
1717
1818const limit = pLimit ( 25 )
1919
20+ // Structure of files returned by the 'List pull request files' API
21+ export interface GitHubFile {
22+ filename : string
23+ patch : string
24+ }
25+
2026// Note that there are parts of this class which don't seem to be
2127// used by Danger, they are exposed for Peril support.
2228
@@ -329,13 +335,60 @@ export class GitHubAPI {
329335 } )
330336 }
331337
332- getPullRequestDiff = async ( ) => {
338+ getPullRequestFiles = async ( page : number = 1 ) : Promise < GitHubFile [ ] > => {
333339 const repo = this . repoMetadata . repoSlug
334340 const prID = this . repoMetadata . pullRequestID
335- const res = await this . get ( `repos/${ repo } /pulls/${ prID } ` , {
336- Accept : "application/vnd.github.v3.diff" ,
337- } )
338- return res . ok ? res . text ( ) : ""
341+ const perPage = 100
342+ const url = `repos/${ repo } /pulls/${ prID } /files?page=${ page } &per_page=${ perPage } `
343+
344+ try {
345+ const response = await this . get ( url , {
346+ Accept : "application/vnd.github.v3.diff" ,
347+ } )
348+ const data = await response . json ( )
349+
350+ if ( ! response . ok ) {
351+ throw new Error ( `GitHub 'List pull request files' API returned an error: ${ data . message } ` )
352+ }
353+
354+ // Check for pagination using the Link header
355+ const linkHeader = response . headers . get ( "Link" )
356+ const hasNextPage = linkHeader && linkHeader . includes ( 'rel="next"' )
357+
358+ // If there's a next page, recursively fetch it and concatenate the results
359+ if ( hasNextPage ) {
360+ const nextPageNumber = page + 1
361+ const nextPageFiles = await this . getPullRequestFiles ( nextPageNumber )
362+ return [ ...data , ...nextPageFiles ]
363+ }
364+
365+ return data as GitHubFile [ ]
366+ } catch ( error ) {
367+ console . error ( "Failed to fetch GitHub pull request files:" , error )
368+ throw error
369+ }
370+ }
371+
372+ getPullRequestDiff = async ( ) : Promise < string > => {
373+ // This is a hack to get the file patch into a format that parse-diff accepts
374+ // as the GitHub API for listing pull request files is missing file names in the patch.
375+ function prefixedPatch ( file : GitHubFile ) : string {
376+ return `
377+ diff --git a/${ file . filename } b/${ file . filename }
378+ --- a/${ file . filename }
379+ +++ b/${ file . filename }
380+ ${ file . patch }
381+ `
382+ }
383+
384+ try {
385+ const files = await this . getPullRequestFiles ( )
386+ const diff = files . map ( prefixedPatch ) . join ( "\n" )
387+ return diff
388+ } catch ( error ) {
389+ console . error ( "Failed to fetch pull request diff:" , error )
390+ return ""
391+ }
339392 }
340393
341394 getFileContents = async ( path : string , repoSlug : string , ref : string ) : Promise < any > => {
0 commit comments