( runtime: PRRuntime, ref: GhPRRef, )
| 518 | * re-review after new commits). |
| 519 | */ |
| 520 | export async function fetchGhPRViewedFiles( |
| 521 | runtime: PRRuntime, |
| 522 | ref: GhPRRef, |
| 523 | ): Promise<Record<string, boolean>> { |
| 524 | const query = ` |
| 525 | query($owner: String!, $repo: String!, $number: Int!, $cursor: String) { |
| 526 | repository(owner: $owner, name: $repo) { |
| 527 | pullRequest(number: $number) { |
| 528 | files(first: 100, after: $cursor) { |
| 529 | nodes { |
| 530 | path |
| 531 | viewerViewedState |
| 532 | } |
| 533 | pageInfo { |
| 534 | hasNextPage |
| 535 | endCursor |
| 536 | } |
| 537 | } |
| 538 | } |
| 539 | } |
| 540 | } |
| 541 | `; |
| 542 | |
| 543 | const result: Record<string, boolean> = {}; |
| 544 | let cursor: string | null = null; |
| 545 | |
| 546 | // Paginate through all files (GitHub returns max 100 per page) |
| 547 | do { |
| 548 | const args = hostnameArgs(ref.host, [ |
| 549 | "api", "graphql", |
| 550 | "-f", `query=${query}`, |
| 551 | "-F", `owner=${ref.owner}`, |
| 552 | "-F", `repo=${ref.repo}`, |
| 553 | "-F", `number=${ref.number}`, |
| 554 | ]); |
| 555 | if (cursor) { |
| 556 | args.push("-F", `cursor=${cursor}`); |
| 557 | } |
| 558 | |
| 559 | const res = await runtime.runCommand("gh", args); |
| 560 | if (res.exitCode !== 0) { |
| 561 | throw new Error( |
| 562 | `Failed to fetch PR viewed files: ${res.stderr.trim() || `exit code ${res.exitCode}`}`, |
| 563 | ); |
| 564 | } |
| 565 | |
| 566 | const data = JSON.parse(res.stdout) as { |
| 567 | data?: { |
| 568 | repository?: { |
| 569 | pullRequest?: { |
| 570 | files?: { |
| 571 | nodes: Array<{ path: string; viewerViewedState: string }>; |
| 572 | pageInfo: { hasNextPage: boolean; endCursor: string | null }; |
| 573 | }; |
| 574 | }; |
| 575 | }; |
| 576 | }; |
| 577 | errors?: Array<{ message: string }>; |
no test coverage detected