From a7d489648472b8a2298ba435c08491b0ce0d2087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samy=20Pess=C3=A9?= Date: Thu, 15 Feb 2024 17:32:20 +0100 Subject: [PATCH] Process all pages to fetch the list of spaces in a collection (#164) --- src/lib/api.ts | 51 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index ae8391af6..1e8fc4636 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -5,6 +5,8 @@ import { ContentVisibility, GitBookAPI, GitBookAPIError, + HttpResponse, + List, PublishedContentLookup, } from '@gitbook/api'; import assertNever from 'assert-never'; @@ -438,13 +440,12 @@ export const getCollection = cache('api.getCollection', async (collectionId: str export const getCollectionSpaces = cache( 'api.getCollectionSpaces', async (collectionId: string) => { - const response = await api().collections.listSpacesInCollectionById( - collectionId, - {}, - { + const response = await getAll((params) => + api().collections.listSpacesInCollectionById(collectionId, params, { ...noCacheFetchOptions, - }, + }), ); + return cacheResponse(response, { data: response.data.items.filter( (space) => space.visibility === ContentVisibility.InCollection, @@ -596,3 +597,43 @@ export function userAgent(): string { return result; } + +/** + * Iterate over a paginated API endpoint and return all the items. + */ +async function getAll( + getPage: (params: { page?: string; limit?: number }) => Promise< + HttpResponse< + List & { + items: T[]; + }, + E + > + >, +): Promise< + HttpResponse< + List & { + items: T[]; + }, + E + > +> { + const limit = 100; + + let page: string | undefined = undefined; + const result: T[] = []; + + while (1) { + const response = await getPage({ page, limit }); + result.push(...response.data.items); + + if (response.data.next) { + page = response.data.next.page; + } else { + response.data.items = result; + return response; + } + } + + throw new Error('Unreachable'); +}