File tree Expand file tree Collapse file tree 6 files changed +82
-1
lines changed
Expand file tree Collapse file tree 6 files changed +82
-1
lines changed Original file line number Diff line number Diff line change @@ -157,9 +157,35 @@ await octokit.graphql.paginate(
157157);
158158```
159159
160+ ### Options
161+
162+ You can provide a third argument to ` paginate ` or ` iterator ` to modify the behavior of the pagination.
163+
164+ ` maxPages ` will stop the iteration at the specified number of pages, useful when you don't need all the items in the response but still want to take advantage of the automatic merging.
165+
166+ ```
167+ const { repository } = await octokit.graphql.paginate(
168+ `query paginate($cursor: String) {
169+ repository(owner: "octokit", name: "rest.js") {
170+ issues(first: 10, after: $cursor) {
171+ nodes {
172+ title
173+ }
174+ pageInfo {
175+ hasNextPage
176+ endCursor
177+ }
178+ }
179+ }
180+ }`,
181+ { },
182+ { maxPages: 10 },
183+ );
184+ ```
185+
160186### Pagination Direction
161187
162- You can control the pagination direction by the properties deinfed in the ` pageInfo ` resource.
188+ You can control the pagination direction by the properties defined in the ` pageInfo ` resource.
163189
164190For a forward pagination, use:
165191
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ import { Octokit } from "@octokit/core";
22import { createIterator } from "./iterator" ;
33import { createPaginate } from "./paginate" ;
44export type { PageInfoForward , PageInfoBackward } from "./page-info" ;
5+ export type { Options } from "./options" ;
56
67export function paginateGraphql ( octokit : Octokit ) {
78 octokit . graphql ;
Original file line number Diff line number Diff line change @@ -2,19 +2,28 @@ import { extractPageInfos } from "./extract-page-info";
22import { Octokit } from "@octokit/core" ;
33import { getCursorFrom , hasAnotherPage } from "./page-info" ;
44import { MissingCursorChange } from "./errors" ;
5+ import type { Options } from "./options" ;
56
67const createIterator = ( octokit : Octokit ) => {
78 return < ResponseType = any > (
89 query : string ,
910 initialParameters : Record < string , any > = { } ,
11+ options : Options = { } ,
1012 ) => {
1113 let nextPageExists = true ;
1214 let parameters = { ...initialParameters } ;
15+ const { maxPages } = options ;
16+ let page = 0 ;
1317
1418 return {
1519 [ Symbol . asyncIterator ] : ( ) => ( {
1620 async next ( ) {
1721 if ( ! nextPageExists ) return { done : true , value : { } as ResponseType } ;
22+ if ( maxPages && page >= maxPages ) {
23+ return { done : true , value : { } as ResponseType } ;
24+ }
25+
26+ page += 1 ;
1827
1928 const response = await octokit . graphql < ResponseType > (
2029 query ,
Original file line number Diff line number Diff line change 1+ export type Options = {
2+ maxPages ?: number ;
3+ } ;
Original file line number Diff line number Diff line change 11import { Octokit } from "@octokit/core" ;
22import { mergeResponses } from "./merge-responses" ;
33import { createIterator } from "./iterator" ;
4+ import type { Options } from "./options" ;
45
56const createPaginate = ( octokit : Octokit ) => {
67 const iterator = createIterator ( octokit ) ;
78 return async < ResponseType extends object = any > (
89 query : string ,
910 initialParameters : Record < string , any > = { } ,
11+ options : Options = { } ,
1012 ) : Promise < ResponseType > => {
1113 let mergedResponse : ResponseType = { } as ResponseType ;
1214 for await ( const response of iterator < ResponseType > (
1315 query ,
1416 initialParameters ,
17+ options ,
1518 ) ) {
1619 mergedResponse = mergeResponses < ResponseType > ( mergedResponse , response ) ;
1720 }
Original file line number Diff line number Diff line change @@ -282,6 +282,45 @@ describe("pagination", () => {
282282 ] ) ;
283283 } ) ;
284284
285+ it ( ".paginate.iterator() allows users to pass `maxPages` parameter and stops at the right place." , async ( ) : Promise < void > => {
286+ const responses = createResponsePages ( { amount : 3 } ) ;
287+
288+ const { octokit, getCallCount, getPassedVariablesForCall } = MockOctokit ( {
289+ responses,
290+ } ) ;
291+
292+ const actualResponse = await octokit . graphql . paginate < TestResponseType > (
293+ `
294+ query paginate ($cursor: String) {
295+ repository(owner: "octokit", name: "rest.js") {
296+ issues(first: 10, after: $cursor) {
297+ nodes {
298+ title
299+ }
300+ pageInfo {
301+ hasNextPage
302+ endCursor
303+ }
304+ }
305+ }
306+ }` ,
307+ { } ,
308+ { maxPages : 2 } ,
309+ ) ;
310+
311+ expect ( actualResponse ) . toEqual ( {
312+ repository : {
313+ issues : {
314+ nodes : [ { title : "Issue 1" } , { title : "Issue 2" } ] ,
315+ pageInfo : { hasNextPage : true , endCursor : "endCursor2" } ,
316+ } ,
317+ } ,
318+ } ) ;
319+ expect ( getCallCount ( ) ) . toBe ( 2 ) ;
320+ expect ( getPassedVariablesForCall ( 1 ) ) . toBeUndefined ( ) ;
321+ expect ( getPassedVariablesForCall ( 2 ) ) . toEqual ( { cursor : "endCursor1" } ) ;
322+ } ) ;
323+
285324 it ( "paginate() throws error with path and variable name if cursors do not change between calls." , async ( ) : Promise < void > => {
286325 const [ responsePage1 , responsePage2 ] = createResponsePages ( { amount : 2 } ) ;
287326 responsePage2 . repository . issues . pageInfo = {
You can’t perform that action at this time.
0 commit comments