@bitrix24/b24jssdk 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README-AI.md +26 -3
  2. package/dist/esm/_virtual/_commonjsHelpers.mjs +1 -1
  3. package/dist/esm/_virtual/protobuf.mjs +1 -1
  4. package/dist/esm/_virtual/protobuf2.mjs +1 -1
  5. package/dist/esm/core/abstract-b24.mjs +1 -1
  6. package/dist/esm/core/actions/abstract-action.mjs +1 -1
  7. package/dist/esm/core/actions/abstract-batch.mjs +1 -1
  8. package/dist/esm/core/actions/manager.mjs +1 -1
  9. package/dist/esm/core/actions/v2/batch-by-chunk.mjs +1 -1
  10. package/dist/esm/core/actions/v2/batch.mjs +1 -1
  11. package/dist/esm/core/actions/v2/call-list.mjs +7 -3
  12. package/dist/esm/core/actions/v2/call-list.mjs.map +1 -1
  13. package/dist/esm/core/actions/v2/call.mjs +1 -1
  14. package/dist/esm/core/actions/v2/fetch-list.mjs +7 -3
  15. package/dist/esm/core/actions/v2/fetch-list.mjs.map +1 -1
  16. package/dist/esm/core/actions/v2/manager-v2.mjs +1 -1
  17. package/dist/esm/core/actions/v3/batch-by-chunk.mjs +1 -1
  18. package/dist/esm/core/actions/v3/batch.mjs +1 -1
  19. package/dist/esm/core/actions/v3/call-list.mjs +9 -5
  20. package/dist/esm/core/actions/v3/call-list.mjs.map +1 -1
  21. package/dist/esm/core/actions/v3/call.mjs +1 -1
  22. package/dist/esm/core/actions/v3/fetch-list.mjs +9 -5
  23. package/dist/esm/core/actions/v3/fetch-list.mjs.map +1 -1
  24. package/dist/esm/core/actions/v3/manager-v3.mjs +1 -1
  25. package/dist/esm/core/http/abstract-http.mjs +2 -2
  26. package/dist/esm/core/http/ajax-error.mjs +1 -1
  27. package/dist/esm/core/http/ajax-result.mjs +44 -4
  28. package/dist/esm/core/http/ajax-result.mjs.map +1 -1
  29. package/dist/esm/core/http/limiters/adaptive-delayer.mjs +1 -1
  30. package/dist/esm/core/http/limiters/manager.mjs +1 -1
  31. package/dist/esm/core/http/limiters/operating-limiter.mjs +1 -1
  32. package/dist/esm/core/http/limiters/params-factory.mjs +1 -1
  33. package/dist/esm/core/http/limiters/rate-limiter.mjs +1 -1
  34. package/dist/esm/core/http/v2.mjs +2 -2
  35. package/dist/esm/core/http/v3.mjs +2 -2
  36. package/dist/esm/core/interaction/batch/abstract-interaction-batch.mjs +1 -1
  37. package/dist/esm/core/interaction/batch/parse-row.mjs +1 -1
  38. package/dist/esm/core/interaction/batch/processing/interface-strategy.mjs +1 -1
  39. package/dist/esm/core/interaction/batch/processing/v2/abstract-processing.mjs +1 -1
  40. package/dist/esm/core/interaction/batch/processing/v2/abstract-processing.mjs.map +1 -1
  41. package/dist/esm/core/interaction/batch/processing/v2/as-array.mjs +1 -1
  42. package/dist/esm/core/interaction/batch/processing/v2/as-object.mjs +1 -1
  43. package/dist/esm/core/interaction/batch/processing/v3/abstract-processing.mjs +1 -1
  44. package/dist/esm/core/interaction/batch/processing/v3/abstract-processing.mjs.map +1 -1
  45. package/dist/esm/core/interaction/batch/processing/v3/as-array.mjs +1 -1
  46. package/dist/esm/core/interaction/batch/processing/v3/as-object.mjs +1 -1
  47. package/dist/esm/core/interaction/batch/v2.mjs +1 -1
  48. package/dist/esm/core/interaction/batch/v3.mjs +1 -1
  49. package/dist/esm/core/language/list.mjs +1 -1
  50. package/dist/esm/core/request-id-generator.mjs +1 -1
  51. package/dist/esm/core/result.mjs +1 -1
  52. package/dist/esm/core/sdk-error.mjs +1 -1
  53. package/dist/esm/core/tools/abstract-tool.mjs +1 -1
  54. package/dist/esm/core/tools/healthcheck.mjs +1 -1
  55. package/dist/esm/core/tools/manager.mjs +1 -1
  56. package/dist/esm/core/tools/ping.mjs +1 -1
  57. package/dist/esm/core/version-manager.mjs +1 -1
  58. package/dist/esm/frame/auth.mjs +1 -1
  59. package/dist/esm/frame/b24.mjs +1 -1
  60. package/dist/esm/frame/dialog.mjs +45 -5
  61. package/dist/esm/frame/dialog.mjs.map +1 -1
  62. package/dist/esm/frame/frame.mjs +1 -1
  63. package/dist/esm/frame/message/commands.mjs +1 -1
  64. package/dist/esm/frame/message/controller.mjs +1 -1
  65. package/dist/esm/frame/options.mjs +1 -1
  66. package/dist/esm/frame/parent.mjs +1 -1
  67. package/dist/esm/frame/placement.mjs +32 -9
  68. package/dist/esm/frame/placement.mjs.map +1 -1
  69. package/dist/esm/frame/slider.mjs +1 -1
  70. package/dist/esm/helper/abstract-helper.mjs +1 -1
  71. package/dist/esm/helper/app-manager.mjs +1 -1
  72. package/dist/esm/helper/currency-manager.mjs +1 -1
  73. package/dist/esm/helper/helper-manager.mjs +2 -2
  74. package/dist/esm/helper/license-manager.mjs +1 -1
  75. package/dist/esm/helper/options-manager.mjs +1 -1
  76. package/dist/esm/helper/payment-manager.mjs +1 -1
  77. package/dist/esm/helper/profile-manager.mjs +1 -1
  78. package/dist/esm/helper/use-b24-helper.mjs +1 -1
  79. package/dist/esm/hook/auth.mjs +1 -1
  80. package/dist/esm/hook/b24.mjs +1 -1
  81. package/dist/esm/index.d.mts +109 -13
  82. package/dist/esm/index.d.ts +109 -13
  83. package/dist/esm/index.mjs +1 -1
  84. package/dist/esm/loader-b24frame.mjs +1 -1
  85. package/dist/esm/logger/abstract-logger.mjs +1 -1
  86. package/dist/esm/logger/browser.mjs +1 -1
  87. package/dist/esm/logger/formatter/abstract-formatter.mjs +1 -1
  88. package/dist/esm/logger/formatter/json-formatter.mjs +1 -1
  89. package/dist/esm/logger/formatter/line-formatter.mjs +1 -1
  90. package/dist/esm/logger/formatter/telegram-formatter.mjs +1 -1
  91. package/dist/esm/logger/handler/abstract-handler.mjs +1 -1
  92. package/dist/esm/logger/handler/consola-adapter.mjs +1 -1
  93. package/dist/esm/logger/handler/console-handler.mjs +1 -1
  94. package/dist/esm/logger/handler/console-v2-handler.mjs +1 -1
  95. package/dist/esm/logger/handler/memory-handler.mjs +1 -1
  96. package/dist/esm/logger/handler/stream-handler.mjs +1 -1
  97. package/dist/esm/logger/handler/telegram-handler.mjs +1 -1
  98. package/dist/esm/logger/handler/winston-adapter.mjs +1 -1
  99. package/dist/esm/logger/logger-factory.mjs +1 -1
  100. package/dist/esm/logger/logger.mjs +1 -1
  101. package/dist/esm/logger/null-logger.mjs +1 -1
  102. package/dist/esm/logger/processor/memory-usage-processor.mjs +1 -1
  103. package/dist/esm/logger/processor/pid-processor.mjs +1 -1
  104. package/dist/esm/oauth/auth.mjs +1 -1
  105. package/dist/esm/oauth/b24.mjs +1 -1
  106. package/dist/esm/oauth/refresh-token-error.mjs +1 -1
  107. package/dist/esm/pullClient/abstract-connector.mjs +1 -1
  108. package/dist/esm/pullClient/channel-manager.mjs +1 -1
  109. package/dist/esm/pullClient/channel-manager.mjs.map +1 -1
  110. package/dist/esm/pullClient/client.mjs +1 -1
  111. package/dist/esm/pullClient/errors.mjs +1 -1
  112. package/dist/esm/pullClient/json-rpc.mjs +1 -1
  113. package/dist/esm/pullClient/long-polling-connector.mjs +1 -1
  114. package/dist/esm/pullClient/protobuf/index.mjs +1 -1
  115. package/dist/esm/pullClient/protobuf/model.mjs +1 -1
  116. package/dist/esm/pullClient/protobuf/protobuf.mjs +1 -1
  117. package/dist/esm/pullClient/shared-config.mjs +1 -1
  118. package/dist/esm/pullClient/storage-manager.mjs +1 -1
  119. package/dist/esm/pullClient/web-socket-connector.mjs +1 -1
  120. package/dist/esm/tools/browser.mjs +1 -1
  121. package/dist/esm/tools/environment.mjs +1 -1
  122. package/dist/esm/tools/formatters/iban.mjs +1 -1
  123. package/dist/esm/tools/formatters/numbers.mjs +1 -1
  124. package/dist/esm/tools/index.mjs +1 -1
  125. package/dist/esm/tools/scroll-size.mjs +1 -1
  126. package/dist/esm/tools/text.mjs +1 -1
  127. package/dist/esm/tools/type.mjs +1 -1
  128. package/dist/esm/tools/use-formatters.mjs +1 -1
  129. package/dist/esm/tools/uuidv7.mjs +1 -1
  130. package/dist/esm/types/b24-helper.mjs +1 -1
  131. package/dist/esm/types/b24.mjs +1 -1
  132. package/dist/esm/types/bizproc/index.mjs +1 -1
  133. package/dist/esm/types/catalog/index.mjs +1 -1
  134. package/dist/esm/types/common.mjs +1 -1
  135. package/dist/esm/types/crm/entity-type.mjs +1 -1
  136. package/dist/esm/types/crm/productrow.mjs +1 -1
  137. package/dist/esm/types/logger.mjs +1 -1
  138. package/dist/esm/types/pull.mjs +1 -1
  139. package/dist/umd/index.js +1321 -846
  140. package/dist/umd/index.js.map +1 -1
  141. package/dist/umd/index.min.js +37 -34
  142. package/dist/umd/index.min.js.map +1 -1
  143. package/package.json +5 -5
package/README-AI.md CHANGED
@@ -17,6 +17,24 @@ Core building blocks:
17
17
 
18
18
  Note: since v0.4.0 the package ships ESM and UMD only (no CommonJS).
19
19
 
20
+ ## Deprecation notice — read before generating code
21
+
22
+ The following surface is `@deprecated` and **scheduled for removal in `2.0.0`**.
23
+ Many examples in this document still reference it because it remains the most
24
+ widely-used path today, but new code should target the `actions.v{2,3}.*` API.
25
+
26
+ | Deprecated | Replacement |
27
+ |---|---|
28
+ | `b24.callMethod(method, params, start?)` | `b24.actions.v2.call.make({ method, params })` / `b24.actions.v3.call.make({ method, params })` |
29
+ | `b24.callBatch(calls, isHaltOnError?, returnAjaxResult?)` | `b24.actions.v2.batch.make({ calls, options })` / `b24.actions.v3.batch.make(...)` |
30
+ | `b24.callBatchByChunk(calls, isHaltOnError)` | `b24.actions.v2.batchByChunk.make({ calls, options })` / `b24.actions.v3.batchByChunk.make(...)` |
31
+ | `b24.callListMethod(method, params, progress?, customKey?)` | `b24.actions.v2.callList.make({ method, params, customKeyForResult })` / `b24.actions.v3.callList.make(...)` |
32
+ | `b24.fetchListMethod(method, params, idKey?, customKey?)` | `b24.actions.v2.fetchList.make({ method, params, idKey, customKeyForResult })` / `b24.actions.v3.fetchList.make(...)` |
33
+ | `AjaxResult#isMore()`, `#hasMore()`, `#getNext()`, `#fetchNext()`, `#getTotal()` | The `next`/`total` envelope fields are `restApi:v2`-only (no `restApi:v3` counterpart). Do not iterate manually — let `actions.v{2,3}.{callList,fetchList}` handle pagination. For element counts in `restApi:v3` use the `aggregate` action with `count` / `countDistinct`. |
34
+
35
+ `AjaxResult.getData()` returns exactly `{ result: T, time: PayloadTime }` — the
36
+ v2-only `next` and `total` fields are no longer surfaced through the public type.
37
+
20
38
 
21
39
  ## Frontend in Bitrix24 (TypeScript, ESM)
22
40
 
@@ -405,6 +423,11 @@ async function loadAllDealsStreaming($b24: any) {
405
423
 
406
424
  #### C) Manual pagination: callMethod + next pages
407
425
 
426
+ > **`@deprecated` — slated for removal in `2.0.0`.** `callMethod`, `isMore()`,
427
+ > and `getNext()` rely on the `restApi:v2` envelope field `next`, which
428
+ > `restApi:v3` does not return. Prefer `b24.actions.v{2,3}.fetchList.make` for
429
+ > custom-throttled iteration; that helper hides pagination for both API versions.
430
+
408
431
  Use when you need to control page sizes, pauses, or add custom throttling. Iterate until `isMore()` returns false, using `getNext($b24.getHttpClient())`.
409
432
 
410
433
  ```ts
@@ -446,9 +469,9 @@ import { AjaxError } from '@bitrix24/b24jssdk'
446
469
 
447
470
  try {
448
471
  const res = await $b24.callMethod('crm.item.get', { entityTypeId: 1, id: 10 })
449
- const payload = res.getData() // raw REST payload
472
+ const payload = res.getData() // { result, time } — see Deprecation notice
450
473
  const ok = res.isSuccess // boolean
451
- const total = res.getTotal() // for list calls
474
+ // const total = res.getTotal() // @deprecated, removed in 2.0.0; v3 has no `total`
452
475
  } catch (e) {
453
476
  if (e instanceof AjaxError) {
454
477
  console.error(e.code, e.description, e.status, e.requestInfo)
@@ -557,7 +580,7 @@ This document is based on the SDK source in packages/jssdk/src and the docs unde
557
580
  ```
558
581
 
559
582
  - Unique ID Generator: request IDs are appended automatically via Http
560
- - Result / AjaxResult: uniform result objects, error aggregation, paging helpers (isMore, getNext, getTotal)
583
+ - Result / AjaxResult: uniform result objects, error aggregation. (Legacy paging helpers `isMore`/`getNext`/`getTotal` are `@deprecated` for `2.0.0` — see Deprecation notice.)
561
584
  - Language List and LoggerBrowser
562
585
 
563
586
  ### Tools
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -68,10 +68,14 @@ class CallListV2 extends AbstractAction {
68
68
  const idKey = options?.idKey ?? "ID";
69
69
  const customKeyForResult = options?.customKeyForResult ?? null;
70
70
  const params = options?.params ?? {};
71
+ if ("order" in params && params["order"]) {
72
+ this._logger.warning("callList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.");
73
+ }
71
74
  const moreIdKey = `>${idKey}`;
75
+ const { order: _ignoredOrder, ...restParams } = params;
72
76
  const requestParams = {
73
- ...params,
74
- order: { ...params["order"] || {}, [idKey]: "ASC" },
77
+ ...restParams,
78
+ order: { [idKey]: "ASC" },
75
79
  filter: { ...params["filter"] || {}, [moreIdKey]: 0 },
76
80
  start: -1
77
81
  };
@@ -1 +1 @@
1
- {"version":3,"file":"call-list.mjs","sources":["../../../../../src/core/actions/v2/call-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { Result } from '../../result'\n\nexport type ActionCallListV2 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'start'>\n idKey?: string\n customKeyForResult?: string\n requestId?: string\n}\n\n/**\n * Fast data retrieval without counting the total number of records. `restApi:v2`\n *\n * @todo add docs\n */\nexport class CallListV2 extends AbstractAction {\n /**\n * Fast data retrieval without counting the total number of records.\n *\n * @template T - The type of the elements of the returned array (default is `unknown`).\n *\n * @param {ActionCallListV2} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase).\n * or another field, depending on the REST API data structure.\n * - `customKeyForResult?: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n *\n * @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.\n *\n * @example\n * import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'\n *\n * interface CrmItem { id: number, title: string }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const response = await b24.actions.v2.callList.make<CrmItem>({\n * method: 'crm.item.list',\n * params: {\n * entityTypeId: EnumCrmEntityTypeId.company,\n * filter: {\n * '=%title': 'A%',\n * '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago\n * },\n * select: ['id', 'title']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'list-123'\n * })\n * if (!response.isSuccess) {\n * throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)\n * }\n * const list = response.getData()\n * console.log(`Result: ${list?.length}`) // Number of items received\n */\n public override async make<T = unknown>(options: ActionCallListV2): Promise<Result<T[]>> {\n const batchSize = 50\n const result: Result<T[]> = new Result()\n\n const idKey = options?.idKey ?? 'ID'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n const moreIdKey = `>${idKey}`\n const requestParams: TypeCallParams = {\n ...params,\n order: { ...(params['order'] || {}), [idKey]: 'ASC' },\n filter: { ...(params['filter'] || {}), [moreIdKey]: 0 },\n start: -1\n }\n\n let allItems: T[] = []\n let isContinue = true\n\n do {\n const response: AjaxResult<T> = await this._b24.actions.v2.call.make<T>({\n method: options.method,\n params: requestParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('callFastListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n for (const [index, error] of response.errors) {\n result.addError(error, index)\n }\n isContinue = false\n break\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n let resultData: T[] = []\n if (null === customKeyForResult) {\n resultData = responseData.result as T[]\n } else {\n resultData = (responseData.result as any)[customKeyForResult] as T[]\n }\n\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n allItems = [...allItems, ...resultData]\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (\n lastItem\n && typeof lastItem[idKey] !== 'undefined'\n ) {\n requestParams.filter[moreIdKey] = Number.parseInt(lastItem[idKey])\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n\n return result.setData(allItems)\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call-list.mjs","sources":["../../../../../src/core/actions/v2/call-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { Result } from '../../result'\n\nexport type ActionCallListV2 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'start' | 'order'>\n idKey?: string\n customKeyForResult?: string\n requestId?: string\n}\n\n/**\n * Fast data retrieval without counting the total number of records. `restApi:v2`\n *\n * @todo add docs\n */\nexport class CallListV2 extends AbstractAction {\n /**\n * Fast data retrieval without counting the total number of records.\n *\n * @template T - The type of the elements of the returned array (default is `unknown`).\n *\n * @param {ActionCallListV2} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase).\n * or another field, depending on the REST API data structure.\n * - `customKeyForResult?: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n *\n * @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.\n *\n * @example\n * import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'\n *\n * interface CrmItem { id: number, title: string }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const response = await b24.actions.v2.callList.make<CrmItem>({\n * method: 'crm.item.list',\n * params: {\n * entityTypeId: EnumCrmEntityTypeId.company,\n * filter: {\n * '=%title': 'A%',\n * '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago\n * },\n * select: ['id', 'title']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'list-123'\n * })\n * if (!response.isSuccess) {\n * throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)\n * }\n * const list = response.getData()\n * console.log(`Result: ${list?.length}`) // Number of items received\n */\n public override async make<T = unknown>(options: ActionCallListV2): Promise<Result<T[]>> {\n const batchSize = 50\n const result: Result<T[]> = new Result()\n\n const idKey = options?.idKey ?? 'ID'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n // Warn and strip user-provided `order` — cursor pagination requires ordering by idKey only\n if ('order' in params && params['order']) {\n this._logger.warning('callList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.')\n }\n\n const moreIdKey = `>${idKey}`\n const { order: _ignoredOrder, ...restParams } = params as TypeCallParams\n const requestParams: TypeCallParams = {\n ...restParams,\n order: { [idKey]: 'ASC' },\n filter: { ...(params['filter'] || {}), [moreIdKey]: 0 },\n start: -1\n }\n\n let allItems: T[] = []\n let isContinue = true\n\n do {\n const response: AjaxResult<T> = await this._b24.actions.v2.call.make<T>({\n method: options.method,\n params: requestParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('callFastListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n for (const [index, error] of response.errors) {\n result.addError(error, index)\n }\n isContinue = false\n break\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n let resultData: T[] = []\n if (null === customKeyForResult) {\n resultData = responseData.result as T[]\n } else {\n resultData = (responseData.result as any)[customKeyForResult] as T[]\n }\n\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n allItems = [...allItems, ...resultData]\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (\n lastItem\n && typeof lastItem[idKey] !== 'undefined'\n ) {\n requestParams.filter[moreIdKey] = Number.parseInt(lastItem[idKey])\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n\n return result.setData(allItems)\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAmBO,MAAM,mBAAmB,cAAA,CAAe;AAAA,EAnB/C;AAmB+C,IAAA,MAAA,CAAA,IAAA,EAAA,YAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgD7C,MAAsB,KAAkB,OAAA,EAAiD;AACvF,IAAA,MAAM,SAAA,GAAY,EAAA;AAClB,IAAA,MAAM,MAAA,GAAsB,IAAI,MAAA,EAAO;AAEvC,IAAA,MAAM,KAAA,GAAQ,SAAS,KAAA,IAAS,IAAA;AAChC,IAAA,MAAM,kBAAA,GAAqB,SAAS,kBAAA,IAAsB,IAAA;AAC1D,IAAA,MAAM,MAAA,GAAS,OAAA,EAAS,MAAA,IAAU,EAAC;AAGnC,IAAA,IAAI,OAAA,IAAW,MAAA,IAAU,MAAA,CAAO,OAAO,CAAA,EAAG;AACxC,MAAA,IAAA,CAAK,OAAA,CAAQ,QAAQ,+JAA+J,CAAA;AAAA,IACtL;AAEA,IAAA,MAAM,SAAA,GAAY,IAAI,KAAK,CAAA,CAAA;AAC3B,IAAA,MAAM,EAAE,KAAA,EAAO,aAAA,EAAe,GAAG,YAAW,GAAI,MAAA;AAChD,IAAA,MAAM,aAAA,GAAgC;AAAA,MACpC,GAAG,UAAA;AAAA,MACH,KAAA,EAAO,EAAE,CAAC,KAAK,GAAG,KAAA,EAAM;AAAA,MACxB,MAAA,EAAQ,EAAE,GAAI,MAAA,CAAO,QAAQ,CAAA,IAAK,EAAC,EAAI,CAAC,SAAS,GAAG,CAAA,EAAE;AAAA,MACtD,KAAA,EAAO;AAAA,KACT;AAEA,IAAA,IAAI,WAAgB,EAAC;AACrB,IAAA,IAAI,UAAA,GAAa,IAAA;AAEjB,IAAA,GAAG;AACD,MAAA,MAAM,WAA0B,MAAM,IAAA,CAAK,KAAK,OAAA,CAAQ,EAAA,CAAG,KAAK,IAAA,CAAQ;AAAA,QACtE,QAAQ,OAAA,CAAQ,MAAA;AAAA,QAChB,MAAA,EAAQ,aAAA;AAAA,QACR,WAAW,OAAA,CAAQ;AAAA,OACpB,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,SAAA,EAAW;AACvB,QAAA,IAAA,CAAK,OAAA,CAAQ,MAAM,oBAAA,EAAsB;AAAA,UACvC,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,WAAW,OAAA,CAAQ,SAAA;AAAA,UACnB,QAAA,EAAU,SAAS,gBAAA;AAAiB,SACrC,CAAA;AACD,QAAA,KAAA,MAAW,CAAC,KAAA,EAAO,KAAK,CAAA,IAAK,SAAS,MAAA,EAAQ;AAC5C,UAAA,MAAA,CAAO,QAAA,CAAS,OAAO,KAAK,CAAA;AAAA,QAC9B;AACA,QAAA,UAAA,GAAa,KAAA;AACb,QAAA;AAAA,MACF;AACA,MAAA,MAAM,YAAA,GAAe,SAAS,OAAA,EAAQ;AACtC,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA,UAAA,GAAa,KAAA;AACb,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,aAAkB,EAAC;AACvB,MAAA,IAAI,SAAS,kBAAA,EAAoB;AAC/B,QAAA,UAAA,GAAa,YAAA,CAAa,MAAA;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,UAAA,GAAc,YAAA,CAAa,OAAe,kBAAkB,CAAA;AAAA,MAC9D;AAEA,MAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,QAAA,UAAA,GAAa,KAAA;AACb,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,GAAW,CAAC,GAAG,QAAA,EAAU,GAAG,UAAU,CAAA;AAEtC,MAAA,IAAI,UAAA,CAAW,SAAS,SAAA,EAAW;AACjC,QAAA,UAAA,GAAa,KAAA;AACb,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,QAAA,GAAW,UAAA,CAAW,UAAA,CAAW,MAAA,GAAS,CAAC,CAAA;AACjD,MAAA,IACE,QAAA,IACG,OAAO,QAAA,CAAS,KAAK,MAAM,WAAA,EAC9B;AACA,QAAA,aAAA,CAAc,OAAO,SAAS,CAAA,GAAI,OAAO,QAAA,CAAS,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,MACnE,CAAA,MAAO;AACL,QAAA,UAAA,GAAa,KAAA;AACb,QAAA;AAAA,MACF;AAAA,IACF,CAAA,QAAS,UAAA;AAET,IAAA,OAAO,MAAA,CAAO,QAAQ,QAAQ,CAAA;AAAA,EAChC;AACF;;;;"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -71,10 +71,14 @@ class FetchListV2 extends AbstractAction {
71
71
  const idKey = options?.idKey ?? "ID";
72
72
  const customKeyForResult = options?.customKeyForResult ?? null;
73
73
  const params = options?.params ?? {};
74
+ if ("order" in params && params["order"]) {
75
+ this._logger.warning("fetchList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.");
76
+ }
74
77
  const moreIdKey = `>${idKey}`;
78
+ const { order: _ignoredOrder, ...restParams } = params;
75
79
  const requestParams = {
76
- ...params,
77
- order: { ...params["order"] || {}, [idKey]: "ASC" },
80
+ ...restParams,
81
+ order: { [idKey]: "ASC" },
78
82
  filter: { ...params["filter"] || {}, [moreIdKey]: 0 },
79
83
  start: -1
80
84
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-list.mjs","sources":["../../../../../src/core/actions/v2/fetch-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { SdkError } from '../../sdk-error'\n\nexport type ActionFetchListV2 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'start'>\n idKey?: string\n customKeyForResult?: string\n requestId?: string\n}\n\n/**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v2`\n *\n * @todo add docs\n */\nexport class FetchListV2 extends AbstractAction {\n /**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval.\n * Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.\n *\n * @template T - The type of items in the returned arrays (default is `unknown`).\n *\n * @param {ActionFetchListV2} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase).\n * or another field, depending on the REST API data structure.\n * - `customKeyForResult?: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n *\n * @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.\n * Each iteration returns the next page/batch of results until all data is fetched.\n *\n * @example\n * import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'\n *\n * interface CrmItem { id: number, title: string }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const generator = b24.actions.v2.fetchList.make<CrmItem>({\n * method: 'crm.item.list',\n * params: {\n * entityTypeId: EnumCrmEntityTypeId.company,\n * filter: {\n * '=%title': 'A%',\n * '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago\n * },\n * select: ['id', 'title']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'list-123'\n * })\n *\n * for await (const chunk of generator) {\n * // Process chunk (e.g., save to database, analyze, etc.)\n * console.log(`Processing ${chunk.length} items`)\n * }\n *\n * @see {@link https://apidocs.bitrix24.com/settings/performance/huge-data.html Bitrix24: Fast algorithm for large data}\n */\n public override async* make<T = unknown>(options: ActionFetchListV2): AsyncGenerator<T[]> {\n const batchSize = 50\n\n const idKey = options?.idKey ?? 'ID'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n const moreIdKey = `>${idKey}`\n const requestParams: TypeCallParams = {\n ...params,\n order: { ...(params['order'] || {}), [idKey]: 'ASC' },\n filter: { ...(params['filter'] || {}), [moreIdKey]: 0 },\n start: -1\n }\n\n let isContinue = true\n\n do {\n const response: AjaxResult<T> = await this._b24.actions.v2.call.make<T>({\n method: options.method,\n params: requestParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('fetchListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n throw new SdkError({\n code: 'JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V2',\n description: `API Error: ${response.getErrorMessages().join('; ')}`,\n status: 500\n })\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n let resultData: T[] = []\n if (null === customKeyForResult) {\n resultData = responseData.result as T[]\n } else {\n resultData = (responseData.result as any)[customKeyForResult] as T[]\n }\n\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n yield resultData\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (\n lastItem\n && typeof lastItem[idKey] !== 'undefined'\n ) {\n requestParams.filter[moreIdKey] = Number.parseInt(lastItem[idKey])\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-list.mjs","sources":["../../../../../src/core/actions/v2/fetch-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { SdkError } from '../../sdk-error'\n\nexport type ActionFetchListV2 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'start' | 'order'>\n idKey?: string\n customKeyForResult?: string\n requestId?: string\n}\n\n/**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v2`\n *\n * @todo add docs\n */\nexport class FetchListV2 extends AbstractAction {\n /**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval.\n * Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.\n *\n * @template T - The type of items in the returned arrays (default is `unknown`).\n *\n * @param {ActionFetchListV2} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'start'>` - Request parameters, excluding the `start` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'ID' (uppercase). Alternatively, it can be 'id' (lowercase).\n * or another field, depending on the REST API data structure.\n * - `customKeyForResult?: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n *\n * @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.\n * Each iteration returns the next page/batch of results until all data is fetched.\n *\n * @example\n * import { EnumCrmEntityTypeId, Text } from '@bitrix24/b24jssdk'\n *\n * interface CrmItem { id: number, title: string }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const generator = b24.actions.v2.fetchList.make<CrmItem>({\n * method: 'crm.item.list',\n * params: {\n * entityTypeId: EnumCrmEntityTypeId.company,\n * filter: {\n * '=%title': 'A%',\n * '>=createdTime': Text.toB24Format(sixMonthAgo) // created at least 6 months ago\n * },\n * select: ['id', 'title']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'list-123'\n * })\n *\n * for await (const chunk of generator) {\n * // Process chunk (e.g., save to database, analyze, etc.)\n * console.log(`Processing ${chunk.length} items`)\n * }\n *\n * @see {@link https://apidocs.bitrix24.com/settings/performance/huge-data.html Bitrix24: Fast algorithm for large data}\n */\n public override async* make<T = unknown>(options: ActionFetchListV2): AsyncGenerator<T[]> {\n const batchSize = 50\n\n const idKey = options?.idKey ?? 'ID'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n // Warn and strip user-provided `order` — cursor pagination requires ordering by idKey only\n if ('order' in params && params['order']) {\n this._logger.warning('fetchList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.')\n }\n\n const moreIdKey = `>${idKey}`\n const { order: _ignoredOrder, ...restParams } = params as TypeCallParams\n const requestParams: TypeCallParams = {\n ...restParams,\n order: { [idKey]: 'ASC' },\n filter: { ...(params['filter'] || {}), [moreIdKey]: 0 },\n start: -1\n }\n\n let isContinue = true\n\n do {\n const response: AjaxResult<T> = await this._b24.actions.v2.call.make<T>({\n method: options.method,\n params: requestParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('fetchListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n throw new SdkError({\n code: 'JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V2',\n description: `API Error: ${response.getErrorMessages().join('; ')}`,\n status: 500\n })\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n let resultData: T[] = []\n if (null === customKeyForResult) {\n resultData = responseData.result as T[]\n } else {\n resultData = (responseData.result as any)[customKeyForResult] as T[]\n }\n\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n yield resultData\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (\n lastItem\n && typeof lastItem[idKey] !== 'undefined'\n ) {\n requestParams.filter[moreIdKey] = Number.parseInt(lastItem[idKey])\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -67,9 +67,13 @@ class CallListV3 extends AbstractAction {
67
67
  const idKey = options?.idKey ?? "id";
68
68
  const customKeyForResult = options?.customKeyForResult ?? null;
69
69
  const params = options?.params ?? {};
70
+ if ("order" in params && params["order"]) {
71
+ this._logger.warning("callList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.");
72
+ }
73
+ const { order: _ignoredOrder, ...restParams } = params;
70
74
  const requestParams = {
71
- ...params,
72
- order: { ...params["order"] || {}, [idKey]: "ASC" },
75
+ ...restParams,
76
+ order: { [idKey]: "ASC" },
73
77
  filter: [...params["filter"] || []],
74
78
  pagination: { page: 0, limit: batchSize }
75
79
  };
@@ -77,11 +81,11 @@ class CallListV3 extends AbstractAction {
77
81
  let isContinue = true;
78
82
  let nextId = 0;
79
83
  do {
80
- const sendParams = { ...requestParams };
84
+ const sendParams = { ...requestParams, filter: [...requestParams.filter] };
81
85
  sendParams.filter.push([idKey, ">", nextId]);
82
86
  const response = await this._b24.actions.v3.call.make({
83
87
  method: options.method,
84
- params: requestParams,
88
+ params: sendParams,
85
89
  requestId: options.requestId
86
90
  });
87
91
  if (!response.isSuccess) {
@@ -1 +1 @@
1
- {"version":3,"file":"call-list.mjs","sources":["../../../../../src/core/actions/v3/call-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { Result } from '../../result'\n\nexport type ActionCallListV3 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'pagination'>\n idKey?: string\n customKeyForResult: string\n requestId?: string\n limit?: number\n}\n\n/**\n * Fast data retrieval without counting the total number of records. `restApi:v3`\n *\n * @todo add docs\n */\nexport class CallListV3 extends AbstractAction {\n /**\n * Fast data retrieval without counting the total number of records.\n *\n * @template T - The type of the elements of the returned array (default is `unknown`).\n *\n * @param {ActionCallListV3} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'pagination'>` - Request parameters, excluding the `pagination` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'id'. Alternatively, it can be another field, depending on the REST API data structure.\n * - `customKeyForResult: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n * - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.\n *\n * @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.\n *\n * @example\n * import { Text } from '@bitrix24/b24jssdk'\n *\n * interface MainEventLogItem { id: number, userId: number }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const response = await b24.actions.v3.callList.make<MainEventLogItem>({\n * method: 'main.eventlog.list',\n * params: {\n * filter: [\n * ['timestampX', '>=', Text.toB24Format(sixMonthAgo)] // created at least 6 months ago\n * ],\n * select: ['id', 'userId']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'eventlog-123',\n * limit: 60\n * })\n * if (!response.isSuccess) {\n * throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)\n * }\n * const list = response.getData()\n * console.log(`Result: ${list?.length}`) // Number of items received\n */\n public override async make<T = unknown>(options: ActionCallListV3): Promise<Result<T[]>> {\n const batchSize = options?.limit ?? 50\n const result: Result<T[]> = new Result()\n\n const idKey = options?.idKey ?? 'id'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n const requestParams: TypeCallParams = {\n ...params,\n order: { ...(params['order'] || {}), [idKey]: 'ASC' },\n filter: [...(params['filter'] || [])],\n pagination: { page: 0, limit: batchSize }\n }\n\n let allItems: T[] = []\n let isContinue = true\n let nextId = 0\n do {\n const sendParams = { ...requestParams }\n sendParams.filter.push([idKey, '>', nextId])\n const response: AjaxResult<T> = await this._b24.actions.v3.call.make<T>({\n method: options.method,\n params: requestParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('callFastListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n for (const [index, error] of response.errors) {\n result.addError(error, index)\n }\n isContinue = false\n break\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n const resultData = (responseData.result as any)[customKeyForResult] as T[]\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n allItems = [...allItems, ...resultData]\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (lastItem && typeof lastItem[idKey] !== 'undefined') {\n nextId = Number.parseInt(lastItem[idKey] as string)\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n\n return result.setData(allItems)\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call-list.mjs","sources":["../../../../../src/core/actions/v3/call-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { Result } from '../../result'\n\nexport type ActionCallListV3 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'pagination' | 'order'>\n idKey?: string\n customKeyForResult: string\n requestId?: string\n limit?: number\n}\n\n/**\n * Fast data retrieval without counting the total number of records. `restApi:v3`\n *\n * @todo add docs\n */\nexport class CallListV3 extends AbstractAction {\n /**\n * Fast data retrieval without counting the total number of records.\n *\n * @template T - The type of the elements of the returned array (default is `unknown`).\n *\n * @param {ActionCallListV3} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'pagination'>` - Request parameters, excluding the `pagination` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'id'. Alternatively, it can be another field, depending on the REST API data structure.\n * - `customKeyForResult: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n * - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.\n *\n * @returns {Promise<Result<T[]>>} A promise that resolves to the result of an REST API call.\n *\n * @example\n * import { Text } from '@bitrix24/b24jssdk'\n *\n * interface MainEventLogItem { id: number, userId: number }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const response = await b24.actions.v3.callList.make<MainEventLogItem>({\n * method: 'main.eventlog.list',\n * params: {\n * filter: [\n * ['timestampX', '>=', Text.toB24Format(sixMonthAgo)] // created at least 6 months ago\n * ],\n * select: ['id', 'userId']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'eventlog-123',\n * limit: 60\n * })\n * if (!response.isSuccess) {\n * throw new Error(`Problem: ${response.getErrorMessages().join('; ')}`)\n * }\n * const list = response.getData()\n * console.log(`Result: ${list?.length}`) // Number of items received\n */\n public override async make<T = unknown>(options: ActionCallListV3): Promise<Result<T[]>> {\n const batchSize = options?.limit ?? 50\n const result: Result<T[]> = new Result()\n\n const idKey = options?.idKey ?? 'id'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n // Warn and strip user-provided `order` — cursor pagination requires ordering by idKey only\n if ('order' in params && params['order']) {\n this._logger.warning('callList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.')\n }\n\n const { order: _ignoredOrder, ...restParams } = params as TypeCallParams\n const requestParams: TypeCallParams = {\n ...restParams,\n order: { [idKey]: 'ASC' },\n filter: [...(params['filter'] || [])],\n pagination: { page: 0, limit: batchSize }\n }\n\n let allItems: T[] = []\n let isContinue = true\n let nextId = 0\n do {\n const sendParams = { ...requestParams, filter: [...requestParams.filter] }\n sendParams.filter.push([idKey, '>', nextId])\n const response: AjaxResult<T> = await this._b24.actions.v3.call.make<T>({\n method: options.method,\n params: sendParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('callFastListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n for (const [index, error] of response.errors) {\n result.addError(error, index)\n }\n isContinue = false\n break\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n const resultData = (responseData.result as any)[customKeyForResult] as T[]\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n allItems = [...allItems, ...resultData]\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (lastItem && typeof lastItem[idKey] !== 'undefined') {\n nextId = Number.parseInt(lastItem[idKey] as string)\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n\n return result.setData(allItems)\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -68,20 +68,24 @@ class FetchListV3 extends AbstractAction {
68
68
  const idKey = options?.idKey ?? "id";
69
69
  const customKeyForResult = options?.customKeyForResult ?? null;
70
70
  const params = options?.params ?? {};
71
+ if ("order" in params && params["order"]) {
72
+ this._logger.warning("fetchList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.");
73
+ }
74
+ const { order: _ignoredOrder, ...restParams } = params;
71
75
  const requestParams = {
72
- ...params,
73
- order: { ...params["order"] || {}, [idKey]: "ASC" },
76
+ ...restParams,
77
+ order: { [idKey]: "ASC" },
74
78
  filter: [...params["filter"] || []],
75
79
  pagination: { page: 0, limit: batchSize }
76
80
  };
77
81
  let isContinue = true;
78
82
  let nextId = 0;
79
83
  do {
80
- const sendParams = { ...requestParams };
84
+ const sendParams = { ...requestParams, filter: [...requestParams.filter] };
81
85
  sendParams.filter.push([idKey, ">", nextId]);
82
86
  const response = await this._b24.actions.v3.call.make({
83
87
  method: options.method,
84
- params: requestParams,
88
+ params: sendParams,
85
89
  requestId: options.requestId
86
90
  });
87
91
  if (!response.isSuccess) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-list.mjs","sources":["../../../../../src/core/actions/v3/fetch-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { SdkError } from '../../sdk-error'\n\nexport type ActionFetchListV3 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'pagination'>\n idKey?: string\n customKeyForResult: string\n requestId?: string\n limit?: number\n}\n\n/**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v3`\n *\n * @todo add docs\n */\nexport class FetchListV3 extends AbstractAction {\n /**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval.\n * Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.\n *\n * @template T - The type of items in the returned arrays (default is `unknown`).\n *\n * @param {ActionFetchListV3} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'pagination'>` - Request parameters, excluding the `pagination` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'id'. Alternatively, it can be another field, depending on the REST API data structure.\n * - `customKeyForResult: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n * - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.\n *\n * @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.\n * Each iteration returns the next page/batch of results until all data is fetched.\n *\n * @example\n * import { Text } from '@bitrix24/b24jssdk'\n *\n * interface MainEventLogItem { id: number, userId: number }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const generator = b24.actions.v3.fetchList.make<MainEventLogItem>({\n * method: 'main.eventlog.list',\n * params: {\n * filter: [\n * ['timestampX', '>=', Text.toB24Format(sixMonthAgo)] // created at least 6 months ago\n * ],\n * select: ['id', 'userId']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'eventlog-123',\n * limit: 60\n * })\n *\n * for await (const chunk of generator) {\n * // Process chunk (e.g., save to database, analyze, etc.)\n * console.log(`Processing ${chunk.length} items`)\n * }\n */\n public override async* make<T = unknown>(options: ActionFetchListV3): AsyncGenerator<T[]> {\n const batchSize = options?.limit ?? 50\n\n const idKey = options?.idKey ?? 'id'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n const requestParams: TypeCallParams = {\n ...params,\n order: { ...(params['order'] || {}), [idKey]: 'ASC' },\n filter: [...(params['filter'] || [])],\n pagination: { page: 0, limit: batchSize }\n }\n\n let isContinue = true\n let nextId = 0\n do {\n const sendParams = { ...requestParams }\n sendParams.filter.push([idKey, '>', nextId])\n\n const response: AjaxResult<T> = await this._b24.actions.v3.call.make<T>({\n method: options.method,\n params: requestParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('fetchListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n throw new SdkError({\n code: 'JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V3',\n description: `API Error: ${response.getErrorMessages().join('; ')}`,\n status: 500\n })\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n const resultData: T[] = (responseData.result as any)[customKeyForResult] as T[]\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n yield resultData\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (\n lastItem\n && typeof lastItem[idKey] !== 'undefined'\n ) {\n nextId = Number.parseInt(lastItem[idKey] as string)\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-list.mjs","sources":["../../../../../src/core/actions/v3/fetch-list.ts"],"sourcesContent":["import type { ActionOptions } from '../abstract-action'\nimport type { TypeCallParams } from '../../../types/http'\nimport type { AjaxResult } from '../../http/ajax-result'\nimport { AbstractAction } from '../abstract-action'\nimport { SdkError } from '../../sdk-error'\n\nexport type ActionFetchListV3 = ActionOptions & {\n method: string\n params?: Omit<TypeCallParams, 'pagination' | 'order'>\n idKey?: string\n customKeyForResult: string\n requestId?: string\n limit?: number\n}\n\n/**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval. `restApi:v3`\n *\n * @todo add docs\n */\nexport class FetchListV3 extends AbstractAction {\n /**\n * Calls a REST API list method and returns an async generator for efficient large data retrieval.\n * Implements the fast algorithm for iterating over large datasets without loading all data into memory at once.\n *\n * @template T - The type of items in the returned arrays (default is `unknown`).\n *\n * @param {ActionFetchListV3} options - parameters for executing the request.\n * - `method: string` - The name of the REST API method that returns a list of data (for example: `crm.item.list`, `tasks.task.list`)\n * - `params?: Omit<TypeCallParams, 'pagination'>` - Request parameters, excluding the `pagination` parameter,\n * since the method is designed to obtain all data in one call.\n * Note: Use `filter`, `order`, and `select` to control the selection.\n * - `idKey?: string` - The name of the field containing the unique identifier of the element.\n * Default is 'id'. Alternatively, it can be another field, depending on the REST API data structure.\n * - `customKeyForResult: string` - A custom key indicating that the response REST API will be\n * grouped by this field.\n * Example: `items` to group a list of CRM items.\n * - `requestId?: string` - Unique request identifier for tracking. Used for query deduplication and debugging.\n * - `limit?: number` - How many records to retrieve at a time. Default is `50`. Maximum is `1000`.\n *\n * @returns {AsyncGenerator<T[]>} An async generator that yields chunks of data as arrays of type `T`.\n * Each iteration returns the next page/batch of results until all data is fetched.\n *\n * @example\n * import { Text } from '@bitrix24/b24jssdk'\n *\n * interface MainEventLogItem { id: number, userId: number }\n * const sixMonthAgo = new Date()\n * sixMonthAgo.setMonth((new Date()).getMonth() - 6)\n * sixMonthAgo.setHours(0, 0, 0)\n * const generator = b24.actions.v3.fetchList.make<MainEventLogItem>({\n * method: 'main.eventlog.list',\n * params: {\n * filter: [\n * ['timestampX', '>=', Text.toB24Format(sixMonthAgo)] // created at least 6 months ago\n * ],\n * select: ['id', 'userId']\n * },\n * idKey: 'id',\n * customKeyForResult: 'items',\n * requestId: 'eventlog-123',\n * limit: 60\n * })\n *\n * for await (const chunk of generator) {\n * // Process chunk (e.g., save to database, analyze, etc.)\n * console.log(`Processing ${chunk.length} items`)\n * }\n */\n public override async* make<T = unknown>(options: ActionFetchListV3): AsyncGenerator<T[]> {\n const batchSize = options?.limit ?? 50\n\n const idKey = options?.idKey ?? 'id'\n const customKeyForResult = options?.customKeyForResult ?? null\n const params = options?.params ?? {}\n\n // Warn and strip user-provided `order` — cursor pagination requires ordering by idKey only\n if ('order' in params && params['order']) {\n this._logger.warning('fetchList.make: user-provided `order` parameter is ignored because cursor-based pagination requires ordering by idKey. Use `filter` to narrow results instead.')\n }\n\n const { order: _ignoredOrder, ...restParams } = params as TypeCallParams\n const requestParams: TypeCallParams = {\n ...restParams,\n order: { [idKey]: 'ASC' },\n filter: [...(params['filter'] || [])],\n pagination: { page: 0, limit: batchSize }\n }\n\n let isContinue = true\n let nextId = 0\n do {\n const sendParams = { ...requestParams, filter: [...requestParams.filter] }\n sendParams.filter.push([idKey, '>', nextId])\n\n const response: AjaxResult<T> = await this._b24.actions.v3.call.make<T>({\n method: options.method,\n params: sendParams,\n requestId: options.requestId\n })\n\n if (!response.isSuccess) {\n this._logger.error('fetchListMethod', {\n method: options.method,\n requestId: options.requestId,\n messages: response.getErrorMessages()\n })\n throw new SdkError({\n code: 'JSSDK_CORE_B24_FETCH_LIST_METHOD_API_V3',\n description: `API Error: ${response.getErrorMessages().join('; ')}`,\n status: 500\n })\n }\n const responseData = response.getData()\n if (!responseData) {\n isContinue = false\n break\n }\n\n const resultData: T[] = (responseData.result as any)[customKeyForResult] as T[]\n if (resultData.length === 0) {\n isContinue = false\n break\n }\n\n yield resultData\n\n if (resultData.length < batchSize) {\n isContinue = false\n break\n }\n\n // Update the filter for the next iteration\n const lastItem = resultData[resultData.length - 1] as Record<string, any>\n if (\n lastItem\n && typeof lastItem[idKey] !== 'undefined'\n ) {\n nextId = Number.parseInt(lastItem[idKey] as string)\n } else {\n isContinue = false\n break\n }\n } while (isContinue)\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -44,7 +44,7 @@ class AbstractHttp {
44
44
  this._logger = LoggerFactory.createNullLogger();
45
45
  const defaultHeaders = {};
46
46
  if (this.isServerSide()) {
47
- defaultHeaders["User-Agent"] = "b24-js-sdk/1.0.5";
47
+ defaultHeaders["User-Agent"] = "b24-js-sdk/1.1.0";
48
48
  }
49
49
  this._authActions = authActions;
50
50
  this._requestIdGenerator = new RequestIdGenerator();
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @package @bitrix24/b24jssdk
3
- * @version 1.0.5
3
+ * @version 1.1.0
4
4
  * @copyright (c) 2026 Bitrix24
5
5
  * @license MIT
6
6
  * @see https://github.com/bitrix24/b24jssdk
@@ -45,8 +45,6 @@ class AjaxResult extends Result {
45
45
  const payload = this._data;
46
46
  return Object.freeze({
47
47
  result: payload.result,
48
- next: "next" in payload ? payload.next : void 0,
49
- total: "total" in payload ? payload.total : void 0,
50
48
  time: payload.time
51
49
  });
52
50
  }
@@ -103,10 +101,27 @@ class AjaxResult extends Result {
103
101
  }
104
102
  /**
105
103
  * Alias for isMore
104
+ *
105
+ * @deprecated Will be removed in `2.0.0`. Tied to the `restApi:v2` envelope
106
+ * field `next`, which `restApi:v3` does not return. Use the SDK's list
107
+ * helpers — they hide pagination entirely:
108
+ * - `restApi:v2`: {@link CallListV2.make `b24.actions.v2.callList.make`} or {@link FetchListV2.make `b24.actions.v2.fetchList.make`}
109
+ * - `restApi:v3`: {@link CallListV3.make `b24.actions.v3.callList.make`} or {@link FetchListV3.make `b24.actions.v3.fetchList.make`}
110
+ *
111
+ * @removed 2.0.0
106
112
  */
107
113
  hasMore() {
108
114
  return this.isMore();
109
115
  }
116
+ /**
117
+ * @deprecated Will be removed in `2.0.0`. Tied to the `restApi:v2` envelope
118
+ * field `next`, which `restApi:v3` does not return. Use the SDK's list
119
+ * helpers — they hide pagination entirely:
120
+ * - `restApi:v2`: {@link CallListV2.make `b24.actions.v2.callList.make`} or {@link FetchListV2.make `b24.actions.v2.fetchList.make`}
121
+ * - `restApi:v3`: {@link CallListV3.make `b24.actions.v3.callList.make`} or {@link FetchListV3.make `b24.actions.v3.fetchList.make`}
122
+ *
123
+ * @removed 2.0.0
124
+ */
110
125
  isMore() {
111
126
  if (!this.isSuccess) {
112
127
  return false;
@@ -115,6 +130,15 @@ class AjaxResult extends Result {
115
130
  const nextValue = "next" in payload ? payload.next : void 0;
116
131
  return Type.isNumber(nextValue);
117
132
  }
133
+ /**
134
+ * @deprecated Will be removed in `2.0.0`. Tied to the `restApi:v2` envelope
135
+ * field `total`, which `restApi:v3` does not return. For `restApi:v3` the
136
+ * SDK exposes element counts via the `aggregate` action (`count` /
137
+ * `countDistinct`); for `restApi:v2` use the list helpers, which iterate
138
+ * without exposing `total`.
139
+ *
140
+ * @removed 2.0.0
141
+ */
118
142
  getTotal() {
119
143
  if (!this.isSuccess) {
120
144
  return 0;
@@ -133,7 +157,13 @@ class AjaxResult extends Result {
133
157
  * Alias for getNext
134
158
  * @param http
135
159
  *
136
- * @todo !fix api version
160
+ * @deprecated Will be removed in `2.0.0`. `restApi:v3` does not support
161
+ * `getNext()` (the v2 envelope field `next` does not exist). Use the SDK's
162
+ * list helpers instead — they hide pagination entirely:
163
+ * - `restApi:v2`: {@link CallListV2.make `b24.actions.v2.callList.make`} or {@link FetchListV2.make `b24.actions.v2.fetchList.make`}
164
+ * - `restApi:v3`: {@link CallListV3.make `b24.actions.v3.callList.make`} or {@link FetchListV3.make `b24.actions.v3.fetchList.make`}
165
+ *
166
+ * @removed 2.0.0
137
167
  */
138
168
  async fetchNext(http) {
139
169
  const data = await this.getNext(http);
@@ -142,6 +172,16 @@ class AjaxResult extends Result {
142
172
  }
143
173
  return data;
144
174
  }
175
+ /**
176
+ * @deprecated Will be removed in `2.0.0`. Throws on `restApi:v3` because the
177
+ * v2 envelope field `next` is not part of the v3 protocol. Use the SDK's
178
+ * list helpers instead — they hide pagination entirely:
179
+ * - `restApi:v2`: {@link CallListV2.make `b24.actions.v2.callList.make`} or {@link FetchListV2.make `b24.actions.v2.fetchList.make`}
180
+ * - `restApi:v3`: {@link CallListV3.make `b24.actions.v3.callList.make`} or {@link FetchListV3.make `b24.actions.v3.fetchList.make`}
181
+ *
182
+ * @throws {SdkError} `JSSDK_CORE_METHOD_NOT_SUPPORT_IN_API_V3` when called against a `restApi:v3` HTTP client. This throw is preserved until `2.0.0`.
183
+ * @removed 2.0.0
184
+ */
145
185
  async getNext(http) {
146
186
  if (http.apiVersion === ApiVersion.v3) {
147
187
  throw new SdkError({