Skip to content

Commit 6e25735

Browse files
committed
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B8xeJm2Hd923k8uo6eoFd2
1 parent 4c71913 commit 6e25735

3 files changed

Lines changed: 16 additions & 9 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ const pages = seam.createPaginator(
350350
)
351351

352352
for await (const device of pages.flatten()) {
353-
console.log(devices.name)
353+
console.log(device.display_name)
354354
}
355355
```
356356

src/lib/seam-paginator.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,7 @@ export class SeamPaginator<
142142
/**
143143
* Yields each item across all pages, fetching the next page as needed.
144144
*/
145-
async *flatten(): AsyncGenerator<
146-
EnsureReadonlyArray<TResponse[TResponseKey]>
147-
> {
145+
async *flatten(): AsyncGenerator<ElementOfArray<TResponse[TResponseKey]>> {
148146
let [current, pagination] = await this.firstPage()
149147
for (const item of current) {
150148
yield item
@@ -174,6 +172,8 @@ export class SeamPaginator<
174172

175173
type EnsureReadonlyArray<T> = T extends readonly any[] ? T : never
176174
type EnsureMutableArray<T> = T extends any[] ? T : never
175+
type ElementOfArray<T> =
176+
T extends ReadonlyArray<infer TElement> ? TElement : never
177177

178178
interface PaginationData {
179179
has_next_page: boolean

test/seam/connect/seam-paginator.test.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import test from 'ava'
22
import { getTestServer } from 'fixtures/seam/connect/api.js'
33

4-
import { SeamHttp, SeamPaginator } from '@seamapi/http/connect'
4+
import { type Device, SeamHttp, SeamPaginator } from '@seamapi/http/connect'
55

66
test('SeamPaginator: creates a SeamPaginator', async (t) => {
77
const { seed, endpoint } = await getTestServer(t)
@@ -80,14 +80,21 @@ test('SeamPaginator: flatten allows iteration over all devices', async (t) => {
8080
const allDevices = await seam.devices.list()
8181
const pages = seam.createPaginator(seam.devices.list({ limit: 1 }))
8282

83-
const devices = []
83+
const deviceIds = []
8484
for await (const device of pages.flatten()) {
85-
devices.push(device)
85+
expectType<Device>(device)
86+
87+
// @ts-expect-error Verify flatten yields single items, not pages.
88+
expectType<Device[]>(device)
89+
90+
deviceIds.push(device.device_id)
8691
}
87-
t.true(devices.length > 1)
88-
t.is(devices.length, allDevices.length)
92+
t.true(deviceIds.length > 1)
93+
t.is(deviceIds.length, allDevices.length)
8994
})
9095

96+
const expectType = <Expected>(_value: Expected): void => {}
97+
9198
test('SeamPaginator: instance allows iteration over all pages', async (t) => {
9299
const { seed, endpoint } = await getTestServer(t)
93100
const seam = SeamHttp.fromApiKey(seed.seam_apikey1_token, { endpoint })

0 commit comments

Comments
 (0)