@bitrix24/b24jssdk 0.1.6 → 0.2.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.
package/dist/umd/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @version @bitrix24/b24jssdk v0.1.6
3
- * @copyright (c) 2024 Bitrix24
2
+ * @version @bitrix24/b24jssdk v0.2.0
3
+ * @copyright (c) 2025 Bitrix24
4
4
  * @licence MIT
5
5
  * @links https://github.com/bitrix24/b24jssdk - GitHub
6
6
  * @links https://bitrix24.github.io/b24jssdk/ - Documentation
@@ -885,12 +885,13 @@
885
885
  }
886
886
  }
887
887
 
888
- let dtfCache = {};
889
- function makeDTF(zone) {
890
- if (!dtfCache[zone]) {
891
- dtfCache[zone] = new Intl.DateTimeFormat("en-US", {
888
+ const dtfCache = new Map();
889
+ function makeDTF(zoneName) {
890
+ let dtf = dtfCache.get(zoneName);
891
+ if (dtf === undefined) {
892
+ dtf = new Intl.DateTimeFormat("en-US", {
892
893
  hour12: false,
893
- timeZone: zone,
894
+ timeZone: zoneName,
894
895
  year: "numeric",
895
896
  month: "2-digit",
896
897
  day: "2-digit",
@@ -899,8 +900,9 @@
899
900
  second: "2-digit",
900
901
  era: "short",
901
902
  });
903
+ dtfCache.set(zoneName, dtf);
902
904
  }
903
- return dtfCache[zone];
905
+ return dtf;
904
906
  }
905
907
 
906
908
  const typeToPos = {
@@ -936,7 +938,7 @@
936
938
  return filled;
937
939
  }
938
940
 
939
- let ianaZoneCache = {};
941
+ const ianaZoneCache = new Map();
940
942
  /**
941
943
  * A zone identified by an IANA identifier, like America/New_York
942
944
  * @implements {Zone}
@@ -947,10 +949,11 @@
947
949
  * @return {IANAZone}
948
950
  */
949
951
  static create(name) {
950
- if (!ianaZoneCache[name]) {
951
- ianaZoneCache[name] = new IANAZone(name);
952
+ let zone = ianaZoneCache.get(name);
953
+ if (zone === undefined) {
954
+ ianaZoneCache.set(name, (zone = new IANAZone(name)));
952
955
  }
953
- return ianaZoneCache[name];
956
+ return zone;
954
957
  }
955
958
 
956
959
  /**
@@ -958,8 +961,8 @@
958
961
  * @return {void}
959
962
  */
960
963
  static resetCache() {
961
- ianaZoneCache = {};
962
- dtfCache = {};
964
+ ianaZoneCache.clear();
965
+ dtfCache.clear();
963
966
  }
964
967
 
965
968
  /**
@@ -1062,6 +1065,7 @@
1062
1065
  * @return {number}
1063
1066
  */
1064
1067
  offset(ts) {
1068
+ if (!this.valid) return NaN;
1065
1069
  const date = new Date(ts);
1066
1070
 
1067
1071
  if (isNaN(date)) return NaN;
@@ -1127,36 +1131,36 @@
1127
1131
  return dtf;
1128
1132
  }
1129
1133
 
1130
- let intlDTCache = {};
1134
+ const intlDTCache = new Map();
1131
1135
  function getCachedDTF(locString, opts = {}) {
1132
1136
  const key = JSON.stringify([locString, opts]);
1133
- let dtf = intlDTCache[key];
1134
- if (!dtf) {
1137
+ let dtf = intlDTCache.get(key);
1138
+ if (dtf === undefined) {
1135
1139
  dtf = new Intl.DateTimeFormat(locString, opts);
1136
- intlDTCache[key] = dtf;
1140
+ intlDTCache.set(key, dtf);
1137
1141
  }
1138
1142
  return dtf;
1139
1143
  }
1140
1144
 
1141
- let intlNumCache = {};
1145
+ const intlNumCache = new Map();
1142
1146
  function getCachedINF(locString, opts = {}) {
1143
1147
  const key = JSON.stringify([locString, opts]);
1144
- let inf = intlNumCache[key];
1145
- if (!inf) {
1148
+ let inf = intlNumCache.get(key);
1149
+ if (inf === undefined) {
1146
1150
  inf = new Intl.NumberFormat(locString, opts);
1147
- intlNumCache[key] = inf;
1151
+ intlNumCache.set(key, inf);
1148
1152
  }
1149
1153
  return inf;
1150
1154
  }
1151
1155
 
1152
- let intlRelCache = {};
1156
+ const intlRelCache = new Map();
1153
1157
  function getCachedRTF(locString, opts = {}) {
1154
1158
  const { base, ...cacheKeyOpts } = opts; // exclude `base` from the options
1155
1159
  const key = JSON.stringify([locString, cacheKeyOpts]);
1156
- let inf = intlRelCache[key];
1157
- if (!inf) {
1160
+ let inf = intlRelCache.get(key);
1161
+ if (inf === undefined) {
1158
1162
  inf = new Intl.RelativeTimeFormat(locString, opts);
1159
- intlRelCache[key] = inf;
1163
+ intlRelCache.set(key, inf);
1160
1164
  }
1161
1165
  return inf;
1162
1166
  }
@@ -1171,14 +1175,28 @@
1171
1175
  }
1172
1176
  }
1173
1177
 
1174
- let weekInfoCache = {};
1178
+ const intlResolvedOptionsCache = new Map();
1179
+ function getCachedIntResolvedOptions(locString) {
1180
+ let opts = intlResolvedOptionsCache.get(locString);
1181
+ if (opts === undefined) {
1182
+ opts = new Intl.DateTimeFormat(locString).resolvedOptions();
1183
+ intlResolvedOptionsCache.set(locString, opts);
1184
+ }
1185
+ return opts;
1186
+ }
1187
+
1188
+ const weekInfoCache = new Map();
1175
1189
  function getCachedWeekInfo(locString) {
1176
- let data = weekInfoCache[locString];
1190
+ let data = weekInfoCache.get(locString);
1177
1191
  if (!data) {
1178
1192
  const locale = new Intl.Locale(locString);
1179
1193
  // browsers currently implement this as a property, but spec says it should be a getter function
1180
1194
  data = "getWeekInfo" in locale ? locale.getWeekInfo() : locale.weekInfo;
1181
- weekInfoCache[locString] = data;
1195
+ // minimalDays was removed from WeekInfo: https://github.com/tc39/proposal-intl-locale-info/issues/86
1196
+ if (!("minimalDays" in data)) {
1197
+ data = { ...fallbackWeekSettings, ...data };
1198
+ }
1199
+ weekInfoCache.set(locString, data);
1182
1200
  }
1183
1201
  return data;
1184
1202
  }
@@ -1277,7 +1295,7 @@
1277
1295
  loc.numberingSystem === "latn" ||
1278
1296
  !loc.locale ||
1279
1297
  loc.locale.startsWith("en") ||
1280
- new Intl.DateTimeFormat(loc.intl).resolvedOptions().numberingSystem === "latn"
1298
+ getCachedIntResolvedOptions(loc.locale).numberingSystem === "latn"
1281
1299
  );
1282
1300
  }
1283
1301
  }
@@ -1436,7 +1454,6 @@
1436
1454
  /**
1437
1455
  * @private
1438
1456
  */
1439
-
1440
1457
  class Locale {
1441
1458
  static fromOpts(opts) {
1442
1459
  return Locale.create(
@@ -1460,9 +1477,11 @@
1460
1477
 
1461
1478
  static resetCache() {
1462
1479
  sysLocaleCache = null;
1463
- intlDTCache = {};
1464
- intlNumCache = {};
1465
- intlRelCache = {};
1480
+ intlDTCache.clear();
1481
+ intlNumCache.clear();
1482
+ intlRelCache.clear();
1483
+ intlResolvedOptionsCache.clear();
1484
+ weekInfoCache.clear();
1466
1485
  }
1467
1486
 
1468
1487
  static fromObject({ locale, numberingSystem, outputCalendar, weekSettings } = {}) {
@@ -1616,7 +1635,7 @@
1616
1635
  return (
1617
1636
  this.locale === "en" ||
1618
1637
  this.locale.toLowerCase() === "en-us" ||
1619
- new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us")
1638
+ getCachedIntResolvedOptions(this.intl).locale.startsWith("en-us")
1620
1639
  );
1621
1640
  }
1622
1641
 
@@ -1955,22 +1974,26 @@
1955
1974
  }
1956
1975
 
1957
1976
  // cache of {numberingSystem: {append: regex}}
1958
- let digitRegexCache = {};
1977
+ const digitRegexCache = new Map();
1959
1978
  function resetDigitRegexCache() {
1960
- digitRegexCache = {};
1979
+ digitRegexCache.clear();
1961
1980
  }
1962
1981
 
1963
1982
  function digitRegex({ numberingSystem }, append = "") {
1964
1983
  const ns = numberingSystem || "latn";
1965
1984
 
1966
- if (!digitRegexCache[ns]) {
1967
- digitRegexCache[ns] = {};
1985
+ let appendCache = digitRegexCache.get(ns);
1986
+ if (appendCache === undefined) {
1987
+ appendCache = new Map();
1988
+ digitRegexCache.set(ns, appendCache);
1968
1989
  }
1969
- if (!digitRegexCache[ns][append]) {
1970
- digitRegexCache[ns][append] = new RegExp(`${numberingSystems[ns]}${append}`);
1990
+ let regex = appendCache.get(append);
1991
+ if (regex === undefined) {
1992
+ regex = new RegExp(`${numberingSystems[ns]}${append}`);
1993
+ appendCache.set(append, regex);
1971
1994
  }
1972
1995
 
1973
- return digitRegexCache[ns][append];
1996
+ return regex;
1974
1997
  }
1975
1998
 
1976
1999
  let now = () => Date.now(),
@@ -4722,6 +4745,14 @@
4722
4745
  return this.isValid ? this.e : null;
4723
4746
  }
4724
4747
 
4748
+ /**
4749
+ * Returns the last DateTime included in the interval (since end is not part of the interval)
4750
+ * @type {DateTime}
4751
+ */
4752
+ get lastDateTime() {
4753
+ return this.isValid ? (this.e ? this.e.minus(1) : null) : null;
4754
+ }
4755
+
4725
4756
  /**
4726
4757
  * Returns whether this Interval's end is at least its start, meaning that the Interval isn't 'backwards'.
4727
4758
  * @type {boolean}
@@ -4986,8 +5017,11 @@
4986
5017
  }
4987
5018
 
4988
5019
  /**
4989
- * Merge an array of Intervals into a equivalent minimal set of Intervals.
5020
+ * Merge an array of Intervals into an equivalent minimal set of Intervals.
4990
5021
  * Combines overlapping and adjacent Intervals.
5022
+ * The resulting array will contain the Intervals in ascending order, that is, starting with the earliest Interval
5023
+ * and ending with the latest.
5024
+ *
4991
5025
  * @param {Array} intervals
4992
5026
  * @return {Array}
4993
5027
  */
@@ -6310,15 +6344,27 @@
6310
6344
  // This is safe for quickDT (used by local() and utc()) because we don't fill in
6311
6345
  // higher-order units from tsNow (as we do in fromObject, this requires that
6312
6346
  // offset is calculated from tsNow).
6347
+ /**
6348
+ * @param {Zone} zone
6349
+ * @return {number}
6350
+ */
6313
6351
  function guessOffsetForZone(zone) {
6314
- if (!zoneOffsetGuessCache[zone]) {
6315
- if (zoneOffsetTs === undefined) {
6316
- zoneOffsetTs = Settings.now();
6317
- }
6352
+ if (zoneOffsetTs === undefined) {
6353
+ zoneOffsetTs = Settings.now();
6354
+ }
6318
6355
 
6319
- zoneOffsetGuessCache[zone] = zone.offset(zoneOffsetTs);
6356
+ // Do not cache anything but IANA zones, because it is not safe to do so.
6357
+ // Guessing an offset which is not present in the zone can cause wrong results from fixOffset
6358
+ if (zone.type !== "iana") {
6359
+ return zone.offset(zoneOffsetTs);
6360
+ }
6361
+ const zoneName = zone.name;
6362
+ let offsetGuess = zoneOffsetGuessCache.get(zoneName);
6363
+ if (offsetGuess === undefined) {
6364
+ offsetGuess = zone.offset(zoneOffsetTs);
6365
+ zoneOffsetGuessCache.set(zoneName, offsetGuess);
6320
6366
  }
6321
- return zoneOffsetGuessCache[zone];
6367
+ return offsetGuess;
6322
6368
  }
6323
6369
 
6324
6370
  // this is a dumbed down version of fromObject() that runs about 60% faster
@@ -6408,7 +6454,7 @@
6408
6454
  * This optimizes quickDT via guessOffsetForZone to avoid repeated calls of
6409
6455
  * zone.offset().
6410
6456
  */
6411
- let zoneOffsetGuessCache = {};
6457
+ const zoneOffsetGuessCache = new Map();
6412
6458
 
6413
6459
  /**
6414
6460
  * A DateTime is an immutable data structure representing a specific date and time and accompanying methods. It contains class and instance methods for creating, parsing, interrogating, transforming, and formatting them.
@@ -6612,7 +6658,7 @@
6612
6658
  throw new InvalidArgumentError(
6613
6659
  `fromMillis requires a numerical input, but received a ${typeof milliseconds} with value ${milliseconds}`
6614
6660
  );
6615
- } else if (milliseconds < -MAX_DATE || milliseconds > MAX_DATE) {
6661
+ } else if (milliseconds < -864e13 || milliseconds > MAX_DATE) {
6616
6662
  // this isn't perfect because we can still end up out of range because of additional shifting, but it's a start
6617
6663
  return DateTime.invalid("Timestamp out of range");
6618
6664
  } else {
@@ -6973,7 +7019,7 @@
6973
7019
 
6974
7020
  static resetCache() {
6975
7021
  zoneOffsetTs = undefined;
6976
- zoneOffsetGuessCache = {};
7022
+ zoneOffsetGuessCache.clear();
6977
7023
  }
6978
7024
 
6979
7025
  // INFO
@@ -7742,7 +7788,7 @@
7742
7788
  * @example DateTime.now().toISO() //=> '2017-04-22T20:47:05.335-04:00'
7743
7789
  * @example DateTime.now().toISO({ includeOffset: false }) //=> '2017-04-22T20:47:05.335'
7744
7790
  * @example DateTime.now().toISO({ format: 'basic' }) //=> '20170422T204705.335-0400'
7745
- * @return {string}
7791
+ * @return {string|null}
7746
7792
  */
7747
7793
  toISO({
7748
7794
  format = "extended",
@@ -7769,7 +7815,7 @@
7769
7815
  * @param {string} [opts.format='extended'] - choose between the basic and extended format
7770
7816
  * @example DateTime.utc(1982, 5, 25).toISODate() //=> '1982-05-25'
7771
7817
  * @example DateTime.utc(1982, 5, 25).toISODate({ format: 'basic' }) //=> '19820525'
7772
- * @return {string}
7818
+ * @return {string|null}
7773
7819
  */
7774
7820
  toISODate({ format = "extended" } = {}) {
7775
7821
  if (!this.isValid) {
@@ -7854,7 +7900,7 @@
7854
7900
  /**
7855
7901
  * Returns a string representation of this DateTime appropriate for use in SQL Date
7856
7902
  * @example DateTime.utc(2014, 7, 13).toSQLDate() //=> '2014-07-13'
7857
- * @return {string}
7903
+ * @return {string|null}
7858
7904
  */
7859
7905
  toSQLDate() {
7860
7906
  if (!this.isValid) {
@@ -7949,7 +7995,7 @@
7949
7995
  }
7950
7996
 
7951
7997
  /**
7952
- * Returns the epoch seconds of this DateTime.
7998
+ * Returns the epoch seconds (including milliseconds in the fractional part) of this DateTime.
7953
7999
  * @return {number}
7954
8000
  */
7955
8001
  toSeconds() {
@@ -8056,7 +8102,7 @@
8056
8102
  /**
8057
8103
  * Return an Interval spanning between this DateTime and another DateTime
8058
8104
  * @param {DateTime} otherDateTime - the other end point of the Interval
8059
- * @return {Interval}
8105
+ * @return {Interval|DateTime}
8060
8106
  */
8061
8107
  until(otherDateTime) {
8062
8108
  return this.isValid ? Interval.fromDateTimes(this, otherDateTime) : this;
@@ -8649,7 +8695,6 @@
8649
8695
  return str;
8650
8696
  }
8651
8697
  const matches = str.match(
8652
- // eslint-disable-next-line
8653
8698
  /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
8654
8699
  );
8655
8700
  if (!matches) {
@@ -9018,75 +9063,42 @@
9018
9063
  })(RpcMethod || {});
9019
9064
 
9020
9065
  class Result {
9021
- _errorCollection;
9066
+ _errors;
9022
9067
  _data;
9023
- constructor() {
9024
- this._errorCollection = /* @__PURE__ */ new Set();
9025
- this._data = null;
9068
+ constructor(data) {
9069
+ this._errors = /* @__PURE__ */ new Map();
9070
+ this._data = data ?? null;
9026
9071
  }
9027
- /**
9028
- * Getter for the `isSuccess` property.
9029
- * Checks if the `_errorCollection` is empty to determine success.
9030
- *
9031
- * @returns Whether the operation resulted in success (no errors).
9032
- */
9033
9072
  get isSuccess() {
9034
- return this._errorCollection.size === 0;
9073
+ return this._errors.size === 0;
9074
+ }
9075
+ get errors() {
9076
+ return this._errors;
9035
9077
  }
9036
- /**
9037
- * Sets the data associated with the result.
9038
- *
9039
- * @param data The data to be stored in the result.
9040
- * @returns The current Result object for chaining methods.
9041
- */
9042
9078
  setData(data) {
9043
9079
  this._data = data;
9044
9080
  return this;
9045
9081
  }
9046
- /**
9047
- * Retrieves the data associated with the result.
9048
- *
9049
- * @returns The data stored in the result, if any.
9050
- */
9051
9082
  getData() {
9052
9083
  return this._data;
9053
9084
  }
9054
- /**
9055
- * Adds an error message or Error object to the result.
9056
- *
9057
- * @param error The error message or Error object to be added.
9058
- * @returns The current Result object for chaining methods.
9059
- */
9060
- addError(error) {
9061
- if (error instanceof Error) {
9062
- this._errorCollection.add(error);
9063
- } else {
9064
- this._errorCollection.add(new Error(error.toString()));
9065
- }
9085
+ addError(error, key) {
9086
+ const errorKey = key ?? Text.getUuidRfc4122();
9087
+ const errorObj = typeof error === "string" ? new Error(error) : error;
9088
+ this._errors.set(errorKey, errorObj);
9066
9089
  return this;
9067
9090
  }
9068
- /**
9069
- * Adds multiple errors to the result in a single call.
9070
- *
9071
- * @param errors An array of errors or strings that will be converted to errors.
9072
- * @returns The current Result object for chaining methods.
9073
- */
9074
9091
  addErrors(errors) {
9075
9092
  for (const error of errors) {
9076
- if (error instanceof Error) {
9077
- this._errorCollection.add(error);
9078
- } else {
9079
- this._errorCollection.add(new Error(error.toString()));
9080
- }
9093
+ this.addError(error);
9081
9094
  }
9082
9095
  return this;
9083
9096
  }
9084
- /**
9085
- * Retrieves an iterator for the errors collected in the result.
9086
- * @returns An iterator over the stored Error objects.
9087
- */
9088
9097
  getErrors() {
9089
- return this._errorCollection.values();
9098
+ return this._errors.values();
9099
+ }
9100
+ hasError(key) {
9101
+ return this._errors.has(key);
9090
9102
  }
9091
9103
  /**
9092
9104
  * Retrieves an array of error messages from the collected errors.
@@ -9095,7 +9107,7 @@
9095
9107
  * contains the message of a corresponding error object.
9096
9108
  */
9097
9109
  getErrorMessages() {
9098
- return [...this.getErrors()].map((error) => error.message);
9110
+ return Array.from(this._errors.values(), (e) => e.message);
9099
9111
  }
9100
9112
  /**
9101
9113
  * Converts the Result object to a string.
@@ -9103,36 +9115,168 @@
9103
9115
  * @returns {string} Returns a string representation of the result operation
9104
9116
  */
9105
9117
  toString() {
9106
- if (this.isSuccess) {
9107
- return `Result (success): data: ${JSON.stringify(this._data)}`;
9118
+ const status = this.isSuccess ? "success" : "failure";
9119
+ const data = this.safeStringify(this._data);
9120
+ return this.isSuccess ? `Result(${status}): ${data}` : `Result(${status}): ${data}
9121
+ Errors: ${this.getErrorMessages().join(", ")}`;
9122
+ }
9123
+ safeStringify(data) {
9124
+ try {
9125
+ return JSON.stringify(data, this.replacer, 2);
9126
+ } catch {
9127
+ return "[Unable to serialize data]";
9108
9128
  }
9109
- return `Result (failure): errors: ${this.getErrorMessages().join(", ")}`;
9129
+ }
9130
+ replacer(_, value) {
9131
+ if (value instanceof Error) {
9132
+ return {
9133
+ name: value.name,
9134
+ message: value.message,
9135
+ stack: value.stack
9136
+ };
9137
+ }
9138
+ return value;
9139
+ }
9140
+ // Static constructors
9141
+ static ok(data) {
9142
+ return new Result(data);
9143
+ }
9144
+ static fail(error, key) {
9145
+ return new Result().addError(error, key);
9110
9146
  }
9111
9147
  }
9112
9148
 
9113
9149
  class AjaxError extends Error {
9114
- cause;
9150
+ code;
9115
9151
  _status;
9116
- _answerError;
9117
- constructor(params) {
9118
- const message = `${params.answerError.error}${params.answerError.errorDescription ? ": " + params.answerError.errorDescription : ""}`;
9152
+ requestInfo;
9153
+ timestamp;
9154
+ originalError;
9155
+ // override cause: null | Error
9156
+ // private _status: number
9157
+ // private _answerError: AnswerError
9158
+ constructor(details) {
9159
+ const message = AjaxError.formatErrorMessage(details);
9119
9160
  super(message);
9120
- this.cause = params.cause || null;
9121
- this.name = this.constructor.name;
9122
- this._status = params.status;
9123
- this._answerError = params.answerError;
9124
- }
9161
+ this.name = "AjaxError";
9162
+ this.code = details.code;
9163
+ this._status = details.status;
9164
+ this.requestInfo = details.requestInfo;
9165
+ this.originalError = details.originalError;
9166
+ this.timestamp = /* @__PURE__ */ new Date();
9167
+ this.cleanErrorStack();
9168
+ }
9169
+ // constructor(params: AjaxErrorParams) {
9170
+ // const message = `${ params.answerError.error }${
9171
+ // params.answerError.errorDescription
9172
+ // ? ': ' + params.answerError.errorDescription
9173
+ // : ''
9174
+ // }`
9175
+ //
9176
+ // super(message)
9177
+ // this.cause = params.cause || null
9178
+ // this.name = this.constructor.name
9179
+ //
9180
+ // this._status = params.status
9181
+ // this._answerError = params.answerError
9182
+ // }
9183
+ /**
9184
+ * @deprecated
9185
+ */
9125
9186
  get answerError() {
9126
- return this._answerError;
9187
+ return {
9188
+ error: this.message,
9189
+ errorDescription: ""
9190
+ };
9127
9191
  }
9128
9192
  get status() {
9129
9193
  return this._status;
9130
9194
  }
9195
+ /**
9196
+ * @deprecated
9197
+ */
9131
9198
  set status(status) {
9132
9199
  this._status = status;
9133
9200
  }
9201
+ /**
9202
+ * Creates AjaxError from HTTP response
9203
+ */
9204
+ static fromResponse(response) {
9205
+ return new AjaxError({
9206
+ code: response.data?.error || "unknown_error",
9207
+ description: response.data?.error_description,
9208
+ status: response.status,
9209
+ requestInfo: {
9210
+ method: response.config?.method?.toUpperCase(),
9211
+ url: response.config?.url,
9212
+ params: response.config?.params
9213
+ }
9214
+ });
9215
+ }
9216
+ /**
9217
+ * Creates AjaxError from exception
9218
+ */
9219
+ static fromException(error, context) {
9220
+ if (error instanceof AjaxError) return error;
9221
+ return new AjaxError({
9222
+ code: context?.code || "internal_error",
9223
+ status: context?.status || 500,
9224
+ description: error instanceof Error ? error.message : String(error),
9225
+ requestInfo: context?.requestInfo,
9226
+ originalError: error
9227
+ });
9228
+ }
9229
+ /**
9230
+ * Serializes error for logging and debugging
9231
+ */
9232
+ toJSON() {
9233
+ return {
9234
+ name: this.name,
9235
+ code: this.code,
9236
+ message: this.message,
9237
+ status: this._status,
9238
+ timestamp: this.timestamp.toISOString(),
9239
+ requestInfo: this.requestInfo,
9240
+ stack: this.stack
9241
+ };
9242
+ }
9243
+ // override toString(): string {
9244
+ // return `${ this.answerError.error }${
9245
+ // this.answerError.errorDescription
9246
+ // ? ': ' + this.answerError.errorDescription
9247
+ // : ''
9248
+ // } (${ this.status })`
9249
+ // }
9250
+ /**
9251
+ * Formats error information for human-readable output
9252
+ */
9134
9253
  toString() {
9135
- return `${this.answerError.error}${this.answerError.errorDescription ? ": " + this.answerError.errorDescription : ""} (${this.status})`;
9254
+ let output = `[${this.name}] ${this.code} (${this._status}): ${this.message}`;
9255
+ if (this.requestInfo) {
9256
+ output += `
9257
+ Request: ${this.requestInfo.method} ${this.requestInfo.url}`;
9258
+ }
9259
+ if (this.stack) {
9260
+ output += `
9261
+ Stack trace:
9262
+ ${this.stack}`;
9263
+ }
9264
+ return output;
9265
+ }
9266
+ static formatErrorMessage(details) {
9267
+ const parts = [details.code];
9268
+ if (details.description) {
9269
+ parts.push(`- ${details.description}`);
9270
+ }
9271
+ if (details.requestInfo?.method && details.requestInfo.url) {
9272
+ parts.push(`(on ${details.requestInfo.method} ${details.requestInfo.url})`);
9273
+ }
9274
+ return parts.join(" ");
9275
+ }
9276
+ cleanErrorStack() {
9277
+ if (typeof this.stack === "string") {
9278
+ this.stack = this.stack.split("\n").filter((line) => !line.includes("AjaxError.constructor")).join("\n");
9279
+ }
9136
9280
  }
9137
9281
  }
9138
9282
 
@@ -9140,31 +9284,48 @@
9140
9284
  _status;
9141
9285
  _query;
9142
9286
  _data;
9143
- constructor(answer, query, status) {
9287
+ constructor(options) {
9144
9288
  super();
9145
- this._data = answer;
9146
- this._query = structuredClone(query);
9147
- this._status = status;
9148
- if (typeof this._data.error !== "undefined") {
9149
- const error = typeof this._data.error === "string" ? this._data : this._data.error;
9150
- this.addError(
9151
- new AjaxError({
9152
- status: this._status,
9153
- answerError: {
9154
- error: error.error || "",
9155
- errorDescription: error.error_description || ""
9156
- }
9157
- })
9158
- );
9159
- }
9160
- }
9161
- // @ts-ignore
9162
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
9163
- setData(data) {
9164
- throw new Error("AjaxResult not support setData()");
9289
+ this._data = Object.freeze(options.answer);
9290
+ this._query = Object.freeze(structuredClone(options.query));
9291
+ this._status = options.status;
9292
+ this.#processErrors();
9293
+ }
9294
+ #processErrors() {
9295
+ const { error } = this._data;
9296
+ if (!error) return;
9297
+ const errorParams = this.#normalizeError(error);
9298
+ this.addError(this.#createAjaxError(errorParams), "base-error");
9299
+ }
9300
+ #normalizeError(error) {
9301
+ return typeof error === "string" ? { code: error, description: this._data.error_description || "" } : { code: error.error, description: error.error_description || "" };
9302
+ }
9303
+ #createAjaxError(params) {
9304
+ return new AjaxError({
9305
+ code: String(this._status),
9306
+ description: params.description,
9307
+ status: this._status,
9308
+ requestInfo: {
9309
+ method: this._query.method,
9310
+ // url: '?',
9311
+ params: this._query.params
9312
+ }
9313
+ // request:
9314
+ });
9165
9315
  }
9166
9316
  getData() {
9167
- return this._data;
9317
+ return Object.freeze({
9318
+ result: this._data.result,
9319
+ next: this._data.next,
9320
+ total: this._data.total,
9321
+ time: this._data.time
9322
+ });
9323
+ }
9324
+ /**
9325
+ * Alias for isMore
9326
+ */
9327
+ hasMore() {
9328
+ return this.isMore();
9168
9329
  }
9169
9330
  isMore() {
9170
9331
  return Type.isNumber(this._data?.next);
@@ -9178,16 +9339,35 @@
9178
9339
  getQuery() {
9179
9340
  return this._query;
9180
9341
  }
9181
- async getNext(http) {
9182
- if (this.isMore() && this.isSuccess) {
9183
- this._query.start = Number.parseInt(this._data?.next);
9184
- return http.call(
9185
- this._query.method,
9186
- this._query.params,
9187
- this._query.start
9188
- );
9342
+ /**
9343
+ * Alias for getNext
9344
+ * @param http
9345
+ */
9346
+ async fetchNext(http) {
9347
+ const data = await this.getNext(http);
9348
+ if (data === false) {
9349
+ return null;
9189
9350
  }
9190
- return Promise.resolve(false);
9351
+ return data;
9352
+ }
9353
+ async getNext(http) {
9354
+ if (!this.isMore() || !this.isSuccess) return false;
9355
+ const nextPageQuery = this.#buildNextPageQuery();
9356
+ return http.call(
9357
+ nextPageQuery.method,
9358
+ nextPageQuery.params,
9359
+ nextPageQuery.start
9360
+ );
9361
+ }
9362
+ #buildNextPageQuery() {
9363
+ return {
9364
+ ...this._query,
9365
+ start: Text.toInteger(this._data.next)
9366
+ };
9367
+ }
9368
+ // Immutable API
9369
+ setData() {
9370
+ throw new ReferenceError("AjaxResult does not allow data modification");
9191
9371
  }
9192
9372
  }
9193
9373
 
@@ -9842,7 +10022,7 @@
9842
10022
  *
9843
10023
  * @returns {boolean} True if value is a RegExp object, otherwise false
9844
10024
  */
9845
- const isRegExp$1 = kindOfTest('RegExp');
10025
+ const isRegExp = kindOfTest('RegExp');
9846
10026
 
9847
10027
  const reduceDescriptors = (obj, reducer) => {
9848
10028
  const descriptors = Object.getOwnPropertyDescriptors(obj);
@@ -9909,26 +10089,6 @@
9909
10089
  return value != null && Number.isFinite(value = +value) ? value : defaultValue;
9910
10090
  };
9911
10091
 
9912
- const ALPHA = 'abcdefghijklmnopqrstuvwxyz';
9913
-
9914
- const DIGIT = '0123456789';
9915
-
9916
- const ALPHABET = {
9917
- DIGIT,
9918
- ALPHA,
9919
- ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT
9920
- };
9921
-
9922
- const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {
9923
- let str = '';
9924
- const {length} = alphabet;
9925
- while (size--) {
9926
- str += alphabet[Math.random() * length|0];
9927
- }
9928
-
9929
- return str;
9930
- };
9931
-
9932
10092
  /**
9933
10093
  * If the thing is a FormData object, return true, otherwise return false.
9934
10094
  *
@@ -10025,7 +10185,7 @@
10025
10185
  isDate,
10026
10186
  isFile,
10027
10187
  isBlob,
10028
- isRegExp: isRegExp$1,
10188
+ isRegExp,
10029
10189
  isFunction,
10030
10190
  isStream,
10031
10191
  isURLSearchParams,
@@ -10056,8 +10216,6 @@
10056
10216
  findKey,
10057
10217
  global: _global,
10058
10218
  isContextDefined,
10059
- ALPHABET,
10060
- generateString,
10061
10219
  isSpecCompliantForm,
10062
10220
  toJSONObject,
10063
10221
  isAsyncFn,
@@ -10454,7 +10612,7 @@
10454
10612
  *
10455
10613
  * @param {string} url The base of the url (e.g., http://www.google.com)
10456
10614
  * @param {object} [params] The params to be appended
10457
- * @param {?object} options
10615
+ * @param {?(object|Function)} options
10458
10616
  *
10459
10617
  * @returns {string} The formatted url
10460
10618
  */
@@ -10466,6 +10624,12 @@
10466
10624
 
10467
10625
  const _encode = options && options.encode || encode$1;
10468
10626
 
10627
+ if (utils$1.isFunction(options)) {
10628
+ options = {
10629
+ serialize: options
10630
+ };
10631
+ }
10632
+
10469
10633
  const serializeFn = options && options.serialize;
10470
10634
 
10471
10635
  let serializedParams;
@@ -10761,7 +10925,7 @@
10761
10925
  }
10762
10926
  }
10763
10927
 
10764
- return (0, JSON.stringify)(rawValue);
10928
+ return (encoder || JSON.stringify)(rawValue);
10765
10929
  }
10766
10930
 
10767
10931
  const defaults$2 = {
@@ -11448,68 +11612,18 @@
11448
11612
 
11449
11613
  const asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args));
11450
11614
 
11451
- const isURLSameOrigin = platform.hasStandardBrowserEnv ?
11615
+ const isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {
11616
+ url = new URL(url, platform.origin);
11452
11617
 
11453
- // Standard browser envs have full support of the APIs needed to test
11454
- // whether the request URL is of the same origin as current location.
11455
- (function standardBrowserEnv() {
11456
- const msie = platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent);
11457
- const urlParsingNode = document.createElement('a');
11458
- let originURL;
11459
-
11460
- /**
11461
- * Parse a URL to discover its components
11462
- *
11463
- * @param {String} url The URL to be parsed
11464
- * @returns {Object}
11465
- */
11466
- function resolveURL(url) {
11467
- let href = url;
11468
-
11469
- if (msie) {
11470
- // IE needs attribute set twice to normalize properties
11471
- urlParsingNode.setAttribute('href', href);
11472
- href = urlParsingNode.href;
11473
- }
11474
-
11475
- urlParsingNode.setAttribute('href', href);
11476
-
11477
- // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
11478
- return {
11479
- href: urlParsingNode.href,
11480
- protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
11481
- host: urlParsingNode.host,
11482
- search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
11483
- hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
11484
- hostname: urlParsingNode.hostname,
11485
- port: urlParsingNode.port,
11486
- pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
11487
- urlParsingNode.pathname :
11488
- '/' + urlParsingNode.pathname
11489
- };
11490
- }
11491
-
11492
- originURL = resolveURL(window.location.href);
11493
-
11494
- /**
11495
- * Determine if a URL shares the same origin as the current location
11496
- *
11497
- * @param {String} requestURL The URL to test
11498
- * @returns {boolean} True if URL shares the same origin, otherwise false
11499
- */
11500
- return function isURLSameOrigin(requestURL) {
11501
- const parsed = (utils$1.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
11502
- return (parsed.protocol === originURL.protocol &&
11503
- parsed.host === originURL.host);
11504
- };
11505
- })() :
11506
-
11507
- // Non standard browser envs (web workers, react-native) lack needed support.
11508
- (function nonStandardBrowserEnv() {
11509
- return function isURLSameOrigin() {
11510
- return true;
11511
- };
11512
- })();
11618
+ return (
11619
+ origin.protocol === url.protocol &&
11620
+ origin.host === url.host &&
11621
+ (isMSIE || origin.port === url.port)
11622
+ );
11623
+ })(
11624
+ new URL(platform.origin),
11625
+ platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)
11626
+ ) : () => true;
11513
11627
 
11514
11628
  const cookies = platform.hasStandardBrowserEnv ?
11515
11629
 
@@ -11588,8 +11702,9 @@
11588
11702
  *
11589
11703
  * @returns {string} The combined full path
11590
11704
  */
11591
- function buildFullPath(baseURL, requestedURL) {
11592
- if (baseURL && !isAbsoluteURL(requestedURL)) {
11705
+ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
11706
+ let isRelativeUrl = !isAbsoluteURL(requestedURL);
11707
+ if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {
11593
11708
  return combineURLs(baseURL, requestedURL);
11594
11709
  }
11595
11710
  return requestedURL;
@@ -11611,7 +11726,7 @@
11611
11726
  config2 = config2 || {};
11612
11727
  const config = {};
11613
11728
 
11614
- function getMergedValue(target, source, caseless) {
11729
+ function getMergedValue(target, source, prop, caseless) {
11615
11730
  if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) {
11616
11731
  return utils$1.merge.call({caseless}, target, source);
11617
11732
  } else if (utils$1.isPlainObject(source)) {
@@ -11623,11 +11738,11 @@
11623
11738
  }
11624
11739
 
11625
11740
  // eslint-disable-next-line consistent-return
11626
- function mergeDeepProperties(a, b, caseless) {
11741
+ function mergeDeepProperties(a, b, prop , caseless) {
11627
11742
  if (!utils$1.isUndefined(b)) {
11628
- return getMergedValue(a, b, caseless);
11743
+ return getMergedValue(a, b, prop , caseless);
11629
11744
  } else if (!utils$1.isUndefined(a)) {
11630
- return getMergedValue(undefined, a, caseless);
11745
+ return getMergedValue(undefined, a, prop , caseless);
11631
11746
  }
11632
11747
  }
11633
11748
 
@@ -11685,7 +11800,7 @@
11685
11800
  socketPath: defaultToConfig2,
11686
11801
  responseEncoding: defaultToConfig2,
11687
11802
  validateStatus: mergeDirectKeys,
11688
- headers: (a, b) => mergeDeepProperties(headersToObject(a), headersToObject(b), true)
11803
+ headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
11689
11804
  };
11690
11805
 
11691
11806
  utils$1.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {
@@ -11704,7 +11819,7 @@
11704
11819
 
11705
11820
  newConfig.headers = headers = AxiosHeaders$1.from(headers);
11706
11821
 
11707
- newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url), config.params, config.paramsSerializer);
11822
+ newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);
11708
11823
 
11709
11824
  // HTTP basic authentication
11710
11825
  if (auth) {
@@ -12427,7 +12542,7 @@
12427
12542
  });
12428
12543
  }
12429
12544
 
12430
- const VERSION$1 = "1.7.7";
12545
+ const VERSION$1 = "1.8.4";
12431
12546
 
12432
12547
  const validators$1 = {};
12433
12548
 
@@ -12478,6 +12593,14 @@
12478
12593
  };
12479
12594
  };
12480
12595
 
12596
+ validators$1.spelling = function spelling(correctSpelling) {
12597
+ return (value, opt) => {
12598
+ // eslint-disable-next-line no-console
12599
+ console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);
12600
+ return true;
12601
+ }
12602
+ };
12603
+
12481
12604
  /**
12482
12605
  * Assert object's properties type
12483
12606
  *
@@ -12547,9 +12670,9 @@
12547
12670
  return await this._request(configOrUrl, config);
12548
12671
  } catch (err) {
12549
12672
  if (err instanceof Error) {
12550
- let dummy;
12673
+ let dummy = {};
12551
12674
 
12552
- Error.captureStackTrace ? Error.captureStackTrace(dummy = {}) : (dummy = new Error());
12675
+ Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());
12553
12676
 
12554
12677
  // slice off the Error: ... line
12555
12678
  const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : '';
@@ -12604,6 +12727,18 @@
12604
12727
  }
12605
12728
  }
12606
12729
 
12730
+ // Set config.allowAbsoluteUrls
12731
+ if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) {
12732
+ config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;
12733
+ } else {
12734
+ config.allowAbsoluteUrls = true;
12735
+ }
12736
+
12737
+ validator.assertOptions(config, {
12738
+ baseUrl: validators.spelling('baseURL'),
12739
+ withXsrfToken: validators.spelling('withXSRFToken')
12740
+ }, true);
12741
+
12607
12742
  // Set config.method
12608
12743
  config.method = (config.method || this.defaults.method || 'get').toLowerCase();
12609
12744
 
@@ -12694,7 +12829,7 @@
12694
12829
 
12695
12830
  getUri(config) {
12696
12831
  config = mergeConfig$1(this.defaults, config);
12697
- const fullPath = buildFullPath(config.baseURL, config.url);
12832
+ const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
12698
12833
  return buildURL(fullPath, config.params, config.paramsSerializer);
12699
12834
  }
12700
12835
  };
@@ -13079,7 +13214,7 @@
13079
13214
 
13080
13215
  const formats = Format.RFC3986;
13081
13216
 
13082
- const has$2 = Object.prototype.hasOwnProperty;
13217
+ const has$1 = Object.prototype.hasOwnProperty;
13083
13218
  const isArray$2 = Array.isArray;
13084
13219
 
13085
13220
  const hexTable = (function () {
@@ -13133,7 +13268,7 @@
13133
13268
  } else if (target && typeof target === 'object') {
13134
13269
  if (
13135
13270
  (options && (options.plainObjects || options.allowPrototypes)) ||
13136
- !has$2.call(Object.prototype, source)
13271
+ !has$1.call(Object.prototype, source)
13137
13272
  ) {
13138
13273
  target[source] = true;
13139
13274
  }
@@ -13155,7 +13290,7 @@
13155
13290
 
13156
13291
  if (isArray$2(target) && isArray$2(source)) {
13157
13292
  source.forEach(function (item, i) {
13158
- if (has$2.call(target, i)) {
13293
+ if (has$1.call(target, i)) {
13159
13294
  const targetItem = target[i];
13160
13295
  if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
13161
13296
  target[i] = merge(targetItem, item, options);
@@ -13172,7 +13307,7 @@
13172
13307
  return Object.keys(source).reduce(function (acc, key) {
13173
13308
  const value = source[key];
13174
13309
 
13175
- if (has$2.call(acc, key)) {
13310
+ if (has$1.call(acc, key)) {
13176
13311
  acc[key] = merge(acc[key], value, options);
13177
13312
  } else {
13178
13313
  acc[key] = value;
@@ -13296,10 +13431,6 @@
13296
13431
  return value
13297
13432
  };
13298
13433
 
13299
- const isRegExp = function isRegExp(obj) {
13300
- return Object.prototype.toString.call(obj) === '[object RegExp]'
13301
- };
13302
-
13303
13434
  const isBuffer = function isBuffer(obj) {
13304
13435
  if (!obj || typeof obj !== 'object') {
13305
13436
  return false
@@ -13323,8 +13454,6 @@
13323
13454
  return fn(val)
13324
13455
  };
13325
13456
 
13326
- const has$1 = Object.prototype.hasOwnProperty;
13327
-
13328
13457
  const arrayPrefixGenerators = {
13329
13458
  brackets: function brackets(prefix) {
13330
13459
  return prefix + '[]'
@@ -13407,7 +13536,7 @@
13407
13536
  let tmpSc = sideChannel;
13408
13537
  let step = 0;
13409
13538
  let findFlag = false;
13410
- while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
13539
+ while ((tmpSc = tmpSc.get(sentinel)) !== void 0 && !findFlag) {
13411
13540
  // Where object last appeared in the ref tree
13412
13541
  const pos = tmpSc.get(object);
13413
13542
  step += 1;
@@ -13472,7 +13601,7 @@
13472
13601
  if (encodeValuesOnly && encoder) {
13473
13602
  obj = maybeMap(obj, encoder);
13474
13603
  }
13475
- objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
13604
+ objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void 0 }];
13476
13605
  } else if (isArray$1(filter)) {
13477
13606
  objKeys = filter;
13478
13607
  } else {
@@ -13536,108 +13665,14 @@
13536
13665
  };
13537
13666
 
13538
13667
  const normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
13539
- if (!opts) {
13668
+ {
13540
13669
  return defaults$1
13541
13670
  }
13542
-
13543
- if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
13544
- throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided')
13545
- }
13546
-
13547
- if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') {
13548
- throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided')
13549
- }
13550
-
13551
- if (
13552
- opts.encoder !== null &&
13553
- typeof opts.encoder !== 'undefined' &&
13554
- typeof opts.encoder !== 'function'
13555
- ) {
13556
- throw new TypeError('Encoder has to be a function.')
13557
- }
13558
-
13559
- const charset = opts.charset || defaults$1.charset;
13560
- if (
13561
- typeof opts.charset !== 'undefined' &&
13562
- opts.charset !== 'utf-8' &&
13563
- opts.charset !== 'iso-8859-1'
13564
- ) {
13565
- throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined')
13566
- }
13567
-
13568
- let format = formats;
13569
- if (typeof opts.format !== 'undefined') {
13570
- if (!has$1.call(formatters, opts.format)) {
13571
- throw new TypeError('Unknown format option provided.')
13572
- }
13573
- format = opts.format;
13574
- }
13575
- const formatter = formatters[format];
13576
-
13577
- let filter = defaults$1.filter;
13578
- if (typeof opts.filter === 'function' || isArray$1(opts.filter)) {
13579
- filter = opts.filter;
13580
- }
13581
-
13582
- let arrayFormat;
13583
- if (opts.arrayFormat in arrayPrefixGenerators) {
13584
- arrayFormat = opts.arrayFormat;
13585
- } else if ('indices' in opts) {
13586
- arrayFormat = opts.indices ? 'indices' : 'repeat';
13587
- } else {
13588
- arrayFormat = defaults$1.arrayFormat;
13589
- }
13590
-
13591
- if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {
13592
- throw new TypeError('`commaRoundTrip` must be a boolean, or absent')
13593
- }
13594
-
13595
- const allowDots =
13596
- typeof opts.allowDots === 'undefined'
13597
- ? opts.encodeDotInKeys === true
13598
- ? true
13599
- : defaults$1.allowDots
13600
- : !!opts.allowDots;
13601
-
13602
- return {
13603
- addQueryPrefix:
13604
- typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults$1.addQueryPrefix,
13605
- allowDots: allowDots,
13606
- allowEmptyArrays:
13607
- typeof opts.allowEmptyArrays === 'boolean'
13608
- ? !!opts.allowEmptyArrays
13609
- : defaults$1.allowEmptyArrays,
13610
- arrayFormat: arrayFormat,
13611
- charset: charset,
13612
- charsetSentinel:
13613
- typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults$1.charsetSentinel,
13614
- commaRoundTrip: opts.commaRoundTrip,
13615
- delimiter: typeof opts.delimiter === 'undefined' ? defaults$1.delimiter : opts.delimiter,
13616
- encode: typeof opts.encode === 'boolean' ? opts.encode : defaults$1.encode,
13617
- encodeDotInKeys:
13618
- typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults$1.encodeDotInKeys,
13619
- encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults$1.encoder,
13620
- encodeValuesOnly:
13621
- typeof opts.encodeValuesOnly === 'boolean'
13622
- ? opts.encodeValuesOnly
13623
- : defaults$1.encodeValuesOnly,
13624
- filter: filter,
13625
- format: format,
13626
- formatter: formatter,
13627
- serializeDate:
13628
- typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults$1.serializeDate,
13629
- skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults$1.skipNulls,
13630
- sort: typeof opts.sort === 'function' ? opts.sort : null,
13631
- strictNullHandling:
13632
- typeof opts.strictNullHandling === 'boolean'
13633
- ? opts.strictNullHandling
13634
- : defaults$1.strictNullHandling,
13635
- }
13636
13671
  };
13637
13672
 
13638
13673
  function stringify(object, opts) {
13639
13674
  let obj = object;
13640
- const options = normalizeStringifyOptions(opts);
13675
+ const options = normalizeStringifyOptions();
13641
13676
 
13642
13677
  let objKeys;
13643
13678
  let filter;
@@ -13920,91 +13955,13 @@
13920
13955
  };
13921
13956
 
13922
13957
  const normalizeParseOptions = function normalizeParseOptions(opts) {
13923
- if (!opts) {
13958
+ {
13924
13959
  return defaults
13925
13960
  }
13926
-
13927
- if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
13928
- throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided')
13929
- }
13930
-
13931
- if (typeof opts.decodeDotInKeys !== 'undefined' && typeof opts.decodeDotInKeys !== 'boolean') {
13932
- throw new TypeError('`decodeDotInKeys` option can only be `true` or `false`, when provided')
13933
- }
13934
-
13935
- if (
13936
- opts.decoder !== null &&
13937
- typeof opts.decoder !== 'undefined' &&
13938
- typeof opts.decoder !== 'function'
13939
- ) {
13940
- throw new TypeError('Decoder has to be a function.')
13941
- }
13942
-
13943
- if (
13944
- typeof opts.charset !== 'undefined' &&
13945
- opts.charset !== 'utf-8' &&
13946
- opts.charset !== 'iso-8859-1'
13947
- ) {
13948
- throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined')
13949
- }
13950
- const charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
13951
-
13952
- const duplicates = typeof opts.duplicates === 'undefined' ? defaults.duplicates : opts.duplicates;
13953
-
13954
- if (duplicates !== 'combine' && duplicates !== 'first' && duplicates !== 'last') {
13955
- throw new TypeError('The duplicates option must be either combine, first, or last')
13956
- }
13957
-
13958
- const allowDots =
13959
- typeof opts.allowDots === 'undefined'
13960
- ? opts.decodeDotInKeys === true
13961
- ? true
13962
- : defaults.allowDots
13963
- : !!opts.allowDots;
13964
-
13965
- return {
13966
- allowDots: allowDots,
13967
- allowEmptyArrays:
13968
- typeof opts.allowEmptyArrays === 'boolean'
13969
- ? !!opts.allowEmptyArrays
13970
- : defaults.allowEmptyArrays,
13971
- allowPrototypes:
13972
- typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
13973
- allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
13974
- arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
13975
- charset: charset,
13976
- charsetSentinel:
13977
- typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
13978
- comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
13979
- decodeDotInKeys:
13980
- typeof opts.decodeDotInKeys === 'boolean' ? opts.decodeDotInKeys : defaults.decodeDotInKeys,
13981
- decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
13982
- delimiter:
13983
- typeof opts.delimiter === 'string' || isRegExp(opts.delimiter)
13984
- ? opts.delimiter
13985
- : defaults.delimiter,
13986
- // eslint-disable-next-line no-implicit-coercion, no-extra-parens
13987
- depth: typeof opts.depth === 'number' || opts.depth === false ? +opts.depth : defaults.depth,
13988
- duplicates: duplicates,
13989
- ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
13990
- interpretNumericEntities:
13991
- typeof opts.interpretNumericEntities === 'boolean'
13992
- ? opts.interpretNumericEntities
13993
- : defaults.interpretNumericEntities,
13994
- parameterLimit:
13995
- typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
13996
- parseArrays: opts.parseArrays !== false,
13997
- plainObjects:
13998
- typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
13999
- strictNullHandling:
14000
- typeof opts.strictNullHandling === 'boolean'
14001
- ? opts.strictNullHandling
14002
- : defaults.strictNullHandling,
14003
- }
14004
13961
  };
14005
13962
 
14006
13963
  function parse(str, opts) {
14007
- const options = normalizeParseOptions(opts);
13964
+ const options = normalizeParseOptions();
14008
13965
 
14009
13966
  if (str === '' || str === null || typeof str === 'undefined') {
14010
13967
  return options.plainObjects ? Object.create(null) : {}
@@ -14100,33 +14057,37 @@
14100
14057
  // endregion ////
14101
14058
  // region Actions Call ////
14102
14059
  async batch(calls, isHaltOnError = true) {
14103
- const isArrayMode = Array.isArray(calls);
14104
- const cmd = isArrayMode ? [] : {};
14060
+ if (Array.isArray(calls)) {
14061
+ return this.#batchAsArray(
14062
+ calls,
14063
+ isHaltOnError
14064
+ );
14065
+ }
14066
+ return this.#batchAsObject(
14067
+ calls,
14068
+ isHaltOnError
14069
+ );
14070
+ }
14071
+ async #batchAsObject(calls, isHaltOnError = true) {
14072
+ const cmd = {};
14105
14073
  let cnt = 0;
14106
14074
  const processRow = (row, index) => {
14107
14075
  let method = null;
14108
14076
  let params = null;
14109
- if (Array.isArray(row)) {
14110
- method = row[0];
14111
- params = row[1];
14112
- } else if (row.method) {
14113
- method = row.method;
14114
- params = row.params;
14077
+ if (row.method) {
14078
+ method = row.method ?? null;
14079
+ params = row?.params ?? null;
14080
+ } else if (Array.isArray(row) && row.length > 0) {
14081
+ method = row[0] ?? null;
14082
+ params = row[1] ?? null;
14115
14083
  }
14116
14084
  if (method) {
14117
14085
  cnt++;
14118
- const data = method + "?" + stringify(params);
14119
- if (isArrayMode || Array.isArray(cmd)) {
14120
- cmd.push(data);
14121
- } else {
14122
- cmd[index] = data;
14123
- }
14086
+ cmd[index] = method + "?" + stringify(params);
14124
14087
  }
14125
14088
  };
14126
- if (isArrayMode) {
14127
- for (const [index, item] of calls.entries()) processRow(item, index);
14128
- } else {
14129
- for (const [index, item] of Object.entries(calls)) processRow(item, index);
14089
+ for (const [index, row] of Object.entries(calls)) {
14090
+ processRow(row, index);
14130
14091
  }
14131
14092
  if (cnt < 1) {
14132
14093
  return Promise.resolve(new Result());
@@ -14136,7 +14097,7 @@
14136
14097
  cmd
14137
14098
  }).then((response) => {
14138
14099
  const responseResult = response.getData().result;
14139
- const results = isArrayMode ? [] : {};
14100
+ const results = {};
14140
14101
  const processResponse = (row, index) => {
14141
14102
  if (
14142
14103
  // @ts-ignore
@@ -14144,8 +14105,8 @@
14144
14105
  typeof responseResult.result_error[index] !== "undefined"
14145
14106
  ) {
14146
14107
  const q = row.split("?");
14147
- const data = new AjaxResult(
14148
- {
14108
+ results[index] = new AjaxResult({
14109
+ answer: {
14149
14110
  // @ts-ignore
14150
14111
  result: Type.isUndefined(responseResult.result[index]) ? (
14151
14112
  // @ts-ignore
@@ -14159,67 +14120,154 @@
14159
14120
  // @ts-ignore
14160
14121
  total: responseResult.result_total[index],
14161
14122
  // @ts-ignore
14162
- next: responseResult.result_next[index]
14123
+ next: responseResult.result_next[index],
14124
+ // @todo test this ////
14125
+ // @ts-ignore
14126
+ time: responseResult.result_time[index]
14163
14127
  },
14164
- {
14128
+ query: {
14165
14129
  method: q[0] || "",
14166
14130
  params: parse(q[1] || ""),
14167
14131
  start: 0
14168
14132
  },
14169
- response.getStatus()
14170
- );
14171
- if (isArrayMode || Array.isArray(results)) {
14172
- results.push(data);
14173
- } else {
14174
- results[index] = data;
14175
- }
14133
+ status: response.getStatus()
14134
+ });
14176
14135
  }
14177
14136
  };
14178
- if (Array.isArray(cmd)) {
14179
- for (const [index, item] of cmd.entries()) processResponse(item, index);
14180
- } else {
14181
- for (const [index, item] of Object.entries(cmd))
14182
- processResponse(item, index);
14137
+ for (const [index, row] of Object.entries(cmd)) {
14138
+ processResponse(row, index);
14183
14139
  }
14184
- let dataResult;
14140
+ const dataResult = {};
14185
14141
  const initError = (result2) => {
14142
+ if (result2.hasError("base-error")) {
14143
+ return result2.errors.get("base-error");
14144
+ }
14186
14145
  return new AjaxError({
14146
+ code: "0",
14147
+ description: result2.getErrorMessages().join("; "),
14187
14148
  status: 0,
14188
- answerError: {
14189
- error: result2.getErrorMessages().join("; "),
14190
- errorDescription: `batch ${result2.getQuery().method}: ${stringify(result2.getQuery().params, { encode: false })}`
14149
+ requestInfo: {
14150
+ method: result2.getQuery().method,
14151
+ params: result2.getQuery().params
14191
14152
  },
14192
- cause: result2.getErrors().next().value
14153
+ originalError: result2.getErrors().next().value
14193
14154
  });
14194
14155
  };
14195
14156
  const result = new Result();
14196
- if (isArrayMode || Array.isArray(results)) {
14197
- dataResult = [];
14198
- for (const data of results) {
14199
- if (data.getStatus() !== 200 || !data.isSuccess) {
14200
- const error = initError(data);
14201
- if (!isHaltOnError && !data.isSuccess) {
14202
- result.addError(error);
14203
- continue;
14204
- }
14205
- return Promise.reject(error);
14157
+ for (const key of Object.keys(results)) {
14158
+ const data = results[key];
14159
+ if (data.getStatus() !== 200 || !data.isSuccess) {
14160
+ const error = initError(data);
14161
+ if (!isHaltOnError && !data.isSuccess) {
14162
+ result.addError(error, key);
14163
+ continue;
14206
14164
  }
14207
- dataResult.push(data.getData().result);
14165
+ return Promise.reject(error);
14208
14166
  }
14209
- } else {
14210
- dataResult = {};
14211
- for (const key of Object.keys(results)) {
14212
- const data = results[key];
14213
- if (data.getStatus() !== 200 || !data.isSuccess) {
14214
- const error = initError(data);
14215
- if (!isHaltOnError && !data.isSuccess) {
14216
- result.addError(error);
14217
- continue;
14218
- }
14219
- return Promise.reject(error);
14167
+ dataResult[key] = data.getData().result;
14168
+ }
14169
+ result.setData(dataResult);
14170
+ return Promise.resolve(result);
14171
+ });
14172
+ }
14173
+ async #batchAsArray(calls, isHaltOnError = true) {
14174
+ const cmd = [];
14175
+ let cnt = 0;
14176
+ const processRow = (row) => {
14177
+ let method = null;
14178
+ let params = null;
14179
+ if (row.method) {
14180
+ method = row.method ?? null;
14181
+ params = row?.params ?? null;
14182
+ } else if (Array.isArray(row) && row.length > 0) {
14183
+ method = row[0] ?? null;
14184
+ params = row[1] ?? null;
14185
+ }
14186
+ if (method) {
14187
+ cnt++;
14188
+ const data = method + "?" + stringify(params);
14189
+ cmd.push(data);
14190
+ }
14191
+ };
14192
+ for (const [_, row] of calls.entries()) {
14193
+ processRow(row);
14194
+ }
14195
+ if (cnt < 1) {
14196
+ return Promise.resolve(new Result());
14197
+ }
14198
+ return this.call("batch", {
14199
+ halt: isHaltOnError ? 1 : 0,
14200
+ cmd
14201
+ }).then((response) => {
14202
+ const responseResult = response.getData().result;
14203
+ const results = [];
14204
+ const processResponse = (row, index) => {
14205
+ if (
14206
+ // @ts-ignore
14207
+ typeof responseResult.result[index] !== "undefined" || // @ts-ignore
14208
+ typeof responseResult.result_error[index] !== "undefined"
14209
+ ) {
14210
+ const q = row.split("?");
14211
+ const data = new AjaxResult({
14212
+ answer: {
14213
+ // @ts-ignore
14214
+ result: Type.isUndefined(responseResult.result[index]) ? (
14215
+ // @ts-ignore
14216
+ {}
14217
+ ) : (
14218
+ // @ts-ignore
14219
+ responseResult.result[index]
14220
+ ),
14221
+ // @ts-ignore
14222
+ error: responseResult?.result_error[index] || void 0,
14223
+ // @ts-ignore
14224
+ total: responseResult.result_total[index],
14225
+ // @ts-ignore
14226
+ next: responseResult.result_next[index],
14227
+ // @todo test this ////
14228
+ // @ts-ignore
14229
+ time: responseResult.result_time[index]
14230
+ },
14231
+ query: {
14232
+ method: q[0] || "",
14233
+ params: parse(q[1] || ""),
14234
+ start: 0
14235
+ },
14236
+ status: response.getStatus()
14237
+ });
14238
+ results.push(data);
14239
+ }
14240
+ };
14241
+ for (const [index, row] of cmd.entries()) {
14242
+ processResponse(row, index);
14243
+ }
14244
+ const dataResult = [];
14245
+ const initError = (result2) => {
14246
+ if (result2.hasError("base-error")) {
14247
+ return result2.errors.get("base-error");
14248
+ }
14249
+ return new AjaxError({
14250
+ code: "0",
14251
+ description: result2.getErrorMessages().join("; "),
14252
+ status: 0,
14253
+ requestInfo: {
14254
+ method: result2.getQuery().method,
14255
+ params: result2.getQuery().params
14256
+ },
14257
+ originalError: result2.getErrors().next().value
14258
+ });
14259
+ };
14260
+ const result = new Result();
14261
+ for (const data of results) {
14262
+ if (data.getStatus() !== 200 || !data.isSuccess) {
14263
+ const error = initError(data);
14264
+ if (!isHaltOnError && !data.isSuccess) {
14265
+ result.addError(error);
14266
+ continue;
14220
14267
  }
14221
- dataResult[key] = data.getData().result;
14268
+ return Promise.reject(error);
14222
14269
  }
14270
+ dataResult.push(data.getData().result);
14223
14271
  }
14224
14272
  result.setData(dataResult);
14225
14273
  return Promise.resolve(result);
@@ -14267,9 +14315,14 @@
14267
14315
  };
14268
14316
  }
14269
14317
  const problemError = new AjaxError({
14318
+ code: String(answerError.error),
14319
+ description: answerError.errorDescription,
14270
14320
  status: error_.response?.status || 0,
14271
- answerError,
14272
- cause: error_
14321
+ requestInfo: {
14322
+ method,
14323
+ params
14324
+ },
14325
+ originalError: error_
14273
14326
  });
14274
14327
  if (problemError.status === 401 && ["expired_token", "invalid_token"].includes(
14275
14328
  problemError.answerError.error
@@ -14303,9 +14356,14 @@
14303
14356
  };
14304
14357
  }
14305
14358
  const problemError2 = new AjaxError({
14306
- status: error__.response?.status || 0,
14307
- answerError: answerError2,
14308
- cause: error__
14359
+ code: String(answerError2.error),
14360
+ description: answerError2.errorDescription,
14361
+ status: error_.response?.status || 0,
14362
+ requestInfo: {
14363
+ method,
14364
+ params
14365
+ },
14366
+ originalError: error__
14309
14367
  });
14310
14368
  return Promise.reject(problemError2);
14311
14369
  }
@@ -14314,15 +14372,15 @@
14314
14372
  return Promise.reject(problemError);
14315
14373
  }
14316
14374
  ).then((response) => {
14317
- const result = new AjaxResult(
14318
- response.payload,
14319
- {
14375
+ const result = new AjaxResult({
14376
+ answer: response.payload,
14377
+ query: {
14320
14378
  method,
14321
14379
  params,
14322
14380
  start
14323
14381
  },
14324
- response.status
14325
- );
14382
+ status: response.status
14383
+ });
14326
14384
  return Promise.resolve(result);
14327
14385
  });
14328
14386
  }
@@ -14343,7 +14401,7 @@
14343
14401
  result.logTag = this.#logTag;
14344
14402
  }
14345
14403
  result[this.#requestIdGenerator.getQueryStringParameterName()] = this.#requestIdGenerator.getRequestId();
14346
- result[this.#requestIdGenerator.getQueryStringSdkParameterName()] = "0.1.6";
14404
+ result[this.#requestIdGenerator.getQueryStringSdkParameterName()] = "0.2.0";
14347
14405
  if (!!result.data && !!result.data.start) {
14348
14406
  delete result.data.start;
14349
14407
  }
@@ -15497,6 +15555,8 @@
15497
15555
  MessageCommands2["selectAccess"] = "selectAccess";
15498
15556
  MessageCommands2["selectCRM"] = "selectCRM";
15499
15557
  MessageCommands2["showAppForm"] = "showAppForm";
15558
+ MessageCommands2["getInterface"] = "getInterface";
15559
+ MessageCommands2["placementBindEvent"] = "placementBindEvent";
15500
15560
  return MessageCommands2;
15501
15561
  })(MessageCommands || {});
15502
15562
 
@@ -16302,9 +16362,11 @@
16302
16362
  }
16303
16363
 
16304
16364
  class PlacementManager {
16365
+ #messageManager;
16305
16366
  #title = "";
16306
16367
  #options = {};
16307
- constructor() {
16368
+ constructor(messageManager) {
16369
+ this.#messageManager = messageManager;
16308
16370
  }
16309
16371
  /**
16310
16372
  * Initializes the data received from the parent window message.
@@ -16328,6 +16390,54 @@
16328
16390
  get isSliderMode() {
16329
16391
  return this.options?.IFRAME === "Y";
16330
16392
  }
16393
+ /**
16394
+ * Get Information About the JS Interface of the Current Embedding Location
16395
+ *
16396
+ * @return {Promise<any>}
16397
+ *
16398
+ * @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-get-interface.html
16399
+ */
16400
+ async getInterface() {
16401
+ return this.#messageManager.send(
16402
+ MessageCommands.getInterface,
16403
+ {
16404
+ isSafely: true
16405
+ }
16406
+ );
16407
+ }
16408
+ /**
16409
+ * Set Up the Interface Event Handler
16410
+ * @param {string} eventName
16411
+ * @return {Promise<any>}
16412
+ *
16413
+ * @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-bind-event.html
16414
+ */
16415
+ async bindEvent(eventName) {
16416
+ return this.#messageManager.send(
16417
+ MessageCommands.getInterface,
16418
+ {
16419
+ event: eventName,
16420
+ isSafely: true
16421
+ }
16422
+ );
16423
+ }
16424
+ /**
16425
+ * Call the Registered Interface Command
16426
+ * @param {string} command
16427
+ * @param {Record<string, any>} parameters
16428
+ * @return {Promise<any>}
16429
+ *
16430
+ * @link https://apidocs.bitrix24.com/api-reference/widgets/ui-interaction/bx24-placement-call.html
16431
+ */
16432
+ async call(command, parameters = {}) {
16433
+ return this.#messageManager.send(
16434
+ command,
16435
+ {
16436
+ ...parameters,
16437
+ isSafely: true
16438
+ }
16439
+ );
16440
+ }
16331
16441
  }
16332
16442
 
16333
16443
  class B24Frame extends AbstractB24 {
@@ -16355,7 +16465,7 @@
16355
16465
  this.#appFrame,
16356
16466
  this.#messageManager
16357
16467
  );
16358
- this.#placementManager = new PlacementManager();
16468
+ this.#placementManager = new PlacementManager(this.#messageManager);
16359
16469
  this._isInit = false;
16360
16470
  }
16361
16471
  setLogger(logger) {
@@ -24263,7 +24373,7 @@
24263
24373
  }
24264
24374
  if (message.extra.server_time_unix) {
24265
24375
  message.extra.server_time_ago = (Date.now() - message.extra.server_time_unix * 1e3) / 1e3 - (this._config?.server.timeShift || 0);
24266
- message.extra.server_time_ago = message.extra.server_time_ago > 0 ? message.extra.server_time_ago : 0;
24376
+ message.extra.server_time_ago = Math.max(message.extra.server_time_ago, 0);
24267
24377
  }
24268
24378
  this.logMessage(message);
24269
24379
  try {
@@ -25329,7 +25439,7 @@ Data string: ${pullEvent}
25329
25439
  }
25330
25440
  trimDuplicates() {
25331
25441
  if (this._session.lastMessageIds.length > MAX_IDS_TO_STORE) {
25332
- this._session.lastMessageIds = this._session.lastMessageIds.slice(-MAX_IDS_TO_STORE);
25442
+ this._session.lastMessageIds = this._session.lastMessageIds.slice(-10);
25333
25443
  }
25334
25444
  }
25335
25445
  // endregion ////
@@ -25407,19 +25517,19 @@ Data string: ${pullEvent}
25407
25517
  * @deprecated
25408
25518
  */
25409
25519
  /*/
25410
- getRestClientOptions()
25411
- {
25412
- let result = {};
25520
+ getRestClientOptions()
25521
+ {
25522
+ let result = {};
25413
25523
 
25414
- if (this.guestMode && this.guestUserId !== 0)
25415
- {
25416
- result.queryParams = {
25417
- pull_guest_id: this.guestUserId
25418
- }
25419
- }
25420
- return result;
25421
- }
25422
- //*/
25524
+ if (this.guestMode && this.guestUserId !== 0)
25525
+ {
25526
+ result.queryParams = {
25527
+ pull_guest_id: this.guestUserId
25528
+ }
25529
+ }
25530
+ return result;
25531
+ }
25532
+ //*/
25423
25533
  // endregion ////
25424
25534
  }
25425
25535