@clickup/rest-client
Version:
A syntax sugar tool around Node fetch() API, tailored to work with TypeScript and response validators
38 lines (34 loc) • 1.17 kB
text/typescript
/**
* Keeps calling a function with an updating cursor, and depaginates all the
* results until the cursor returned is null or undefined.
*
* On each call, the inner function needs to return an array with two elements:
* 1. Array or results, which could be empty, but not null or undefined.
* 2. A new cursor.
*/
export default async function* depaginate<TItem, TCursor = string>(
readFunc: (
cursor: TCursor | undefined,
) => Promise<readonly [TItem[], TCursor | null | undefined]>,
): AsyncGenerator<TItem, void, undefined> {
let prevCursor: TCursor | null | undefined = undefined;
let cursor: TCursor | null | undefined = undefined;
for (;;) {
let items: TItem[];
[items, cursor] = await readFunc(cursor === null ? undefined : cursor);
yield* items;
if (cursor === null || cursor === undefined) {
break;
}
if (JSON.stringify(prevCursor) === JSON.stringify(cursor)) {
throw Error(
"Depagination got stuck: prevCursor=" +
JSON.stringify(prevCursor) +
", cursor=" +
JSON.stringify(cursor) +
" (they must differ)",
);
}
prevCursor = cursor;
}
}