diff --git a/src/lib/seam-paginator.ts b/src/lib/seam-paginator.ts index cf2526ce..79fd3617 100644 --- a/src/lib/seam-paginator.ts +++ b/src/lib/seam-paginator.ts @@ -82,18 +82,21 @@ export class SeamPaginator< throw new Error('Cannot paginate a response without a responseKey') } + const method = this.#request.method + + const requestData = { + ...(usesParams(method) + ? (this.#request.params ?? {}) + : ((this.#request.body as Record | null) ?? {})), + page_cursor: nextPageCursor, + } + const request = new SeamHttpRequest(this.#parent, { pathname: this.#request.pathname, - method: this.#request.method, + method, responseKey, - params: - this.#request.params != null - ? { ...this.#request.params, page_cursor: nextPageCursor } - : undefined, - body: - this.#request.body != null - ? { ...this.#request.body, page_cursor: nextPageCursor } - : undefined, + params: usesParams(method) ? requestData : undefined, + body: usesParams(method) ? undefined : requestData, }) const response = await request.fetchResponse() @@ -186,6 +189,9 @@ export class SeamPaginator< } } +const usesParams = (method: string): boolean => + ['GET', 'DELETE'].includes(method.toUpperCase()) + type EnsureReadonlyArray = T extends readonly any[] ? T : never type EnsureMutableArray = T extends any[] ? T : never type ElementOfArray = diff --git a/test/seam/connect/seam-paginator.test.ts b/test/seam/connect/seam-paginator.test.ts index 60ba69a6..09459307 100644 --- a/test/seam/connect/seam-paginator.test.ts +++ b/test/seam/connect/seam-paginator.test.ts @@ -96,6 +96,40 @@ test('SeamPaginator: flatten allows iteration over all devices', async (t) => { const expectType = (_value: Expected): void => {} +test('SeamPaginator: sends the page cursor when the request has no parameters', async (t) => { + const { seed, endpoint } = await getTestServer(t) + const seam = SeamHttp.fromApiKey(seed.seam_apikey1_token, { endpoint }) + + nock(endpoint) + .get('/devices/list') + .reply(200, { + devices: [{ device_id: 'device-1' }], + pagination: { + has_next_page: true, + next_page_cursor: 'page-cursor-1', + next_page_url: `${endpoint}/devices/list?page_cursor=page-cursor-1`, + }, + }) + .get('/devices/list') + .query({ page_cursor: 'page-cursor-1', _strict: 'true' }) + .reply(200, { + devices: [{ device_id: 'device-2' }], + pagination: { + has_next_page: false, + next_page_cursor: null, + next_page_url: null, + }, + }) + + const pages = seam.createPaginator(seam.devices.list()) + const devices = await pages.flattenToArray() + + t.deepEqual( + devices.map(({ device_id: deviceId }) => deviceId), + ['device-1', 'device-2'], + ) +}) + test('SeamPaginator: stops iterating when the page cursor repeats', async (t) => { const { seed, endpoint } = await getTestServer(t) const seam = SeamHttp.fromApiKey(seed.seam_apikey1_token, { endpoint })