MCPcopy
hub / github.com/slackapi/node-slack-sdk / paginate

Method paginate

packages/web-api/src/WebClient.ts:197–271  ·  view source on GitHub ↗
(
    method: string,
    options?: WebAPICallOptions,
    shouldStop?: PaginatePredicate,
    reduce?: PageReducer<A>,
  )

Source from the content-addressed store, hash-verified

195 reduce?: PageReducer<A>,
196 ): Promise<A>;
197 public paginate<R extends PageReducer, A extends PageAccumulator<R>>(
198 method: string,
199 options?: WebAPICallOptions,
200 shouldStop?: PaginatePredicate,
201 reduce?: PageReducer<A>,
202 ): (Promise<A> | AsyncIterator<WebAPICallResult>) {
203
204 if (!methods.cursorPaginationEnabledMethods.has(method)) {
205 this.logger.warn(`paginate() called with method ${method}, which is not known to be cursor pagination enabled.`);
206 }
207
208 const pageSize = (() => {
209 if (options !== undefined && typeof options.limit === 'number') {
210 const limit = options.limit;
211 delete options.limit;
212 return limit;
213 }
214 return defaultPageSize;
215 })();
216
217 async function* generatePages(this: WebClient): AsyncIterableIterator<WebAPICallResult> {
218 // when result is undefined, that signals that the first of potentially many calls has not yet been made
219 let result: WebAPICallResult | undefined = undefined;
220 // paginationOptions stores pagination options not already stored in the options argument
221 let paginationOptions: methods.CursorPaginationEnabled | undefined = {
222 limit: pageSize,
223 };
224 if (options !== undefined && options.cursor !== undefined) {
225 paginationOptions.cursor = options.cursor as string;
226 }
227
228 // NOTE: test for the situation where you're resuming a pagination using and existing cursor
229
230 while (result === undefined || paginationOptions !== undefined) {
231 result = await this.apiCall(method, Object.assign(options !== undefined ? options : {}, paginationOptions));
232 yield result;
233 paginationOptions = paginationOptionsForNextPage(result, pageSize);
234 }
235 }
236
237 if (shouldStop === undefined) {
238 return generatePages.call(this);
239 }
240
241 const pageReducer: PageReducer<A> = (reduce !== undefined) ? reduce : noopPageReducer;
242 let index = 0;
243
244 return (async () => {
245 // Unroll the first iteration of the iterator
246 // This is done primarily because in order to satisfy the type system, we need a variable that is typed as A
247 // (shown as accumulator before), but before the first iteration all we have is a variable typed A | undefined.
248 // Unrolling the first iteration allows us to deal with undefined as a special case.
249
250 const pageIterator: AsyncIterableIterator<WebAPICallResult> = generatePages.call(this);
251 const firstIteratorResult = await pageIterator.next(undefined);
252 // Assumption: there will always be at least one result in a paginated API request
253 // if (firstIteratorResult.done) { return; }
254 const firstPage = firstIteratorResult.value;

Callers 2

WebClient.spec.jsFile · 0.80

Calls 1

warnMethod · 0.65

Tested by

no test coverage detected