@bitrix24/b24jssdk 0.1.7 → 0.2.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @version @bitrix24/b24jssdk v0.1.7
2
+ * @version @bitrix24/b24jssdk v0.2.1
3
3
  * @copyright (c) 2025 Bitrix24
4
4
  * @licence MIT
5
5
  * @links https://github.com/bitrix24/b24jssdk - GitHub
@@ -489,6 +489,24 @@ class TypeManager {
489
489
  }
490
490
  const Type = new TypeManager();
491
491
 
492
+ function pick(data, keys) {
493
+ const result = {};
494
+ for (const key of keys) {
495
+ result[key] = data[key];
496
+ }
497
+ return result;
498
+ }
499
+ function omit(data, keys) {
500
+ const result = { ...data };
501
+ for (const key of keys) {
502
+ delete result[key];
503
+ }
504
+ return result;
505
+ }
506
+ function isArrayOfArray(item) {
507
+ return Array.isArray(item[0]);
508
+ }
509
+
492
510
  const _state = {};
493
511
  let getRandomValues;
494
512
  const randoms8 = new Uint8Array(16);
@@ -664,7 +682,6 @@ class TextManager {
664
682
  return str;
665
683
  }
666
684
  const matches = str.match(
667
- // eslint-disable-next-line
668
685
  /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
669
686
  );
670
687
  if (!matches) {
@@ -1033,75 +1050,42 @@ var RpcMethod = /* @__PURE__ */ ((RpcMethod2) => {
1033
1050
  })(RpcMethod || {});
1034
1051
 
1035
1052
  class Result {
1036
- _errorCollection;
1053
+ _errors;
1037
1054
  _data;
1038
- constructor() {
1039
- this._errorCollection = /* @__PURE__ */ new Set();
1040
- this._data = null;
1055
+ constructor(data) {
1056
+ this._errors = /* @__PURE__ */ new Map();
1057
+ this._data = data ?? null;
1041
1058
  }
1042
- /**
1043
- * Getter for the `isSuccess` property.
1044
- * Checks if the `_errorCollection` is empty to determine success.
1045
- *
1046
- * @returns Whether the operation resulted in success (no errors).
1047
- */
1048
1059
  get isSuccess() {
1049
- return this._errorCollection.size === 0;
1060
+ return this._errors.size === 0;
1061
+ }
1062
+ get errors() {
1063
+ return this._errors;
1050
1064
  }
1051
- /**
1052
- * Sets the data associated with the result.
1053
- *
1054
- * @param data The data to be stored in the result.
1055
- * @returns The current Result object for chaining methods.
1056
- */
1057
1065
  setData(data) {
1058
1066
  this._data = data;
1059
1067
  return this;
1060
1068
  }
1061
- /**
1062
- * Retrieves the data associated with the result.
1063
- *
1064
- * @returns The data stored in the result, if any.
1065
- */
1066
1069
  getData() {
1067
1070
  return this._data;
1068
1071
  }
1069
- /**
1070
- * Adds an error message or Error object to the result.
1071
- *
1072
- * @param error The error message or Error object to be added.
1073
- * @returns The current Result object for chaining methods.
1074
- */
1075
- addError(error) {
1076
- if (error instanceof Error) {
1077
- this._errorCollection.add(error);
1078
- } else {
1079
- this._errorCollection.add(new Error(error.toString()));
1080
- }
1072
+ addError(error, key) {
1073
+ const errorKey = key ?? Text.getUuidRfc4122();
1074
+ const errorObj = typeof error === "string" ? new Error(error) : error;
1075
+ this._errors.set(errorKey, errorObj);
1081
1076
  return this;
1082
1077
  }
1083
- /**
1084
- * Adds multiple errors to the result in a single call.
1085
- *
1086
- * @param errors An array of errors or strings that will be converted to errors.
1087
- * @returns The current Result object for chaining methods.
1088
- */
1089
1078
  addErrors(errors) {
1090
1079
  for (const error of errors) {
1091
- if (error instanceof Error) {
1092
- this._errorCollection.add(error);
1093
- } else {
1094
- this._errorCollection.add(new Error(error.toString()));
1095
- }
1080
+ this.addError(error);
1096
1081
  }
1097
1082
  return this;
1098
1083
  }
1099
- /**
1100
- * Retrieves an iterator for the errors collected in the result.
1101
- * @returns An iterator over the stored Error objects.
1102
- */
1103
1084
  getErrors() {
1104
- return this._errorCollection.values();
1085
+ return this._errors.values();
1086
+ }
1087
+ hasError(key) {
1088
+ return this._errors.has(key);
1105
1089
  }
1106
1090
  /**
1107
1091
  * Retrieves an array of error messages from the collected errors.
@@ -1110,7 +1094,7 @@ class Result {
1110
1094
  * contains the message of a corresponding error object.
1111
1095
  */
1112
1096
  getErrorMessages() {
1113
- return [...this.getErrors()].map((error) => error.message);
1097
+ return Array.from(this._errors.values(), (e) => e.message);
1114
1098
  }
1115
1099
  /**
1116
1100
  * Converts the Result object to a string.
@@ -1118,36 +1102,168 @@ class Result {
1118
1102
  * @returns {string} Returns a string representation of the result operation
1119
1103
  */
1120
1104
  toString() {
1121
- if (this.isSuccess) {
1122
- return `Result (success): data: ${JSON.stringify(this._data)}`;
1105
+ const status = this.isSuccess ? "success" : "failure";
1106
+ const data = this.safeStringify(this._data);
1107
+ return this.isSuccess ? `Result(${status}): ${data}` : `Result(${status}): ${data}
1108
+ Errors: ${this.getErrorMessages().join(", ")}`;
1109
+ }
1110
+ safeStringify(data) {
1111
+ try {
1112
+ return JSON.stringify(data, this.replacer, 2);
1113
+ } catch {
1114
+ return "[Unable to serialize data]";
1115
+ }
1116
+ }
1117
+ replacer(_, value) {
1118
+ if (value instanceof Error) {
1119
+ return {
1120
+ name: value.name,
1121
+ message: value.message,
1122
+ stack: value.stack
1123
+ };
1123
1124
  }
1124
- return `Result (failure): errors: ${this.getErrorMessages().join(", ")}`;
1125
+ return value;
1126
+ }
1127
+ // Static constructors
1128
+ static ok(data) {
1129
+ return new Result(data);
1130
+ }
1131
+ static fail(error, key) {
1132
+ return new Result().addError(error, key);
1125
1133
  }
1126
1134
  }
1127
1135
 
1128
1136
  class AjaxError extends Error {
1129
- cause;
1137
+ code;
1130
1138
  _status;
1131
- _answerError;
1132
- constructor(params) {
1133
- const message = `${params.answerError.error}${params.answerError.errorDescription ? ": " + params.answerError.errorDescription : ""}`;
1139
+ requestInfo;
1140
+ timestamp;
1141
+ originalError;
1142
+ // override cause: null | Error
1143
+ // private _status: number
1144
+ // private _answerError: AnswerError
1145
+ constructor(details) {
1146
+ const message = AjaxError.formatErrorMessage(details);
1134
1147
  super(message);
1135
- this.cause = params.cause || null;
1136
- this.name = this.constructor.name;
1137
- this._status = params.status;
1138
- this._answerError = params.answerError;
1139
- }
1148
+ this.name = "AjaxError";
1149
+ this.code = details.code;
1150
+ this._status = details.status;
1151
+ this.requestInfo = details.requestInfo;
1152
+ this.originalError = details.originalError;
1153
+ this.timestamp = /* @__PURE__ */ new Date();
1154
+ this.cleanErrorStack();
1155
+ }
1156
+ // constructor(params: AjaxErrorParams) {
1157
+ // const message = `${ params.answerError.error }${
1158
+ // params.answerError.errorDescription
1159
+ // ? ': ' + params.answerError.errorDescription
1160
+ // : ''
1161
+ // }`
1162
+ //
1163
+ // super(message)
1164
+ // this.cause = params.cause || null
1165
+ // this.name = this.constructor.name
1166
+ //
1167
+ // this._status = params.status
1168
+ // this._answerError = params.answerError
1169
+ // }
1170
+ /**
1171
+ * @deprecated
1172
+ */
1140
1173
  get answerError() {
1141
- return this._answerError;
1174
+ return {
1175
+ error: this.message,
1176
+ errorDescription: ""
1177
+ };
1142
1178
  }
1143
1179
  get status() {
1144
1180
  return this._status;
1145
1181
  }
1182
+ /**
1183
+ * @deprecated
1184
+ */
1146
1185
  set status(status) {
1147
1186
  this._status = status;
1148
1187
  }
1188
+ /**
1189
+ * Creates AjaxError from HTTP response
1190
+ */
1191
+ static fromResponse(response) {
1192
+ return new AjaxError({
1193
+ code: response.data?.error || "unknown_error",
1194
+ description: response.data?.error_description,
1195
+ status: response.status,
1196
+ requestInfo: {
1197
+ method: response.config?.method?.toUpperCase(),
1198
+ url: response.config?.url,
1199
+ params: response.config?.params
1200
+ }
1201
+ });
1202
+ }
1203
+ /**
1204
+ * Creates AjaxError from exception
1205
+ */
1206
+ static fromException(error, context) {
1207
+ if (error instanceof AjaxError) return error;
1208
+ return new AjaxError({
1209
+ code: context?.code || "internal_error",
1210
+ status: context?.status || 500,
1211
+ description: error instanceof Error ? error.message : String(error),
1212
+ requestInfo: context?.requestInfo,
1213
+ originalError: error
1214
+ });
1215
+ }
1216
+ /**
1217
+ * Serializes error for logging and debugging
1218
+ */
1219
+ toJSON() {
1220
+ return {
1221
+ name: this.name,
1222
+ code: this.code,
1223
+ message: this.message,
1224
+ status: this._status,
1225
+ timestamp: this.timestamp.toISOString(),
1226
+ requestInfo: this.requestInfo,
1227
+ stack: this.stack
1228
+ };
1229
+ }
1230
+ // override toString(): string {
1231
+ // return `${ this.answerError.error }${
1232
+ // this.answerError.errorDescription
1233
+ // ? ': ' + this.answerError.errorDescription
1234
+ // : ''
1235
+ // } (${ this.status })`
1236
+ // }
1237
+ /**
1238
+ * Formats error information for human-readable output
1239
+ */
1149
1240
  toString() {
1150
- return `${this.answerError.error}${this.answerError.errorDescription ? ": " + this.answerError.errorDescription : ""} (${this.status})`;
1241
+ let output = `[${this.name}] ${this.code} (${this._status}): ${this.message}`;
1242
+ if (this.requestInfo) {
1243
+ output += `
1244
+ Request: ${this.requestInfo.method} ${this.requestInfo.url}`;
1245
+ }
1246
+ if (this.stack) {
1247
+ output += `
1248
+ Stack trace:
1249
+ ${this.stack}`;
1250
+ }
1251
+ return output;
1252
+ }
1253
+ static formatErrorMessage(details) {
1254
+ const parts = [details.code];
1255
+ if (details.description) {
1256
+ parts.push(`- ${details.description}`);
1257
+ }
1258
+ if (details.requestInfo?.method && details.requestInfo.url) {
1259
+ parts.push(`(on ${details.requestInfo.method} ${details.requestInfo.url})`);
1260
+ }
1261
+ return parts.join(" ");
1262
+ }
1263
+ cleanErrorStack() {
1264
+ if (typeof this.stack === "string") {
1265
+ this.stack = this.stack.split("\n").filter((line) => !line.includes("AjaxError.constructor")).join("\n");
1266
+ }
1151
1267
  }
1152
1268
  }
1153
1269
 
@@ -1155,31 +1271,48 @@ class AjaxResult extends Result {
1155
1271
  _status;
1156
1272
  _query;
1157
1273
  _data;
1158
- constructor(answer, query, status) {
1274
+ constructor(options) {
1159
1275
  super();
1160
- this._data = answer;
1161
- this._query = structuredClone(query);
1162
- this._status = status;
1163
- if (typeof this._data.error !== "undefined") {
1164
- const error = typeof this._data.error === "string" ? this._data : this._data.error;
1165
- this.addError(
1166
- new AjaxError({
1167
- status: this._status,
1168
- answerError: {
1169
- error: error.error || "",
1170
- errorDescription: error.error_description || ""
1171
- }
1172
- })
1173
- );
1174
- }
1175
- }
1176
- // @ts-ignore
1177
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1178
- setData(data) {
1179
- throw new Error("AjaxResult not support setData()");
1276
+ this._data = Object.freeze(options.answer);
1277
+ this._query = Object.freeze(structuredClone(options.query));
1278
+ this._status = options.status;
1279
+ this.#processErrors();
1280
+ }
1281
+ #processErrors() {
1282
+ const { error } = this._data;
1283
+ if (!error) return;
1284
+ const errorParams = this.#normalizeError(error);
1285
+ this.addError(this.#createAjaxError(errorParams), "base-error");
1286
+ }
1287
+ #normalizeError(error) {
1288
+ return typeof error === "string" ? { code: error, description: this._data.error_description || "" } : { code: error.error, description: error.error_description || "" };
1289
+ }
1290
+ #createAjaxError(params) {
1291
+ return new AjaxError({
1292
+ code: String(this._status),
1293
+ description: params.description,
1294
+ status: this._status,
1295
+ requestInfo: {
1296
+ method: this._query.method,
1297
+ // url: '?',
1298
+ params: this._query.params
1299
+ }
1300
+ // request:
1301
+ });
1180
1302
  }
1181
1303
  getData() {
1182
- return this._data;
1304
+ return Object.freeze({
1305
+ result: this._data.result,
1306
+ next: this._data.next,
1307
+ total: this._data.total,
1308
+ time: this._data.time
1309
+ });
1310
+ }
1311
+ /**
1312
+ * Alias for isMore
1313
+ */
1314
+ hasMore() {
1315
+ return this.isMore();
1183
1316
  }
1184
1317
  isMore() {
1185
1318
  return Type.isNumber(this._data?.next);
@@ -1193,16 +1326,35 @@ class AjaxResult extends Result {
1193
1326
  getQuery() {
1194
1327
  return this._query;
1195
1328
  }
1196
- async getNext(http) {
1197
- if (this.isMore() && this.isSuccess) {
1198
- this._query.start = Number.parseInt(this._data?.next);
1199
- return http.call(
1200
- this._query.method,
1201
- this._query.params,
1202
- this._query.start
1203
- );
1329
+ /**
1330
+ * Alias for getNext
1331
+ * @param http
1332
+ */
1333
+ async fetchNext(http) {
1334
+ const data = await this.getNext(http);
1335
+ if (data === false) {
1336
+ return null;
1204
1337
  }
1205
- return Promise.resolve(false);
1338
+ return data;
1339
+ }
1340
+ async getNext(http) {
1341
+ if (!this.isMore() || !this.isSuccess) return false;
1342
+ const nextPageQuery = this.#buildNextPageQuery();
1343
+ return http.call(
1344
+ nextPageQuery.method,
1345
+ nextPageQuery.params,
1346
+ nextPageQuery.start
1347
+ );
1348
+ }
1349
+ #buildNextPageQuery() {
1350
+ return {
1351
+ ...this._query,
1352
+ start: Text.toInteger(this._data.next)
1353
+ };
1354
+ }
1355
+ // Immutable API
1356
+ setData() {
1357
+ throw new ReferenceError("AjaxResult does not allow data modification");
1206
1358
  }
1207
1359
  }
1208
1360
 
@@ -1389,33 +1541,37 @@ class Http {
1389
1541
  // endregion ////
1390
1542
  // region Actions Call ////
1391
1543
  async batch(calls, isHaltOnError = true) {
1392
- const isArrayMode = Array.isArray(calls);
1393
- const cmd = isArrayMode ? [] : {};
1544
+ if (Array.isArray(calls)) {
1545
+ return this.#batchAsArray(
1546
+ calls,
1547
+ isHaltOnError
1548
+ );
1549
+ }
1550
+ return this.#batchAsObject(
1551
+ calls,
1552
+ isHaltOnError
1553
+ );
1554
+ }
1555
+ async #batchAsObject(calls, isHaltOnError = true) {
1556
+ const cmd = {};
1394
1557
  let cnt = 0;
1395
1558
  const processRow = (row, index) => {
1396
1559
  let method = null;
1397
1560
  let params = null;
1398
- if (Array.isArray(row)) {
1399
- method = row[0];
1400
- params = row[1];
1401
- } else if (row.method) {
1402
- method = row.method;
1403
- params = row.params;
1561
+ if (row.method) {
1562
+ method = row.method ?? null;
1563
+ params = row?.params ?? null;
1564
+ } else if (Array.isArray(row) && row.length > 0) {
1565
+ method = row[0] ?? null;
1566
+ params = row[1] ?? null;
1404
1567
  }
1405
1568
  if (method) {
1406
1569
  cnt++;
1407
- const data = method + "?" + qs.stringify(params);
1408
- if (isArrayMode || Array.isArray(cmd)) {
1409
- cmd.push(data);
1410
- } else {
1411
- cmd[index] = data;
1412
- }
1570
+ cmd[index] = method + "?" + qs.stringify(params);
1413
1571
  }
1414
1572
  };
1415
- if (isArrayMode) {
1416
- for (const [index, item] of calls.entries()) processRow(item, index);
1417
- } else {
1418
- for (const [index, item] of Object.entries(calls)) processRow(item, index);
1573
+ for (const [index, row] of Object.entries(calls)) {
1574
+ processRow(row, index);
1419
1575
  }
1420
1576
  if (cnt < 1) {
1421
1577
  return Promise.resolve(new Result());
@@ -1425,7 +1581,7 @@ class Http {
1425
1581
  cmd
1426
1582
  }).then((response) => {
1427
1583
  const responseResult = response.getData().result;
1428
- const results = isArrayMode ? [] : {};
1584
+ const results = {};
1429
1585
  const processResponse = (row, index) => {
1430
1586
  if (
1431
1587
  // @ts-ignore
@@ -1433,8 +1589,8 @@ class Http {
1433
1589
  typeof responseResult.result_error[index] !== "undefined"
1434
1590
  ) {
1435
1591
  const q = row.split("?");
1436
- const data = new AjaxResult(
1437
- {
1592
+ results[index] = new AjaxResult({
1593
+ answer: {
1438
1594
  // @ts-ignore
1439
1595
  result: Type.isUndefined(responseResult.result[index]) ? (
1440
1596
  // @ts-ignore
@@ -1448,67 +1604,154 @@ class Http {
1448
1604
  // @ts-ignore
1449
1605
  total: responseResult.result_total[index],
1450
1606
  // @ts-ignore
1451
- next: responseResult.result_next[index]
1607
+ next: responseResult.result_next[index],
1608
+ // @todo test this ////
1609
+ // @ts-ignore
1610
+ time: responseResult.result_time[index]
1452
1611
  },
1453
- {
1612
+ query: {
1454
1613
  method: q[0] || "",
1455
1614
  params: qs.parse(q[1] || ""),
1456
1615
  start: 0
1457
1616
  },
1458
- response.getStatus()
1459
- );
1460
- if (isArrayMode || Array.isArray(results)) {
1461
- results.push(data);
1462
- } else {
1463
- results[index] = data;
1464
- }
1617
+ status: response.getStatus()
1618
+ });
1465
1619
  }
1466
1620
  };
1467
- if (Array.isArray(cmd)) {
1468
- for (const [index, item] of cmd.entries()) processResponse(item, index);
1469
- } else {
1470
- for (const [index, item] of Object.entries(cmd))
1471
- processResponse(item, index);
1621
+ for (const [index, row] of Object.entries(cmd)) {
1622
+ processResponse(row, index);
1472
1623
  }
1473
- let dataResult;
1624
+ const dataResult = {};
1474
1625
  const initError = (result2) => {
1626
+ if (result2.hasError("base-error")) {
1627
+ return result2.errors.get("base-error");
1628
+ }
1475
1629
  return new AjaxError({
1630
+ code: "0",
1631
+ description: result2.getErrorMessages().join("; "),
1476
1632
  status: 0,
1477
- answerError: {
1478
- error: result2.getErrorMessages().join("; "),
1479
- errorDescription: `batch ${result2.getQuery().method}: ${qs.stringify(result2.getQuery().params, { encode: false })}`
1633
+ requestInfo: {
1634
+ method: result2.getQuery().method,
1635
+ params: result2.getQuery().params
1480
1636
  },
1481
- cause: result2.getErrors().next().value
1637
+ originalError: result2.getErrors().next().value
1482
1638
  });
1483
1639
  };
1484
1640
  const result = new Result();
1485
- if (isArrayMode || Array.isArray(results)) {
1486
- dataResult = [];
1487
- for (const data of results) {
1488
- if (data.getStatus() !== 200 || !data.isSuccess) {
1489
- const error = initError(data);
1490
- if (!isHaltOnError && !data.isSuccess) {
1491
- result.addError(error);
1492
- continue;
1493
- }
1494
- return Promise.reject(error);
1641
+ for (const key of Object.keys(results)) {
1642
+ const data = results[key];
1643
+ if (data.getStatus() !== 200 || !data.isSuccess) {
1644
+ const error = initError(data);
1645
+ if (!isHaltOnError && !data.isSuccess) {
1646
+ result.addError(error, key);
1647
+ continue;
1495
1648
  }
1496
- dataResult.push(data.getData().result);
1649
+ return Promise.reject(error);
1497
1650
  }
1498
- } else {
1499
- dataResult = {};
1500
- for (const key of Object.keys(results)) {
1501
- const data = results[key];
1502
- if (data.getStatus() !== 200 || !data.isSuccess) {
1503
- const error = initError(data);
1504
- if (!isHaltOnError && !data.isSuccess) {
1505
- result.addError(error);
1506
- continue;
1507
- }
1508
- return Promise.reject(error);
1651
+ dataResult[key] = data.getData().result;
1652
+ }
1653
+ result.setData(dataResult);
1654
+ return Promise.resolve(result);
1655
+ });
1656
+ }
1657
+ async #batchAsArray(calls, isHaltOnError = true) {
1658
+ const cmd = [];
1659
+ let cnt = 0;
1660
+ const processRow = (row) => {
1661
+ let method = null;
1662
+ let params = null;
1663
+ if (row.method) {
1664
+ method = row.method ?? null;
1665
+ params = row?.params ?? null;
1666
+ } else if (Array.isArray(row) && row.length > 0) {
1667
+ method = row[0] ?? null;
1668
+ params = row[1] ?? null;
1669
+ }
1670
+ if (method) {
1671
+ cnt++;
1672
+ const data = method + "?" + qs.stringify(params);
1673
+ cmd.push(data);
1674
+ }
1675
+ };
1676
+ for (const [_, row] of calls.entries()) {
1677
+ processRow(row);
1678
+ }
1679
+ if (cnt < 1) {
1680
+ return Promise.resolve(new Result());
1681
+ }
1682
+ return this.call("batch", {
1683
+ halt: isHaltOnError ? 1 : 0,
1684
+ cmd
1685
+ }).then((response) => {
1686
+ const responseResult = response.getData().result;
1687
+ const results = [];
1688
+ const processResponse = (row, index) => {
1689
+ if (
1690
+ // @ts-ignore
1691
+ typeof responseResult.result[index] !== "undefined" || // @ts-ignore
1692
+ typeof responseResult.result_error[index] !== "undefined"
1693
+ ) {
1694
+ const q = row.split("?");
1695
+ const data = new AjaxResult({
1696
+ answer: {
1697
+ // @ts-ignore
1698
+ result: Type.isUndefined(responseResult.result[index]) ? (
1699
+ // @ts-ignore
1700
+ {}
1701
+ ) : (
1702
+ // @ts-ignore
1703
+ responseResult.result[index]
1704
+ ),
1705
+ // @ts-ignore
1706
+ error: responseResult?.result_error[index] || void 0,
1707
+ // @ts-ignore
1708
+ total: responseResult.result_total[index],
1709
+ // @ts-ignore
1710
+ next: responseResult.result_next[index],
1711
+ // @todo test this ////
1712
+ // @ts-ignore
1713
+ time: responseResult.result_time[index]
1714
+ },
1715
+ query: {
1716
+ method: q[0] || "",
1717
+ params: qs.parse(q[1] || ""),
1718
+ start: 0
1719
+ },
1720
+ status: response.getStatus()
1721
+ });
1722
+ results.push(data);
1723
+ }
1724
+ };
1725
+ for (const [index, row] of cmd.entries()) {
1726
+ processResponse(row, index);
1727
+ }
1728
+ const dataResult = [];
1729
+ const initError = (result2) => {
1730
+ if (result2.hasError("base-error")) {
1731
+ return result2.errors.get("base-error");
1732
+ }
1733
+ return new AjaxError({
1734
+ code: "0",
1735
+ description: result2.getErrorMessages().join("; "),
1736
+ status: 0,
1737
+ requestInfo: {
1738
+ method: result2.getQuery().method,
1739
+ params: result2.getQuery().params
1740
+ },
1741
+ originalError: result2.getErrors().next().value
1742
+ });
1743
+ };
1744
+ const result = new Result();
1745
+ for (const data of results) {
1746
+ if (data.getStatus() !== 200 || !data.isSuccess) {
1747
+ const error = initError(data);
1748
+ if (!isHaltOnError && !data.isSuccess) {
1749
+ result.addError(error);
1750
+ continue;
1509
1751
  }
1510
- dataResult[key] = data.getData().result;
1752
+ return Promise.reject(error);
1511
1753
  }
1754
+ dataResult.push(data.getData().result);
1512
1755
  }
1513
1756
  result.setData(dataResult);
1514
1757
  return Promise.resolve(result);
@@ -1556,9 +1799,14 @@ class Http {
1556
1799
  };
1557
1800
  }
1558
1801
  const problemError = new AjaxError({
1802
+ code: String(answerError.error),
1803
+ description: answerError.errorDescription,
1559
1804
  status: error_.response?.status || 0,
1560
- answerError,
1561
- cause: error_
1805
+ requestInfo: {
1806
+ method,
1807
+ params
1808
+ },
1809
+ originalError: error_
1562
1810
  });
1563
1811
  if (problemError.status === 401 && ["expired_token", "invalid_token"].includes(
1564
1812
  problemError.answerError.error
@@ -1592,9 +1840,14 @@ class Http {
1592
1840
  };
1593
1841
  }
1594
1842
  const problemError2 = new AjaxError({
1595
- status: error__.response?.status || 0,
1596
- answerError: answerError2,
1597
- cause: error__
1843
+ code: String(answerError2.error),
1844
+ description: answerError2.errorDescription,
1845
+ status: error_.response?.status || 0,
1846
+ requestInfo: {
1847
+ method,
1848
+ params
1849
+ },
1850
+ originalError: error__
1598
1851
  });
1599
1852
  return Promise.reject(problemError2);
1600
1853
  }
@@ -1603,15 +1856,15 @@ class Http {
1603
1856
  return Promise.reject(problemError);
1604
1857
  }
1605
1858
  ).then((response) => {
1606
- const result = new AjaxResult(
1607
- response.payload,
1608
- {
1859
+ const result = new AjaxResult({
1860
+ answer: response.payload,
1861
+ query: {
1609
1862
  method,
1610
1863
  params,
1611
1864
  start
1612
1865
  },
1613
- response.status
1614
- );
1866
+ status: response.status
1867
+ });
1615
1868
  return Promise.resolve(result);
1616
1869
  });
1617
1870
  }
@@ -1632,7 +1885,7 @@ class Http {
1632
1885
  result.logTag = this.#logTag;
1633
1886
  }
1634
1887
  result[this.#requestIdGenerator.getQueryStringParameterName()] = this.#requestIdGenerator.getRequestId();
1635
- result[this.#requestIdGenerator.getQueryStringSdkParameterName()] = "0.1.7";
1888
+ result[this.#requestIdGenerator.getQueryStringSdkParameterName()] = "0.2.1";
1636
1889
  if (!!result.data && !!result.data.start) {
1637
1890
  delete result.data.start;
1638
1891
  }
@@ -2794,11 +3047,13 @@ var MessageCommands = /* @__PURE__ */ ((MessageCommands2) => {
2794
3047
  class MessageManager {
2795
3048
  #appFrame;
2796
3049
  #callbackPromises;
3050
+ #callbackSingletone;
2797
3051
  _logger = null;
2798
3052
  runCallbackHandler;
2799
3053
  constructor(appFrame) {
2800
3054
  this.#appFrame = appFrame;
2801
3055
  this.#callbackPromises = /* @__PURE__ */ new Map();
3056
+ this.#callbackSingletone = /* @__PURE__ */ new Map();
2802
3057
  this.runCallbackHandler = this._runCallback.bind(this);
2803
3058
  }
2804
3059
  setLogger(logger) {
@@ -2848,17 +3103,22 @@ class MessageManager {
2848
3103
  timeoutId: null
2849
3104
  };
2850
3105
  const keyPromise = this.#setCallbackPromise(promiseHandler);
3106
+ const paramsSend = omit(params || {}, ["callBack", "isSafely", "safelyTime"]);
3107
+ const { callBack } = params || {};
3108
+ if (callBack) {
3109
+ this.#callbackSingletone.set(keyPromise, callBack);
3110
+ }
2851
3111
  if (command.toString().includes(":")) {
2852
3112
  cmd = {
2853
3113
  method: command.toString(),
2854
- params: params ?? "",
3114
+ params: paramsSend ?? "",
2855
3115
  callback: keyPromise,
2856
3116
  appSid: this.#appFrame.getAppSid()
2857
3117
  };
2858
3118
  } else {
2859
3119
  cmd = command.toString();
2860
3120
  const listParams = [
2861
- params ? JSON.stringify(params) : null,
3121
+ params ? JSON.stringify(paramsSend) : null,
2862
3122
  keyPromise,
2863
3123
  this.#appFrame.getAppSid()
2864
3124
  ];
@@ -2913,6 +3173,11 @@ class MessageManager {
2913
3173
  }
2914
3174
  this.#callbackPromises.delete(cmd.id);
2915
3175
  promise.resolve(cmd.args);
3176
+ } else if (this.#callbackSingletone.has(cmd.id)) {
3177
+ const callBack = this.#callbackSingletone.get(cmd.id);
3178
+ if (callBack) {
3179
+ callBack.apply(globalThis, [cmd.args]);
3180
+ }
2916
3181
  }
2917
3182
  }
2918
3183
  }
@@ -3639,15 +3904,17 @@ class PlacementManager {
3639
3904
  /**
3640
3905
  * Set Up the Interface Event Handler
3641
3906
  * @param {string} eventName
3907
+ * @param {(...args: any[]) => void} callBack
3642
3908
  * @return {Promise<any>}
3643
3909
  *
3644
3910
  * @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-bind-event.html
3645
3911
  */
3646
- async bindEvent(eventName) {
3912
+ async bindEvent(eventName, callBack) {
3647
3913
  return this.#messageManager.send(
3648
- MessageCommands.getInterface,
3914
+ MessageCommands.placementBindEvent,
3649
3915
  {
3650
3916
  event: eventName,
3917
+ callBack,
3651
3918
  isSafely: true
3652
3919
  }
3653
3920
  );
@@ -11604,7 +11871,7 @@ class PullClient {
11604
11871
  }
11605
11872
  if (message.extra.server_time_unix) {
11606
11873
  message.extra.server_time_ago = (Date.now() - message.extra.server_time_unix * 1e3) / 1e3 - (this._config?.server.timeShift || 0);
11607
- message.extra.server_time_ago = message.extra.server_time_ago > 0 ? message.extra.server_time_ago : 0;
11874
+ message.extra.server_time_ago = Math.max(message.extra.server_time_ago, 0);
11608
11875
  }
11609
11876
  this.logMessage(message);
11610
11877
  try {
@@ -12670,7 +12937,7 @@ Data string: ${pullEvent}
12670
12937
  }
12671
12938
  trimDuplicates() {
12672
12939
  if (this._session.lastMessageIds.length > MAX_IDS_TO_STORE) {
12673
- this._session.lastMessageIds = this._session.lastMessageIds.slice(-MAX_IDS_TO_STORE);
12940
+ this._session.lastMessageIds = this._session.lastMessageIds.slice(-10);
12674
12941
  }
12675
12942
  }
12676
12943
  // endregion ////
@@ -12748,19 +13015,19 @@ Data string: ${pullEvent}
12748
13015
  * @deprecated
12749
13016
  */
12750
13017
  /*/
12751
- getRestClientOptions()
12752
- {
12753
- let result = {};
13018
+ getRestClientOptions()
13019
+ {
13020
+ let result = {};
12754
13021
 
12755
- if (this.guestMode && this.guestUserId !== 0)
12756
- {
12757
- result.queryParams = {
12758
- pull_guest_id: this.guestUserId
12759
- }
12760
- }
12761
- return result;
12762
- }
12763
- //*/
13022
+ if (this.guestMode && this.guestUserId !== 0)
13023
+ {
13024
+ result.queryParams = {
13025
+ pull_guest_id: this.guestUserId
13026
+ }
13027
+ }
13028
+ return result;
13029
+ }
13030
+ //*/
12764
13031
  // endregion ////
12765
13032
  }
12766
13033
 
@@ -13282,5 +13549,5 @@ async function initializeB24Frame() {
13282
13549
  });
13283
13550
  }
13284
13551
 
13285
- export { AbstractB24, AjaxError, AjaxResult, AppFrame, AuthHookManager, AuthManager, B24Frame, B24Hook, B24LangList, PullClient as B24PullClientManager, Browser, CloseReasons, ConnectionType, DataType, DialogManager, EnumAppStatus, EnumCrmEntityType, EnumCrmEntityTypeId, ListRpcError, LoadDataType, LoggerBrowser, LoggerType, LsKeys, MessageCommands, MessageManager, OptionsManager$1 as OptionsManager, ParentManager, PlacementManager, PullStatus, RestrictionManagerParamsBase, RestrictionManagerParamsForEnterprise, Result, RpcMethod, SenderType, ServerMode, SliderManager, StatusDescriptions, SubscriptionType, SystemCommands, Text, Type, TypeOption, TypeSpecificUrl, initializeB24Frame, useB24Helper, useFormatter };
13552
+ export { AbstractB24, AjaxError, AjaxResult, AppFrame, AuthHookManager, AuthManager, B24Frame, B24Hook, B24LangList, PullClient as B24PullClientManager, Browser, CloseReasons, ConnectionType, DataType, DialogManager, EnumAppStatus, EnumCrmEntityType, EnumCrmEntityTypeId, ListRpcError, LoadDataType, LoggerBrowser, LoggerType, LsKeys, MessageCommands, MessageManager, OptionsManager$1 as OptionsManager, ParentManager, PlacementManager, PullStatus, RestrictionManagerParamsBase, RestrictionManagerParamsForEnterprise, Result, RpcMethod, SenderType, ServerMode, SliderManager, StatusDescriptions, SubscriptionType, SystemCommands, Text, Type, TypeOption, TypeSpecificUrl, initializeB24Frame, isArrayOfArray, omit, pick, useB24Helper, useFormatter };
13286
13553
  //# sourceMappingURL=index.mjs.map