/**
* Pagination utilities for cursor-based GitHub GraphQL pagination
*/
export interface PageInfo {
hasNextPage: boolean;
endCursor: string | null;
}
/**
* Extracts pagination info from GitHub GraphQL response
* @param pageInfo - GitHub pageInfo object
* @returns Normalized PageInfo
*/
export function extractPageInfo(pageInfo: any): PageInfo {
return {
hasNextPage: pageInfo?.hasNextPage ?? false,
endCursor: pageInfo?.endCursor ?? null,
};
}
/**
* Fetches all pages of a paginated GraphQL query
* @param fetchPage - Function that fetches a single page given a cursor
* @param extractItems - Function to extract items from response
* @param extractPageInfo - Function to extract pageInfo from response
* @returns All items across all pages
*/
export async function fetchAllPages<T, R>(
fetchPage: (cursor: string | null) => Promise<R>,
extractItems: (response: R) => T[],
extractPageInfo: (response: R) => PageInfo
): Promise<T[]> {
const allItems: T[] = [];
let cursor: string | null = null;
let hasNextPage = true;
while (hasNextPage) {
const response = await fetchPage(cursor);
const items = extractItems(response);
allItems.push(...items);
const pageInfo = extractPageInfo(response);
hasNextPage = pageInfo.hasNextPage;
cursor = pageInfo.endCursor;
}
return allItems;
}