| 35 | } |
| 36 | |
| 37 | export class CursorPage<Item> implements CursorPageResponse<Item>, Page<Item>, AsyncIterable<Item> { |
| 38 | data: Array<Item>; |
| 39 | pagination: { next?: string; previous?: string }; |
| 40 | |
| 41 | constructor( |
| 42 | data: Array<Item>, |
| 43 | pagination: { next?: string; previous?: string }, |
| 44 | private pageFetcher: (params: Omit<CursorPageParams, "limit">) => Promise<CursorPage<Item>> |
| 45 | ) { |
| 46 | this.data = data; |
| 47 | this.pagination = pagination; |
| 48 | } |
| 49 | |
| 50 | getPaginatedItems(): Item[] { |
| 51 | return this.data ?? []; |
| 52 | } |
| 53 | |
| 54 | hasNextPage(): boolean { |
| 55 | return !!this.pagination.next; |
| 56 | } |
| 57 | |
| 58 | hasPreviousPage(): boolean { |
| 59 | return !!this.pagination.previous; |
| 60 | } |
| 61 | |
| 62 | getNextPage(): Promise<CursorPage<Item>> { |
| 63 | if (!this.pagination.next) { |
| 64 | throw new Error("No next page available"); |
| 65 | } |
| 66 | |
| 67 | return this.pageFetcher({ after: this.pagination.next }); |
| 68 | } |
| 69 | |
| 70 | getPreviousPage(): Promise<CursorPage<Item>> { |
| 71 | if (!this.pagination.previous) { |
| 72 | throw new Error("No previous page available"); |
| 73 | } |
| 74 | |
| 75 | return this.pageFetcher({ before: this.pagination.previous }); |
| 76 | } |
| 77 | |
| 78 | async *iterPages() { |
| 79 | // eslint-disable-next-line @typescript-eslint/no-this-alias |
| 80 | let page: CursorPage<Item> = this; |
| 81 | yield page; |
| 82 | while (page.hasNextPage()) { |
| 83 | page = await page.getNextPage(); |
| 84 | yield page; |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | async *[Symbol.asyncIterator]() { |
| 89 | for await (const page of this.iterPages()) { |
| 90 | for (const item of page.getPaginatedItems()) { |
| 91 | yield item; |
| 92 | } |
| 93 | } |
| 94 | } |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…