UNPKG

@bitrix24/b24jssdk

Version:

Bitrix24 REST API JavaScript SDK

133 lines (130 loc) 5.07 kB
/** * @package @bitrix24/b24jssdk * @version 1.0.5 * @copyright (c) 2026 Bitrix24 * @license MIT * @see https://github.com/bitrix24/b24jssdk * @see https://bitrix24.github.io/b24jssdk/ */ import { AbstractAction } from '../abstract-action.mjs'; import { SdkError } from '../../sdk-error.mjs'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); class FetchListV2 extends AbstractAction { static { __name(this, "FetchListV2"); } /** * Calls a REST API list method and returns an async generator for efficient large data retrieval. * Implements the fast algorithm for iterating over large datasets without loading all data into memory at once. * * @template T - The type of items in the returned arrays (default is `unknown`). * * @param {ActionFetchListV2} options - parameters for executing the request. * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`) * - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter, * since the method is designed to obtain all data in one call. * Note: Use `filter`, `order`, and `select` to control the selection. * - `idKey?: string` - The name of the field containing the unique identifier of the element. * Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase). * or another field, depending on the REST API data structure. * - `customKeyForResult?: string` - A custom key indicating that the response REST API will be * grouped by this field. * Example: `items` to group a list of CRM items. * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging. * * @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`. * Each iteration returns the next page/batch of results until all data is fetched. * * @example * import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk' * * interface CrmItem { id: number, title: string } * const sixMonthAgo = new Date() * sixMonthAgo.setMonth((new Date()).getMonth() - 6) * sixMonthAgo.setHours(0, 0, 0) * const generator = b24.actions.v2.fetchList.make<CrmItem>({ * method: 'crm.item.list', * params: { * entityTypeId: EnumCrmEntityTypeId.company, * filter: { * '=%title': 'A%', * '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago * }, * select: ['id', 'title'] * }, * idKey: 'id', * customKeyForResult: 'items', * requestId: 'list-123' * }) * * for await (const chunk of generator) { * // Process chunk (e.g., save to database, analyze, etc.) * console.log(`Processing ${chunk.length} items`) * } * * @see {@link https://apidocs.bitrix24.com/settings/performance/huge-data.html Bitrix24: Fast algorithm for large data} */ async *make(options) { const batchSize = 50; const idKey = options?.idKey ?? "ID"; const customKeyForResult = options?.customKeyForResult ?? null; const params = options?.params ?? {}; const moreIdKey = `>${idKey}`; const requestParams = { ...params, order: { ...params["order"] || {}, [idKey]: "ASC" }, filter: { ...params["filter"] || {}, [moreIdKey]: 0 }, start: -1 }; let isContinue = true; do { const response = await this._b24.actions.v2.call.make({ method: options.method, params: requestParams, requestId: options.requestId }); if (!response.isSuccess) { this._logger.error("fetchListMethod", { method: options.method, requestId: options.requestId, messages: response.getErrorMessages() }); throw new SdkError({ code: "JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V2", description: `API Error: ${response.getErrorMessages().join("; ")}`, status: 500 }); } const responseData = response.getData(); if (!responseData) { isContinue = false; break; } let resultData = []; if (null === customKeyForResult) { resultData = responseData.result; } else { resultData = responseData.result[customKeyForResult]; } if (resultData.length === 0) { isContinue = false; break; } yield resultData; if (resultData.length < batchSize) { isContinue = false; break; } const lastItem = resultData[resultData.length - 1]; if (lastItem && typeof lastItem[idKey] !== "undefined") { requestParams.filter[moreIdKey] = Number.parseInt(lastItem[idKey]); } else { isContinue = false; break; } } while (isContinue); } } export { FetchListV2 }; //# sourceMappingURL=fetch-list.mjs.map