From 6e257358c21ab5eb7db857a991a35de741661bed Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 19:47:08 +0000 Subject: [PATCH] fix: Type flatten as yielding items instead of pages The declared yield type of SeamPaginator.flatten was the page array while the generator yields single items, so iterating flatten typed each item as an array of the resource. The mistyping also hid a broken README example that read a property off the wrong variable. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01B8xeJm2Hd923k8uo6eoFd2 --- README.md | 2 +- src/lib/seam-paginator.ts | 6 +++--- test/seam/connect/seam-paginator.test.ts | 17 ++++++++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 59a9fd52..1d780697 100644 --- a/README.md +++ b/README.md @@ -350,7 +350,7 @@ const pages = seam.createPaginator( ) for await (const device of pages.flatten()) { - console.log(devices.name) + console.log(device.display_name) } ``` diff --git a/src/lib/seam-paginator.ts b/src/lib/seam-paginator.ts index 0741f46f..8a52e350 100644 --- a/src/lib/seam-paginator.ts +++ b/src/lib/seam-paginator.ts @@ -142,9 +142,7 @@ export class SeamPaginator< /** * Yields each item across all pages, fetching the next page as needed. */ - async *flatten(): AsyncGenerator< - EnsureReadonlyArray - > { + async *flatten(): AsyncGenerator> { let [current, pagination] = await this.firstPage() for (const item of current) { yield item @@ -174,6 +172,8 @@ export class SeamPaginator< type EnsureReadonlyArray = T extends readonly any[] ? T : never type EnsureMutableArray = T extends any[] ? T : never +type ElementOfArray = + T extends ReadonlyArray ? TElement : never interface PaginationData { has_next_page: boolean diff --git a/test/seam/connect/seam-paginator.test.ts b/test/seam/connect/seam-paginator.test.ts index 2fca098c..fb623a74 100644 --- a/test/seam/connect/seam-paginator.test.ts +++ b/test/seam/connect/seam-paginator.test.ts @@ -1,7 +1,7 @@ import test from 'ava' import { getTestServer } from 'fixtures/seam/connect/api.js' -import { SeamHttp, SeamPaginator } from '@seamapi/http/connect' +import { type Device, SeamHttp, SeamPaginator } from '@seamapi/http/connect' test('SeamPaginator: creates a SeamPaginator', async (t) => { const { seed, endpoint } = await getTestServer(t) @@ -80,14 +80,21 @@ test('SeamPaginator: flatten allows iteration over all devices', async (t) => { const allDevices = await seam.devices.list() const pages = seam.createPaginator(seam.devices.list({ limit: 1 })) - const devices = [] + const deviceIds = [] for await (const device of pages.flatten()) { - devices.push(device) + expectType(device) + + // @ts-expect-error Verify flatten yields single items, not pages. + expectType(device) + + deviceIds.push(device.device_id) } - t.true(devices.length > 1) - t.is(devices.length, allDevices.length) + t.true(deviceIds.length > 1) + t.is(deviceIds.length, allDevices.length) }) +const expectType = (_value: Expected): void => {} + test('SeamPaginator: instance allows iteration over all pages', async (t) => { const { seed, endpoint } = await getTestServer(t) const seam = SeamHttp.fromApiKey(seed.seam_apikey1_token, { endpoint })