intelicoreact 2.0.8 → 2.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/Atomic/FormElements/Dropdown/components/DropdownLoader.d.ts +4 -0
  2. package/dist/Atomic/FormElements/FormattedRawSSN/FormattedRawSSN_old.d.ts +11 -0
  3. package/dist/Atomic/FormElements/NumericInput/NumericInput.d.ts +36 -0
  4. package/dist/Atomic/FormElements/RangeCalendar/RangeCalendar.d.ts +2 -0
  5. package/dist/Atomic/FormElements/RangeSlider/RangeSlider.d.ts +19 -0
  6. package/dist/Atomic/FormElements/SwitcherTagsDropdown/partial/States.d.ts +5 -0
  7. package/dist/Atomic/FormElements/VariantsListRadio/VariantsListRadio.d.ts +17 -0
  8. package/dist/Atomic/FormElements/VariantsListRadio/partials/VariantsListRadioItem.d.ts +12 -0
  9. package/dist/Atomic/FormElements/WidgetPseudoTable/WidgetPseudoTable.d.ts +2 -0
  10. package/dist/Atomic/FormElements/WidgetPseudoTable/partial/constructor.d.ts +23 -0
  11. package/dist/Atomic/FormElements/WidgetWithSwitchableRows/WidgetWithSwitchableRows.d.ts +2 -0
  12. package/dist/Atomic/FormElements/WidgetWithSwitchableRows/partial/constructor.d.ts +38 -0
  13. package/dist/Atomic/UI/AccordionTable/AccordionTable.d.ts +10 -0
  14. package/dist/Atomic/UI/AccordionText/AccordionText.d.ts +8 -0
  15. package/dist/Atomic/UI/Chart/partial/Chart.constants.d.ts +78 -0
  16. package/dist/Atomic/UI/Chart/partial/datasetSetters.d.ts +13 -0
  17. package/dist/Atomic/UI/Chart/partial/optionsConstructor.d.ts +145 -0
  18. package/dist/Atomic/UI/Chart/partial/optionsSetters.d.ts +4 -0
  19. package/dist/Atomic/UI/CircleProgressBar/CircleProgressBar.d.ts +14 -0
  20. package/dist/Atomic/UI/ExampleChartIntegration/ExampleChartIntegration.d.ts +2 -0
  21. package/dist/Atomic/UI/ExampleChartIntegration/partial/utils.d.ts +4 -0
  22. package/dist/Atomic/UI/MonoAccordion/MonoAccordion._test.d.ts +1 -0
  23. package/dist/Atomic/UI/MonoAccordion/MonoAccordion.d.ts +12 -0
  24. package/dist/Atomic/UI/PieChart/PieChart.d.ts +8 -0
  25. package/dist/Atomic/UI/Table/Partials/TdCell.d.ts +13 -0
  26. package/dist/Atomic/UI/Table/Partials/TdHeader.d.ts +5 -0
  27. package/dist/Atomic/UI/Table/Partials/TdRow.d.ts +17 -0
  28. package/dist/Atomic/UI/Table/Partials/TdTitle.d.ts +5 -0
  29. package/dist/Atomic/UI/Table/Table.d.ts +9 -0
  30. package/dist/Atomic/UI/Table/TdTypes/TdActions.d.ts +6 -0
  31. package/dist/Atomic/UI/Table/TdTypes/TdPriority.d.ts +6 -0
  32. package/dist/Atomic/UI/Table/TdTypes/TdRange.d.ts +4 -0
  33. package/dist/Atomic/UI/Table/TdTypes/TdWeight.d.ts +7 -0
  34. package/dist/Atomic/UI/WizardStepper/constructor.d.ts +51 -0
  35. package/dist/Classes/AbortableFetch.d.ts +43 -0
  36. package/dist/Classes/AnimatedHandler.d.ts +4 -0
  37. package/dist/Classes/RESTAPI/index.d.ts +31 -0
  38. package/dist/Classes/RESTAPI/partials/AbortableFetch.d.ts +48 -0
  39. package/dist/Classes/RESTAPI/partials/ApiBase.d.ts +21 -0
  40. package/dist/Classes/RESTAPI/partials/ApiRequestCreators.d.ts +58 -0
  41. package/dist/Classes/RESTAPI/partials/ApiUtils.d.ts +63 -0
  42. package/dist/Classes/RESTAPI/partials/CredentialsProcessing.d.ts +79 -0
  43. package/dist/Classes/RESTAPI/partials/Utils.d.ts +20 -0
  44. package/dist/Classes/RESTAPI/partials/_utils.d.ts +54 -0
  45. package/dist/Classes/RESTAPI/partials/sse.d.ts +27 -0
  46. package/dist/Classes/RESTAPI/partials/types.d.ts +159 -0
  47. package/dist/Constants/index.constants.d.ts +20 -0
  48. package/dist/Functions/Portal.d.ts +6 -0
  49. package/dist/Functions/customEventListener.d.ts +27 -0
  50. package/dist/Functions/dateTime.d.ts +95 -0
  51. package/dist/Functions/fieldValueFormatters.d.ts +19 -0
  52. package/dist/Functions/hooks/useFormFieldsChangesManager.d.ts +15 -0
  53. package/dist/Functions/locale/createTranslator.d.ts +3 -0
  54. package/dist/Functions/operations.d.ts +1 -0
  55. package/dist/Functions/presets/inputMaskPresets.d.ts +136 -0
  56. package/dist/Functions/presets/inputPresets.d.ts +16 -0
  57. package/dist/Functions/presets/mobileKeyboardTypesPresets.d.ts +17 -0
  58. package/dist/Functions/schemas.d.ts +3 -0
  59. package/dist/Functions/sdk/runtime-sdk/client.d.ts +1 -1
  60. package/dist/Functions/useBodyScrollLock.d.ts +2 -0
  61. package/dist/Functions/useClickOutside.d.ts +1 -0
  62. package/dist/Functions/useDebounce.d.ts +4 -0
  63. package/dist/Functions/useFieldFocus.d.ts +7 -0
  64. package/dist/Functions/useFormTools/form-drivers/ArrayWithObjects.d.ts +15 -0
  65. package/dist/Functions/useFormTools/form-drivers/ObjectWithIterableObjects.d.ts +12 -0
  66. package/dist/Functions/useFormTools/form-drivers/ObjectWithNamedKeyObjects.d.ts +15 -0
  67. package/dist/Functions/useFormTools/functions/General.d.ts +15 -0
  68. package/dist/Functions/useFormTools/functions/RenderFields.d.ts +7 -0
  69. package/dist/Functions/useFormTools/functions/usePrevious.d.ts +2 -0
  70. package/dist/Functions/useFormTools/index.d.ts +86 -0
  71. package/dist/Functions/useInputHighlightError.d.ts +12 -0
  72. package/dist/Functions/useLocalStorage.d.ts +2 -0
  73. package/dist/Functions/useLocationParams.d.ts +1 -0
  74. package/dist/Functions/useMediaQuery.d.ts +2 -0
  75. package/dist/Functions/useMetaInfo.d.ts +8 -0
  76. package/dist/Functions/useMouseUpOutside.d.ts +1 -0
  77. package/dist/Functions/useOnlineStatus.d.ts +2 -0
  78. package/dist/Functions/usePasswordChecker.d.ts +7 -0
  79. package/dist/Functions/usePrevious.d.ts +2 -0
  80. package/dist/Functions/useResize.d.ts +3 -0
  81. package/dist/Functions/useScrollTo.d.ts +2 -0
  82. package/dist/Functions/useToggle.d.ts +7 -0
  83. package/dist/Functions/utils.d.ts +40 -0
  84. package/dist/Langs.d.ts +179 -0
  85. package/dist/Molecular/FormWithDependOn/FormWithDependOn.d.ts +3 -0
  86. package/dist/Molecular/FormWithDependOn/FormWithDependOn.interface.d.ts +2 -2
  87. package/dist/Molecular/FormWithDependOn/partials/_utils.d.ts +8 -0
  88. package/dist/charts.cjs.map +1 -1
  89. package/dist/classes.cjs +629 -237
  90. package/dist/classes.cjs.map +4 -4
  91. package/dist/classes.js +629 -237
  92. package/dist/classes.js.map +4 -4
  93. package/dist/index.cjs +627 -235
  94. package/dist/index.cjs.map +4 -4
  95. package/dist/index.js +627 -235
  96. package/dist/index.js.map +4 -4
  97. package/dist/sdk.cjs.map +1 -1
  98. package/dist/sdk.d.ts +1 -1
  99. package/dist/sdk.js.map +1 -1
  100. package/package.json +5 -3
  101. package/styles.css +1 -0
package/dist/index.js CHANGED
@@ -399,7 +399,11 @@ var AnimatedHandler = class {
399
399
  };
400
400
  var AnimatedHandler_default = AnimatedHandler;
401
401
 
402
- // src/Classes/RESTAPI/partials/AbortableFetch.js
402
+ // src/Classes/RESTAPI/partials/AbortableFetch.ts
403
+ var HTTP_METHODS = ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"];
404
+ function isHttpMethod(value) {
405
+ return HTTP_METHODS.includes(value);
406
+ }
403
407
  var RESPONSE_AS_OBJECT_ALWAYS_VALUE2 = "always";
404
408
  var AbortableFetch2 = class {
405
409
  #pathPrefix = null;
@@ -412,6 +416,8 @@ var AbortableFetch2 = class {
412
416
  #catchCallback = null;
413
417
  #everyPromiseCallback = null;
414
418
  #isResponseAsObject = false;
419
+ // ? Последний вход request() — используется repeatRequest() для повторного запроса той же пачки.
420
+ requestInput = [];
415
421
  constructor(input) {
416
422
  if (input && !getIsOnlyAnObject(input)) throw new Error("Not valid input value!");
417
423
  this.getPathPrefix = this.getPathPrefix.bind(this);
@@ -442,20 +448,30 @@ var AbortableFetch2 = class {
442
448
  this.repeatRequest = this.repeatRequest.bind(this);
443
449
  this.setProps(input || {});
444
450
  }
451
+ /**
452
+ * Выполняет один или несколько HTTP-запросов (нативный fetch) с возможностью отмены.
453
+ *
454
+ * Метод `abort()` навешивается на прототип возвращаемого промиса (как в исходной реализации),
455
+ * что позволяет отменить всю цепочку запросов вызовом `abort()` на возвращённом промисе.
456
+ *
457
+ * @param props - путь, объект описания запроса или их массив.
458
+ * @returns Промис с результатом (форма зависит от isResponseAsObject); на прототипе доступен `abort()`.
459
+ */
445
460
  async request(props) {
446
461
  if (!getIsOnlyAnObject(props) && !Array.isArray(props) && typeof props !== "string") throw new Error("Not valid props value!");
447
- const stringifyBody = (b) => b?.constructor === FormData ? b : JSON.stringify(b);
462
+ const stringifyBody = (b) => b instanceof FormData ? b : JSON.stringify(b);
448
463
  this.requestInput = props;
449
464
  const requests = getRequestsArray.call(this, props);
450
465
  const ABORTABLE_FETCH_CONTEXT = this;
451
466
  const abortController = new AbortController();
452
467
  const addProps = (response, request) => {
453
- response.request = request;
454
- if (ABORTABLE_FETCH_CONTEXT.#isResponseAsObject) response.name = getIsOnlyAnObject(request) ? request.name || "" : "";
455
- return response;
468
+ return Object.assign(response, {
469
+ request,
470
+ ...ABORTABLE_FETCH_CONTEXT.#isResponseAsObject ? { name: getIsOnlyAnObject(request) ? request.name || "" : "" } : {}
471
+ });
456
472
  };
457
- let externalRequest = Promise.all(
458
- requests.map(async (item) => {
473
+ const externalRequest = Promise.all(
474
+ requests.map((item) => {
459
475
  const safelyQuery = item.path.includes("?") ? `&${item.queryParameters.replace(/\?/g, "")}` : item.queryParameters;
460
476
  const internalRequest = fetch(`${item.pathPrefix}${item.path}${safelyQuery}`, {
461
477
  ...item.options,
@@ -466,12 +482,15 @@ var AbortableFetch2 = class {
466
482
  }).then(async (response) => addProps(response, item)).catch(async (response) => {
467
483
  if (response instanceof Response) return Promise.resolve(addProps(response, item));
468
484
  return Promise.resolve(
469
- addProps({
470
- ok: false,
471
- status: 0,
472
- statusText: response,
473
- request: item
474
- })
485
+ addProps(
486
+ {
487
+ ok: false,
488
+ status: 0,
489
+ statusText: response,
490
+ request: item
491
+ },
492
+ item
493
+ )
475
494
  );
476
495
  }).then(async (res) => {
477
496
  return typeof ABORTABLE_FETCH_CONTEXT.#everyPromiseCallback === "function" && !item.isSkipEveryPromiseCallback ? await ABORTABLE_FETCH_CONTEXT.#everyPromiseCallback(res) : res;
@@ -480,7 +499,8 @@ var AbortableFetch2 = class {
480
499
  }).then(async (res) => {
481
500
  return { request: item, response: res, ...item.name ? { name: item.name } : {} };
482
501
  });
483
- internalRequest.__proto__.abort = () => abortController.abort();
502
+ const internalProto = Object.getPrototypeOf(internalRequest);
503
+ internalProto.abort = () => abortController.abort();
484
504
  return internalRequest;
485
505
  })
486
506
  ).then(async (resArr) => {
@@ -488,16 +508,17 @@ var AbortableFetch2 = class {
488
508
  return ABORTABLE_FETCH_CONTEXT.#isResponseAsObject ? {} : [];
489
509
  }
490
510
  if (ABORTABLE_FETCH_CONTEXT.#isResponseAsObject === RESPONSE_AS_OBJECT_ALWAYS_VALUE2) {
491
- return resArr.reduce((ac, item) => ({ ...ac, [item.name]: item.response }), {});
511
+ return resArr.reduce((ac, item) => ({ ...ac, [String(item.name)]: item.response }), {});
492
512
  }
493
513
  if (resArr.length === 1) return resArr[0].response;
494
- return ABORTABLE_FETCH_CONTEXT.#isResponseAsObject === true ? resArr.reduce((ac, item) => ({ ...ac, [item.name]: item.response }), {}) : resArr.map((item) => item.response);
514
+ return ABORTABLE_FETCH_CONTEXT.#isResponseAsObject === true ? resArr.reduce((ac, item) => ({ ...ac, [String(item.name)]: item.response }), {}) : resArr.map((item) => item.response);
495
515
  }).then(async (res) => {
496
516
  return typeof ABORTABLE_FETCH_CONTEXT.#callback === "function" ? await ABORTABLE_FETCH_CONTEXT.#callback(res) : res;
497
517
  }).catch(async (res) => {
498
518
  return typeof ABORTABLE_FETCH_CONTEXT.#catchCallback === "function" ? await ABORTABLE_FETCH_CONTEXT.#catchCallback(res) : res;
499
519
  });
500
- externalRequest.__proto__.abort = () => abortController.abort();
520
+ const externalProto = Object.getPrototypeOf(externalRequest);
521
+ externalProto.abort = () => abortController.abort();
501
522
  return externalRequest;
502
523
  function getRequestsArray(input) {
503
524
  const requestsArray = (() => {
@@ -522,15 +543,17 @@ var AbortableFetch2 = class {
522
543
  callback: omitCallback,
523
544
  mergeProps: omitMergeProps,
524
545
  ...optionsRest
525
- } = options || {};
546
+ } = getIsOnlyAnObject(options) ? options : {};
547
+ const localMethod = typeof method === "string" && isHttpMethod(method) ? method : null;
548
+ const localCallback = typeof callback === "function" ? (res) => callback(res) : void 0;
526
549
  return [
527
550
  ...ac,
528
551
  {
529
552
  path,
530
553
  pathPrefix: getMergeProps("pathPrefix") === "onlyLocal" || isNoPathPrefix ? "" : this.#pathPrefix || "",
531
554
  method: (() => {
532
- if (getMergeProps("method") === "onlyLocal") return method || "GET";
533
- return getMergeProps("method") === "onlyGlobal" ? this.#method || "GET" : method || this.#method || "GET";
555
+ if (getMergeProps("method") === "onlyLocal") return localMethod || "GET";
556
+ return getMergeProps("method") === "onlyGlobal" ? this.#method || "GET" : localMethod || this.#method || "GET";
534
557
  })(),
535
558
  queryParameters: (() => {
536
559
  if ((getMergeProps("queryParameters") ?? getMergeProps("query")) === "onlyLocal") {
@@ -539,31 +562,34 @@ var AbortableFetch2 = class {
539
562
  return (getMergeProps("queryParameters") ?? getMergeProps("query")) === "onlyGlobal" ? this.getQueryString(this.getQueryArray(this.#queryParameters)) : this.getQueryString([...this.getQueryArray(this.#queryParameters), ...this.getQueryArray(queryParameters)]);
540
563
  })(),
541
564
  headers: (() => {
542
- if (getMergeProps("headers") === "onlyLocal") return this.getHeadersObj(headers || {});
565
+ if (getMergeProps("headers") === "onlyLocal") return this.getHeadersObj(getIsOnlyAnObject(headers) ? headers : {});
543
566
  return getMergeProps("headers") === "onlyGlobal" ? this.getHeadersObj({ ...this.#headers || {} }) : this.getHeadersObj({
544
567
  ...this.#headers || {},
545
- ...headers || {}
568
+ ...getIsOnlyAnObject(headers) ? headers : {}
546
569
  });
547
570
  })(),
548
571
  body: (() => {
549
572
  if (getMergeProps("body") === "onlyLocal") return body || null;
550
573
  if (getMergeProps("body") === "onlyGlobal") return this.#body || null;
551
574
  if (body && this.#body && typeof body === typeof this.#body && typeof body === "object") {
552
- return Array.isArray(body) ? [...this.#body, ...body] : { ...this.#body, ...body };
553
- } else return body || this.#body || null;
575
+ return Array.isArray(body) ? [...Array.isArray(this.#body) ? this.#body : [], ...body] : { ...getIsOnlyAnObject(this.#body) ? this.#body : {}, ...getIsOnlyAnObject(body) ? body : {} };
576
+ } else {
577
+ return body || this.#body || null;
578
+ }
554
579
  })(),
555
580
  options: (() => {
556
- if (getMergeProps("options") === "onlyLocal") return { ...optionsRest || {} };
557
- return getMergeProps("options") === "onlyGlobal" ? { ...this.#options || {} } : { ...this.#options || {}, ...optionsRest || {} };
581
+ if (getMergeProps("options") === "onlyLocal") return { ...optionsRest };
582
+ return getMergeProps("options") === "onlyGlobal" ? { ...this.#options || {} } : { ...this.#options || {}, ...optionsRest };
558
583
  })(),
559
- callback,
560
- isSkipEveryPromiseCallback,
584
+ callback: localCallback,
585
+ isSkipEveryPromiseCallback: Boolean(isSkipEveryPromiseCallback),
561
586
  ...this.getIsResponseAsObject() ? { name: name && typeof name === "string" ? name : index } : {}
562
587
  }
563
588
  ];
564
589
  }, []);
565
590
  }
566
591
  }
592
+ /** Повторяет последний выполненный запрос (ту же пачку). */
567
593
  repeatRequest() {
568
594
  return this.request(this.requestInput);
569
595
  }
@@ -579,19 +605,23 @@ var AbortableFetch2 = class {
579
605
  return this.#method;
580
606
  }
581
607
  setMethod(value) {
582
- const methods = ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"];
583
- if (value && !methods.includes(value)) throw new Error("Not valid method value!");
608
+ if (value && !isHttpMethod(value)) throw new Error("Not valid method value!");
584
609
  this.#method = value || null;
585
610
  }
586
611
  getQueryParameters() {
587
612
  return this.#queryParameters;
588
613
  }
589
614
  getQueryArray(value) {
590
- if (typeof value === "string") return (value[0] === "?" ? value.slice(1) : value).split("&");
591
- else if (Array.isArray(value)) return value;
592
- else if (typeof value === "object" && value !== null) {
593
- return Object.keys(value).filter((key) => Boolean(key) && Boolean(value[key])).map((key) => `${key}=${value[key]}`);
594
- } else return [];
615
+ if (typeof value === "string") {
616
+ return (value[0] === "?" ? value.slice(1) : value).split("&");
617
+ } else if (Array.isArray(value)) {
618
+ return value.map((item) => `${item}`);
619
+ } else if (typeof value === "object" && value !== null) {
620
+ const record = getIsOnlyAnObject(value) ? value : {};
621
+ return Object.keys(record).filter((key) => Boolean(key) && Boolean(record[key])).map((key) => `${key}=${record[key]}`);
622
+ } else {
623
+ return [];
624
+ }
595
625
  }
596
626
  getQueryString(value) {
597
627
  if (!value) return "";
@@ -610,7 +640,7 @@ var AbortableFetch2 = class {
610
640
  if (!obj) return headers;
611
641
  if (typeof obj !== "object" || Array.isArray(obj)) throw new Error("Not valid headers value!");
612
642
  Object.keys(obj).forEach((key) => {
613
- headers.append(key, obj[key]);
643
+ headers.append(key, `${obj[key]}`);
614
644
  });
615
645
  return headers;
616
646
  }
@@ -686,39 +716,64 @@ var AbortableFetch2 = class {
686
716
  // isAnywayRunCallback,
687
717
  isResponseAsObject
688
718
  } = input;
689
- if (pathPrefix) this.setPathPrefix(pathPrefix);
690
- if (method) this.setMethod(method);
719
+ if (pathPrefix) this.setPathPrefix(typeof pathPrefix === "string" ? pathPrefix : null);
720
+ if (method) this.setMethod(typeof method === "string" && isHttpMethod(method) ? method : null);
691
721
  if (queryParameters) this.setQueryParameters(this.getQueryArray(queryParameters));
692
- if (headers) this.setHeaders(headers);
722
+ if (headers) this.setHeaders(getIsOnlyAnObject(headers) ? headers : null);
693
723
  if (body) this.setBody(body);
694
- if (options) this.setOptions(options);
695
- if (callback) this.setCallback(callback);
696
- if (catchCallback) this.setCatchCallback(catchCallback);
697
- if (everyPromiseCallback) this.setEveryPromiseCallback(everyPromiseCallback);
724
+ if (options) this.setOptions(getIsOnlyAnObject(options) ? options : null);
725
+ if (callback && typeof callback === "function") {
726
+ const fn = callback;
727
+ this.setCallback(function wrappedCallback(response) {
728
+ return fn.call(this, response);
729
+ });
730
+ }
731
+ if (catchCallback && typeof catchCallback === "function") {
732
+ const fn = catchCallback;
733
+ this.setCatchCallback(function wrappedCatchCallback(response) {
734
+ return fn.call(this, response);
735
+ });
736
+ }
737
+ if (everyPromiseCallback && typeof everyPromiseCallback === "function") {
738
+ const fn = everyPromiseCallback;
739
+ this.setEveryPromiseCallback(function wrappedEveryPromiseCallback(response) {
740
+ return fn.call(this, response);
741
+ });
742
+ }
698
743
  if (isResponseAsObject !== void 0) this.setIsResponseAsObject(isResponseAsObject);
699
744
  }
700
745
  };
701
746
  var AbortableFetch_default2 = AbortableFetch2;
702
747
 
703
- // src/Classes/RESTAPI/partials/_utils.js
748
+ // src/Classes/RESTAPI/partials/_utils.ts
704
749
  function getIsOnlyAnObject(input) {
705
- return typeof input === "object" && // "отбивает" примитивы и функции
706
- input instanceof Object && // "отбивает" null
707
- !Array.isArray(input) && // "отбивает" массивы
708
- !(input instanceof Set) && // "отбивает" сеты
709
- !(input instanceof Map);
750
+ return typeof input === "object" && input instanceof Object && !Array.isArray(input) && !(input instanceof Set) && !(input instanceof Map);
710
751
  }
711
- var clone = (input) => {
752
+ function clone(input) {
712
753
  if (input === null || typeof input !== "object") return input;
713
- const data = input instanceof Array ? [] : {};
714
- for (const i in input) data[i] = clone(input[i]);
754
+ if (Array.isArray(input)) return input.map((item) => clone(item));
755
+ const source = getIsOnlyAnObject(input) ? input : {};
756
+ const data = {};
757
+ Object.keys(source).forEach((key) => {
758
+ data[key] = clone(source[key]);
759
+ });
715
760
  return data;
716
- };
717
- var omitKeys = (obj = {}, keys = []) => keys.reduce((acc, key) => {
718
- const { [key]: omit, ...rest } = acc;
719
- return rest;
720
- }, obj);
721
- var getResponseClone = async (res) => typeof res?.clone === "function" ? await res.clone() : clone(res);
761
+ }
762
+ function omitKeys(obj, keys = []) {
763
+ const source = obj ?? {};
764
+ const keySet = new Set(keys);
765
+ const result = {};
766
+ Object.keys(source).forEach((key) => {
767
+ if (!keySet.has(key)) result[key] = source[key];
768
+ });
769
+ return result;
770
+ }
771
+ async function getResponseClone(res) {
772
+ if (res && typeof res === "object" && "clone" in res && typeof res.clone === "function") {
773
+ return res.clone();
774
+ }
775
+ return clone(res);
776
+ }
722
777
  function addCustomMethods(data, prefix) {
723
778
  const preparedPrefix = (prefix || "").toString();
724
779
  Object.keys(data).forEach((key) => {
@@ -732,7 +787,7 @@ async function getInstanceOfFetchSystem(isGetBody) {
732
787
  let credentials = {};
733
788
  if (CREDENTIALS_CONTEXT) {
734
789
  const cred = await CREDENTIALS_CONTEXT.getCredentials();
735
- credentials = CREDENTIALS_CONTEXT.isUseRefreshTokensPropcessing ? await CREDENTIALS_CONTEXT.waitRefresh(cred.isNeedRefresh && !CREDENTIALS_CONTEXT.getIsTokenStartRefresh()).then(
790
+ credentials = CREDENTIALS_CONTEXT.isUseRefreshTokensPropcessing ? await CREDENTIALS_CONTEXT.waitRefresh(Boolean(cred.isNeedRefresh) && !CREDENTIALS_CONTEXT.getIsTokenStartRefresh()).then(
736
791
  async () => CREDENTIALS_CONTEXT.processCredentials(await CREDENTIALS_CONTEXT.getCredentials())
737
792
  ) : cred;
738
793
  }
@@ -750,52 +805,57 @@ async function getInstanceOfFetchSystem(isGetBody) {
750
805
  }
751
806
  return (CREDENTIALS_CONTEXT?.isUseRefreshTokensPropcessing ? CREDENTIALS_CONTEXT.waitRefresh() : Promise.resolve()).then(
752
807
  async () => new AbortableFetch_default2({
753
- //? Метод по умолчанию
808
+ // ? Метод по умолчанию
754
809
  method: "GET",
755
- //? Заголовки по умолчанию
810
+ // ? Заголовки по умолчанию
756
811
  headers: {
757
812
  ...headersToAbortableFetchInstance,
758
- //? (*) Тут обрабатываются кейсы
759
- //? - когда нет this.credentialsProcessing
760
- //? (мы НЕ хотим добавлять токены в принципе, не зашли в верхнюю if-ку)
761
- //? - когда есть this.credentialsProcessing, но нет credentials.token (не авторизованы)
762
- //? (зашли в верхнюю if-ку, попробовали получить/обновить креды)
813
+ // ? (*) Тут обрабатываются кейсы
814
+ // ? - когда нет this.credentialsProcessing
815
+ // ? (мы НЕ хотим добавлять токены в принципе, не зашли в верхнюю if-ку)
816
+ // ? - когда есть this.credentialsProcessing, но нет credentials.token (не авторизованы)
817
+ // ? (зашли в верхнюю if-ку, попробовали получить/обновить креды)
763
818
  ...credentials.token ? CREDENTIALS_CONTEXT?.getHeadersForAuthorize?.(credentials.token) || {} : {}
764
819
  },
765
820
  queryParameters: await API_CONTEXT.processQueryParams(queryParamsToAbortableFetchInstance),
766
- //? Опции по умолчанию
821
+ // ? Опции по умолчанию
767
822
  options: {
768
823
  mode: "cors",
769
824
  redirect: "follow",
770
825
  ...optionsToAbortableFetchInstance
771
826
  },
772
- //? Каждый запрос (каждый запрос мультизапроса), сделаный методом request этого экземпляра выполнит этот колбек
827
+ // ? Каждый запрос (каждый запрос мультизапроса), сделаный методом request этого экземпляра выполнит этот колбек
773
828
  everyPromiseCallback: async function everyPromiseCallback(response) {
774
829
  const ABORTABLE_FETCH_INSTANCE = this;
775
830
  if (!response.status) {
776
- const request = ABORTABLE_FETCH_INSTANCE.requestInput.find((item) => item?.path === response?.request?.path);
777
- const isUseErrorToast = request?.mesageOptions?.isUseErrorToast;
831
+ const reqInput = ABORTABLE_FETCH_INSTANCE.requestInput;
832
+ const responseRequest = getIsOnlyAnObject(response.request) ? response.request : {};
833
+ const request = Array.isArray(reqInput) ? reqInput.find((item) => getIsOnlyAnObject(item) && item.path === responseRequest.path) : void 0;
834
+ const mesageOptions = getIsOnlyAnObject(request) && getIsOnlyAnObject(request.mesageOptions) ? request.mesageOptions : void 0;
835
+ const isUseErrorToast = mesageOptions?.isUseErrorToast;
778
836
  if (isUseErrorToast) {
779
- API_CONTEXT.sendMessage?.(API_CONTEXT.NO_INET, request.mesageOptions, response);
837
+ API_CONTEXT.sendMessage?.(API_CONTEXT.NO_INET, mesageOptions, response);
780
838
  }
781
839
  }
782
- return API_CONTEXT.REJECT_CODES.includes(response.status) || CREDENTIALS_CONTEXT?.isUseRefreshTokensPropcessing && CREDENTIALS_CONTEXT?.CODES_USING_THE_REFRESH_ATTEMPT?.includes?.(response.status) ? Promise.reject(new Error(`status:${response.status}`)) : Promise.resolve(!isGetBody ? response : await API_CONTEXT.getResponseBody(response));
840
+ return API_CONTEXT.REJECT_CODES.includes(Number(response.status)) || CREDENTIALS_CONTEXT?.isUseRefreshTokensPropcessing && Boolean(CREDENTIALS_CONTEXT?.CODES_USING_THE_REFRESH_ATTEMPT?.includes(Number(response.status))) ? Promise.reject(new Error(`status:${Number(response.status)}`)) : Promise.resolve(!isGetBody ? response : await API_CONTEXT.getResponseBody(response));
783
841
  },
784
- //? Если хоть один запрос из пачки будет зареджекчен, зареджектится вся пачка.
785
- //? В этом случае будет выполнен этот колбэк
842
+ // ? Если хоть один запрос из пачки будет зареджекчен, зареджектится вся пачка.
843
+ // ? В этом случае будет выполнен этот колбэк
786
844
  catchCallback: async function catchCallback(res) {
787
845
  const ABORTABLE_FETCH_INSTANCE = this;
788
- const code = Number(res.message.split(":")[1]);
789
- if (CREDENTIALS_CONTEXT?.CODES_USING_THE_REFRESH_ATTEMPT?.includes?.(code)) {
790
- const isDoRefresh = !CREDENTIALS_CONTEXT?.getIsTokenStartRefresh?.();
791
- return CREDENTIALS_CONTEXT?.waitRefresh(isDoRefresh).then(async () => {
792
- const newCredentials = await CREDENTIALS_CONTEXT?.processCredentials({
793
- ...await CREDENTIALS_CONTEXT?.getCredentials(true),
846
+ if (!CREDENTIALS_CONTEXT) return Promise.reject(res);
847
+ const code = Number(res instanceof Error ? res.message.split(":")[1] : "");
848
+ if (CREDENTIALS_CONTEXT.CODES_USING_THE_REFRESH_ATTEMPT?.includes(code)) {
849
+ const isDoRefresh = !CREDENTIALS_CONTEXT.getIsTokenStartRefresh();
850
+ return CREDENTIALS_CONTEXT.waitRefresh(isDoRefresh).then(async () => {
851
+ const newCredentials = await CREDENTIALS_CONTEXT.processCredentials({
852
+ ...await CREDENTIALS_CONTEXT.getCredentials(true),
794
853
  isCatchCallbackProcess: isDoRefresh
795
854
  });
855
+ const currentHeaders = ABORTABLE_FETCH_INSTANCE.getHeaders();
796
856
  ABORTABLE_FETCH_INSTANCE.setHeaders({
797
- ...ABORTABLE_FETCH_INSTANCE.getHeaders(),
798
- ...newCredentials?.token ? { Authorization: `Bearer ${newCredentials?.token}` } : {}
857
+ ...getIsOnlyAnObject(currentHeaders) ? currentHeaders : {},
858
+ ...newCredentials.token ? { Authorization: `Bearer ${newCredentials.token}` } : {}
799
859
  });
800
860
  if (newCredentials.token) return ABORTABLE_FETCH_INSTANCE.repeatRequest();
801
861
  return Promise.reject(res);
@@ -807,13 +867,23 @@ async function getInstanceOfFetchSystem(isGetBody) {
807
867
  );
808
868
  }
809
869
 
810
- // src/Classes/RESTAPI/partials/Utils.js
870
+ // src/Classes/RESTAPI/partials/Utils.ts
811
871
  var Utils = class {
812
- //! Могут содержаться НЕасинхронные методы!
813
- //? Ф-я normalizeQueryParams является нормализатором сложных квери
814
- //? Например: &key1=&&&===&&&key2====&&&&&&&&key3=....
815
- //? Для корректной работы на вход нужно подавать НЕ кодированные значения
816
- //? По умолчанию выходные значения квери-параметров НЕ кодируются
872
+ // ! Могут содержаться НЕасинхронные методы!
873
+ /**
874
+ * Нормализатор сложных query-параметров.
875
+ *
876
+ * Например: `&key1=&&&===&&&key2====&&&&&&&&key3=...`. Для корректной работы на вход нужно подавать
877
+ * НЕ кодированные значения. По умолчанию выходные значения query-параметров НЕ кодируются.
878
+ *
879
+ * @param queryParams - query в виде строки, массива или объекта.
880
+ * @param settings - формат вывода (`array` | `string` | `object`) и флаг кодирования.
881
+ * @returns Нормализованные query-параметры в выбранном формате.
882
+ */
883
+ // ? Ф-я normalizeQueryParams является нормализатором сложных квери
884
+ // ? Например: &key1=&&&===&&&key2====&&&&&&&&key3=....
885
+ // ? Для корректной работы на вход нужно подавать НЕ кодированные значения
886
+ // ? По умолчанию выходные значения квери-параметров НЕ кодируются
817
887
  normalizeQueryParams(queryParams, settings) {
818
888
  if (settings && !getIsOnlyAnObject(settings)) {
819
889
  throw new Error("Bad settings [class Utils, normalizeQueryParams]");
@@ -832,9 +902,13 @@ var Utils = class {
832
902
  if (index === -1) return [item];
833
903
  return [item.slice(0, index), item.slice(index + 1)];
834
904
  }).filter(([key]) => Boolean(key)).map(([key, value]) => prepareParam(key, value));
835
- } else if (getIsOnlyAnObject(input)) return Object.keys(input).map((key) => prepareParam(key, input[key]));
836
- else if (typeof input === "string") return (input[0] === "?" ? input.slice(1) : input).split("&");
837
- else return [];
905
+ } else if (getIsOnlyAnObject(input)) {
906
+ return Object.keys(input).map((key) => prepareParam(key, input[key]));
907
+ } else if (typeof input === "string") {
908
+ return (input[0] === "?" ? input.slice(1) : input).split("&");
909
+ } else {
910
+ return [];
911
+ }
838
912
  };
839
913
  const { isEncode = false, outputAs = "array" } = settings || {};
840
914
  const initialStructure = getInitialArr(queryParams);
@@ -851,7 +925,9 @@ var Utils = class {
851
925
  if (index !== -1 && index !== 0) {
852
926
  const key = str.slice(0, index);
853
927
  acc.result.push(`${key}=${encodeURIComponent(str.slice(index + 1))}`);
854
- } else acc.toJoin = str;
928
+ } else {
929
+ acc.toJoin = str;
930
+ }
855
931
  if (idx === initialStructure.length - 1 && typeof acc.toJoin === "string") processToJoin(acc.toJoin);
856
932
  return acc;
857
933
  },
@@ -859,7 +935,7 @@ var Utils = class {
859
935
  ).result;
860
936
  const outputStructure = normalizedStructure.map((item) => {
861
937
  const [key, value] = item.split("=");
862
- return [key, !isEncode ? decodeURIComponent(value) : value];
938
+ return [key, !isEncode ? decodeURIComponent(value ?? "") : value ?? ""];
863
939
  });
864
940
  switch (outputAs) {
865
941
  case "string":
@@ -873,16 +949,25 @@ var Utils = class {
873
949
  };
874
950
  var Utils_default = Utils;
875
951
 
876
- // src/Classes/RESTAPI/partials/ApiUtils.js
952
+ // src/Classes/RESTAPI/partials/ApiUtils.ts
877
953
  var ApiUtils = class extends Utils_default {
954
+ /** Корневой путь API (раскладывается в ApiBase из constants.API_PATH). */
955
+ API_PATH;
878
956
  constructor(settings) {
879
957
  super();
880
958
  const { utils } = settings || {};
881
959
  if (getIsOnlyAnObject(utils)) addCustomMethods.call(this, utils);
882
960
  }
883
- //? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
884
- //? Метод не планировался как асинхронный,
885
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
961
+ /**
962
+ * Разбирает единый объект параметров запроса на части в зависимости от варианта использования.
963
+ *
964
+ * @param apiParams - объединённые параметры запроса.
965
+ * @param variant - `'doRequestMapping'` для мультизапроса либо `undefined` для одиночного.
966
+ * @returns Для `doRequestMapping` — объект параметров; иначе кортеж `[параметры, настройки]`.
967
+ */
968
+ // ? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
969
+ // ? Метод не планировался как асинхронный,
970
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
886
971
  async splitProperties(apiParams, variant) {
887
972
  const {
888
973
  isResponseAsObject,
@@ -941,79 +1026,224 @@ var ApiUtils = class extends Utils_default {
941
1026
  ];
942
1027
  }
943
1028
  }
944
- //! Обработчик пропы api из объекта описания запроса
945
- //? Планируется, что метод будет перегружаться на экземпляре,
946
- //? т.к. на разных проектах могут быть разные интерпретации пропы api
947
- //? Метод не планировался как асинхронный,
948
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1029
+ /**
1030
+ * Обработчик пропы `api` из объекта описания запроса — возвращает корневой путь API.
1031
+ *
1032
+ * @returns Корневой путь (по умолчанию — API_PATH).
1033
+ */
1034
+ // ! Обработчик пропы api из объекта описания запроса
1035
+ // ? Планируется, что метод будет перегружаться на экземпляре,
1036
+ // ? т.к. на разных проектах могут быть разные интерпретации пропы api
1037
+ // ? Метод не планировался как асинхронный,
1038
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
949
1039
  async getRootPath() {
950
1040
  return this.API_PATH;
951
1041
  }
952
- //? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
953
- //? Метод планировался как асинхронный
1042
+ /**
1043
+ * Извлекает тело ответа в нужном виде (json/blob/text/arrayBuffer/formData) либо по content-type.
1044
+ *
1045
+ * @param response - объект Response (иначе значение возвращается как есть).
1046
+ * @param getBodyAs - желаемый способ извлечения тела.
1047
+ * @returns Промис с телом ответа (или исходным значением / null при ошибке).
1048
+ */
1049
+ // ? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
1050
+ // ? Метод планировался как асинхронный
954
1051
  async getResponseBody(response, getBodyAs) {
955
1052
  if (!(response instanceof Response)) return response;
956
1053
  const contentType = response.headers.get("content-type");
957
1054
  if (!contentType) return "";
958
- const executor = (() => {
959
- if (typeof getBodyAs === "string" && getBodyAs in response && typeof response[getBodyAs] === "function") {
960
- return response[getBodyAs];
961
- }
962
- if (typeof contentType === "string" && contentType.includes("text/csv")) {
963
- return response.blob;
964
- }
965
- return typeof contentType === "string" && contentType.includes("json") ? response.json : response.text;
966
- })();
1055
+ const bodyReaders = {
1056
+ json: (r) => r.json(),
1057
+ blob: (r) => r.blob(),
1058
+ text: (r) => r.text(),
1059
+ arrayBuffer: (r) => r.arrayBuffer(),
1060
+ formData: (r) => r.formData()
1061
+ };
1062
+ const isBodyKey = (key) => key in bodyReaders;
1063
+ const reader = typeof getBodyAs === "string" && isBodyKey(getBodyAs) ? bodyReaders[getBodyAs] : contentType.includes("text/csv") ? bodyReaders.blob : contentType.includes("json") ? bodyReaders.json : bodyReaders.text;
967
1064
  try {
968
- return await executor.call(response);
1065
+ return await reader(response);
969
1066
  } catch {
970
1067
  console.log("Failed to extract the body");
971
1068
  return null;
972
1069
  }
973
1070
  }
974
- //! Обработчик структуры для ошибки (не рендер месседжа, а имеено формирование ошибки),
975
- //? Планируется, что метод будет перегружаться на экземпляре,
976
- //? т.к. на разных проектах могут быть разные структуры тела ответа для ошибки
977
- //? Метод не планировался как асинхронный,
978
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
979
- //? res - уже тело ответа
1071
+ /**
1072
+ * Формирует структуру ошибки из тела ответа (точка расширения под формат бэкенда).
1073
+ *
1074
+ * @param res - уже извлечённое тело ответа.
1075
+ * @returns Структура сообщения об ошибке.
1076
+ */
1077
+ // ! Обработчик структуры для ошибки (не рендер месседжа, а имеено формирование ошибки),
1078
+ // ? Планируется, что метод будет перегружаться на экземпляре,
1079
+ // ? т.к. на разных проектах могут быть разные структуры тела ответа для ошибки
1080
+ // ? Метод не планировался как асинхронный,
1081
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1082
+ // ? res - уже тело ответа
980
1083
  async getErrorMessage(res) {
981
1084
  return res;
982
1085
  }
983
- //? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
984
- //? Метод планировался как асинхронный
1086
+ /**
1087
+ * Проверяет код ответа и (если задан sendMessage) информирует пользователя об успехе/ошибке.
1088
+ *
1089
+ * @param res - объект Response (или совместимый с полем `ok`).
1090
+ * @param settings - сообщения и настройки тостов для данного запроса.
1091
+ * @returns Исходный `res` (метод не меняет ответ, только сигналит сообщением).
1092
+ */
1093
+ // ? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
1094
+ // ? Метод планировался как асинхронный
985
1095
  async checkResponseCode(res, settings) {
986
- if (typeof this.sendMessage !== "function") return res;
1096
+ const send = this.sendMessage;
1097
+ if (typeof send !== "function") return res;
987
1098
  const { successMess, errorMess } = settings || {};
988
- const message = res.ok ? successMess || this.DEFAULT_SUCCESS_MESSAGE : errorMess || await this.getErrorMessage(await this.getResponseBody(await getResponseClone(res)));
1099
+ const isOk = getIsOnlyAnObject(res) ? Boolean(res.ok) : false;
1100
+ const message = isOk ? successMess || this.DEFAULT_SUCCESS_MESSAGE : errorMess || await this.getErrorMessage(await this.getResponseBody(await getResponseClone(res)));
989
1101
  try {
990
- this.sendMessage(message, settings, await getResponseClone(res));
991
- } catch (_error) {
1102
+ send(message, settings, await getResponseClone(res));
1103
+ } catch {
992
1104
  }
993
1105
  return res;
994
1106
  }
995
- //? Суть метода:
996
- //? передать из вне структуры, которые будут использоваться для КАЖДОГО запроса сделанного экземпляром RESTAPI
997
- //! Данные затрут прочие настройки КРОМЕ данных по логике авторизации
998
- //? Планируется, что метод будет перегружаться на экземпляре
999
- //? Метод не планировался как асинхронный,
1000
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1107
+ /**
1108
+ * Структуры, которые будут использоваться для КАЖДОГО запроса, сделанного экземпляром RESTAPI.
1109
+ *
1110
+ * @returns Объект `{ headers, queryParameters, options }` (по умолчанию пустой).
1111
+ */
1112
+ // ? Суть метода:
1113
+ // ? передать из вне структуры, которые будут использоваться для КАЖДОГО запроса сделанного экземпляром RESTAPI
1114
+ // ! Данные затрут прочие настройки КРОМЕ данных по логике авторизации
1115
+ // ? Планируется, что метод будет перегружаться на экземпляре
1116
+ // ? Метод не планировался как асинхронный,
1117
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1001
1118
  async addAsCommon() {
1002
1119
  return {};
1003
1120
  }
1004
- //! Обработчик квери-параметров для общего процессинга,
1005
- //! Например для кодирования decodeURIComponent или/и приведения в формат массива
1006
- //? Планируется, что метод будет перегружаться на экземпляре,
1007
- //? т.к. на разных проектах могут быть разные договоренности по форматам
1008
- //? Метод не планировался как асинхронный,
1009
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1121
+ /**
1122
+ * Общий обработчик query-параметров (точка расширения, напр. кодирование/приведение к массиву).
1123
+ *
1124
+ * @param queryParams - входные query-параметры.
1125
+ * @returns Обработанные query-параметры (по умолчанию — без изменений).
1126
+ */
1127
+ // ! Обработчик квери-параметров для общего процессинга,
1128
+ // ! Например для кодирования decodeURIComponent или/и приведения в формат массива
1129
+ // ? Планируется, что метод будет перегружаться на экземпляре,
1130
+ // ? т.к. на разных проектах могут быть разные договоренности по форматам
1131
+ // ? Метод не планировался как асинхронный,
1132
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1010
1133
  async processQueryParams(queryParams) {
1011
1134
  return queryParams;
1012
1135
  }
1013
1136
  };
1014
1137
  var ApiUtils_default = ApiUtils;
1015
1138
 
1016
- // src/Classes/RESTAPI/partials/ApiRequestCreators.js
1139
+ // src/Classes/RESTAPI/partials/sse.ts
1140
+ function parseSSEEvent(block) {
1141
+ if (typeof block !== "string") return null;
1142
+ const event = { event: "message", data: "", id: void 0, retry: void 0 };
1143
+ const dataLines = [];
1144
+ let hasField = false;
1145
+ block.split("\n").forEach((line) => {
1146
+ if (line === "" || line[0] === ":") return;
1147
+ const colonIdx = line.indexOf(":");
1148
+ const field = colonIdx === -1 ? line : line.slice(0, colonIdx);
1149
+ let value = colonIdx === -1 ? "" : line.slice(colonIdx + 1);
1150
+ if (value[0] === " ") value = value.slice(1);
1151
+ switch (field) {
1152
+ case "event":
1153
+ event.event = value;
1154
+ hasField = true;
1155
+ break;
1156
+ case "data":
1157
+ dataLines.push(value);
1158
+ hasField = true;
1159
+ break;
1160
+ case "id":
1161
+ event.id = value;
1162
+ hasField = true;
1163
+ break;
1164
+ case "retry":
1165
+ if (/^\d+$/.test(value)) {
1166
+ event.retry = Number(value);
1167
+ hasField = true;
1168
+ }
1169
+ break;
1170
+ default:
1171
+ break;
1172
+ }
1173
+ });
1174
+ if (!hasField) return null;
1175
+ event.data = dataLines.join("\n");
1176
+ return event;
1177
+ }
1178
+ function safeCall(fn, ...args) {
1179
+ if (typeof fn !== "function") return;
1180
+ try {
1181
+ fn(...args);
1182
+ } catch {
1183
+ }
1184
+ }
1185
+ async function readSSE(response, { onEvent, onChunk, handlers, parseJson } = {}) {
1186
+ const events = [];
1187
+ const stream = response.body;
1188
+ if (!stream) return events;
1189
+ const reader = stream.getReader();
1190
+ const decoder = new TextDecoder("utf-8");
1191
+ let buffer = "";
1192
+ let pendingCR = "";
1193
+ const normalize = (chunk) => chunk.replace(/\r\n|\r/g, "\n");
1194
+ const flush = (rawBlock) => {
1195
+ const event = parseSSEEvent(rawBlock);
1196
+ if (!event) return;
1197
+ if (parseJson && typeof event.data === "string" && event.data !== "") {
1198
+ try {
1199
+ event.data = JSON.parse(event.data);
1200
+ } catch {
1201
+ }
1202
+ }
1203
+ events.push(event);
1204
+ safeCall(onEvent, event);
1205
+ safeCall(onChunk, event.data, event);
1206
+ if (handlers) safeCall(handlers[event.event], event.data, event);
1207
+ };
1208
+ try {
1209
+ while (true) {
1210
+ const { done, value } = await reader.read();
1211
+ if (done) break;
1212
+ let chunk = pendingCR + decoder.decode(value, { stream: true });
1213
+ pendingCR = "";
1214
+ if (chunk.endsWith("\r")) {
1215
+ pendingCR = "\r";
1216
+ chunk = chunk.slice(0, -1);
1217
+ }
1218
+ buffer += normalize(chunk);
1219
+ let sepIdx;
1220
+ while ((sepIdx = buffer.indexOf("\n\n")) !== -1) {
1221
+ const rawBlock = buffer.slice(0, sepIdx);
1222
+ buffer = buffer.slice(sepIdx + 2);
1223
+ flush(rawBlock);
1224
+ }
1225
+ }
1226
+ buffer += normalize(pendingCR + decoder.decode());
1227
+ buffer = buffer.replace(/\n+$/g, "");
1228
+ if (buffer !== "") flush(buffer);
1229
+ } catch (error) {
1230
+ const name = error && typeof error === "object" && "name" in error ? error.name : void 0;
1231
+ if (name !== "AbortError") throw error;
1232
+ } finally {
1233
+ try {
1234
+ reader.releaseLock?.();
1235
+ } catch {
1236
+ }
1237
+ }
1238
+ return events;
1239
+ }
1240
+
1241
+ // src/Classes/RESTAPI/partials/ApiRequestCreators.ts
1242
+ function isStreamResponse(value) {
1243
+ if (!getIsOnlyAnObject(value) || !value.ok) return false;
1244
+ const body = value.body;
1245
+ return typeof body === "object" && body !== null && "getReader" in body && typeof body.getReader === "function";
1246
+ }
1017
1247
  var PREFIX_OF_CLASS_UTILS = "createRequest_";
1018
1248
  var ApiRequestCreators = class extends ApiUtils_default {
1019
1249
  constructor(settings) {
@@ -1021,8 +1251,14 @@ var ApiRequestCreators = class extends ApiUtils_default {
1021
1251
  const { requestsCreators } = settings || {};
1022
1252
  if (getIsOnlyAnObject(requestsCreators)) addCustomMethods.call(this, requestsCreators, PREFIX_OF_CLASS_UTILS);
1023
1253
  }
1024
- //? При типе toJson пользовательский callback на вход получит тело ответа реализованное методом Response.json()
1025
- //? независимо от насторойки isGetBody
1254
+ /**
1255
+ * Крейтер типа `toJson`: пользовательский callback получит тело ответа (Response.json()).
1256
+ *
1257
+ * @param props - объект описания запроса.
1258
+ * @param variant - вариант обработки splitProperties.
1259
+ */
1260
+ // ? При типе toJson пользовательский callback на вход получит тело ответа реализованное методом Response.json()
1261
+ // ? независимо от насторойки isGetBody
1026
1262
  async createRequest_toJson(props, variant) {
1027
1263
  const safelyProps = omitKeys(props, ["getBodyAs"]);
1028
1264
  return this.splitProperties(
@@ -1031,15 +1267,21 @@ var ApiRequestCreators = class extends ApiUtils_default {
1031
1267
  isGetBody: false,
1032
1268
  callback: async (res) => {
1033
1269
  const output = await this.getResponseBody(res, "json");
1034
- return await (safelyProps.callback?.(output) ?? output);
1270
+ return await (props.callback?.(output) ?? output);
1035
1271
  }
1036
1272
  },
1037
1273
  variant
1038
1274
  );
1039
1275
  }
1040
- //? При типе toJsonAdvanced пользовательский callback на вход получит структуру { response, result },
1041
- //? где response - объект Response, result - тело ответа реализованное методом Response.json()
1042
- //? независимо от насторойки isGetBody
1276
+ /**
1277
+ * Крейтер типа `toJsonAdvanced`: callback получит структуру `{ response, result }`.
1278
+ *
1279
+ * @param props - объект описания запроса.
1280
+ * @param variant - вариант обработки splitProperties.
1281
+ */
1282
+ // ? При типе toJsonAdvanced пользовательский callback на вход получит структуру { response, result },
1283
+ // ? где response - объект Response, result - тело ответа реализованное методом Response.json()
1284
+ // ? независимо от насторойки isGetBody
1043
1285
  async createRequest_toJsonAdvanced(props, variant) {
1044
1286
  const safelyProps = omitKeys(props, ["getBodyAs"]);
1045
1287
  return this.splitProperties(
@@ -1051,14 +1293,20 @@ var ApiRequestCreators = class extends ApiUtils_default {
1051
1293
  response: res,
1052
1294
  result: await this.getResponseBody(await getResponseClone(res), "json")
1053
1295
  };
1054
- return await (safelyProps.callback?.(output) ?? output);
1296
+ return await (props.callback?.(output) ?? output);
1055
1297
  }
1056
1298
  },
1057
1299
  variant
1058
1300
  );
1059
1301
  }
1060
- //? При типе blob пользовательский callback на вход получит тело ответа реализованное методом Response.blob(),
1061
- //? независимо от насторойки isGetBody
1302
+ /**
1303
+ * Крейтер типа `blob`: callback получит тело ответа (Response.blob()).
1304
+ *
1305
+ * @param props - объект описания запроса.
1306
+ * @param variant - вариант обработки splitProperties.
1307
+ */
1308
+ // ? При типе blob пользовательский callback на вход получит тело ответа реализованное методом Response.blob(),
1309
+ // ? независимо от насторойки isGetBody
1062
1310
  async createRequest_blob(props, variant) {
1063
1311
  const safelyProps = omitKeys(props, ["getBodyAs"]);
1064
1312
  return this.splitProperties(
@@ -1067,14 +1315,67 @@ var ApiRequestCreators = class extends ApiUtils_default {
1067
1315
  isGetBody: false,
1068
1316
  callback: async (res) => {
1069
1317
  const output = await this.getResponseBody(await getResponseClone(res), "blob");
1070
- return await (safelyProps.callback?.(output) ?? output);
1318
+ return await (props.callback?.(output) ?? output);
1319
+ }
1320
+ },
1321
+ variant
1322
+ );
1323
+ }
1324
+ /**
1325
+ * Крейтер типа `sse`: обрабатывает ответ как поток Server-Sent Events (text/event-stream).
1326
+ *
1327
+ * Дополнительные пропы объекта описания запроса: `onEvent`, `onChunk`, `handlers`, `parseJson`.
1328
+ * По умолчанию добавляется заголовок `Accept: text/event-stream`. Метод doRequest резолвится
1329
+ * массивом всех событий ПОСЛЕ закрытия потока; отмена — методом `.abort()` возвращённого промиса.
1330
+ *
1331
+ * @param props - объект описания запроса (плюс onEvent/onChunk/handlers/parseJson).
1332
+ * @param variant - вариант обработки splitProperties.
1333
+ */
1334
+ // ? При типе sse запрос обрабатывается как поток Server-Sent Events (text/event-stream).
1335
+ // ? Дополнительные пропы объекта описания запроса:
1336
+ // ? - onEvent(event) — вызывается на каждое распарсенное событие { event, data, id, retry };
1337
+ // ? - onChunk(data, event) — вызывается на полезную нагрузку (поле data) каждого события;
1338
+ // ? - handlers — карта { имяСобытия: cb } для типизированной обработки по полю event
1339
+ // ? (например { delta, status, done }); cb получает (data, event);
1340
+ // ? - parseJson — если true, поле data каждого события прогоняется через JSON.parse.
1341
+ // ? По умолчанию добавляется заголовок Accept: text/event-stream (его можно переопределить через headers).
1342
+ // ? Пользовательский callback (если передан) на вход получит итоговый массив всех событий.
1343
+ // ? Метод doRequest резолвится массивом всех событий ПОСЛЕ закрытия потока;
1344
+ // ? отмена потока выполняется методом .abort() возвращённого промиса (через встроенный AbortController).
1345
+ async createRequest_sse(props, variant) {
1346
+ const safelyProps = omitKeys(props, ["getBodyAs", "onChunk", "onEvent", "handlers", "parseJson"]);
1347
+ const { onChunk, onEvent, handlers, parseJson } = props;
1348
+ const sseOptions = {
1349
+ onChunk: typeof onChunk === "function" ? (data, event) => onChunk(data, event) : void 0,
1350
+ onEvent: typeof onEvent === "function" ? (event) => onEvent(event) : void 0,
1351
+ parseJson: Boolean(parseJson),
1352
+ handlers: getIsOnlyAnObject(handlers) ? Object.keys(handlers).reduce((acc, key) => {
1353
+ const fn = handlers[key];
1354
+ acc[key] = typeof fn === "function" ? (data, event) => fn(data, event) : void 0;
1355
+ return acc;
1356
+ }, {}) : void 0
1357
+ };
1358
+ return this.splitProperties(
1359
+ {
1360
+ ...safelyProps,
1361
+ headers: { Accept: "text/event-stream", ...getIsOnlyAnObject(safelyProps.headers) ? safelyProps.headers : {} },
1362
+ isGetBody: false,
1363
+ callback: async (res) => {
1364
+ const output = isStreamResponse(res) ? await readSSE(res, sseOptions) : res;
1365
+ return await (props.callback?.(output) ?? output);
1071
1366
  }
1072
1367
  },
1073
1368
  variant
1074
1369
  );
1075
1370
  }
1076
- //? При типе testBadResponse пользовательский callback на вход получит объект Response в 401-м статусе
1077
- //? независимо независимо вообще ни от чего
1371
+ /**
1372
+ * Крейтер типа `testBadResponse`: callback получит синтетический Response со статусом 401.
1373
+ *
1374
+ * @param props - объект описания запроса.
1375
+ * @param variant - вариант обработки splitProperties.
1376
+ */
1377
+ // ? При типе testBadResponse пользовательский callback на вход получит объект Response в 401-м статусе
1378
+ // ? независимо независимо вообще ни от чего
1078
1379
  async createRequest_testBadResponse(props, variant) {
1079
1380
  return this.splitProperties(
1080
1381
  {
@@ -1094,17 +1395,33 @@ var ApiRequestCreators = class extends ApiUtils_default {
1094
1395
  variant
1095
1396
  );
1096
1397
  }
1097
- //? По умолчанию пользовательский callback на вход получит
1098
- //? - либо объект Response
1099
- //? - либо тело ответа (в случае isGetBody: 'first') полученное методом getResponseBody (смотри класс ApiUtils)
1398
+ /**
1399
+ * Крейтер по умолчанию: callback получит объект Response (или тело ответа при isGetBody: 'first').
1400
+ *
1401
+ * @param props - объект описания запроса.
1402
+ * @param variant - вариант обработки splitProperties.
1403
+ */
1404
+ // ? По умолчанию пользовательский callback на вход получит
1405
+ // ? - либо объект Response
1406
+ // ? - либо тело ответа (в случае isGetBody: 'first') полученное методом getResponseBody (смотри класс ApiUtils)
1100
1407
  async createRequest_default(props, variant) {
1101
1408
  return this.splitProperties(props, variant);
1102
1409
  }
1103
1410
  };
1104
1411
  var ApiRequestCreators_default = ApiRequestCreators;
1105
1412
 
1106
- // src/Classes/RESTAPI/partials/ApiBase.js
1413
+ // src/Classes/RESTAPI/partials/ApiBase.ts
1107
1414
  var ApiBase = class extends ApiRequestCreators_default {
1415
+ /** Текст ошибки невалидных данных запроса. */
1416
+ BAD_REQUEST_DATA_TEXT;
1417
+ /** Текст сообщения об успехе по умолчанию. */
1418
+ DEFAULT_SUCCESS_MESSAGE;
1419
+ /** Текст сообщения об ошибке по умолчанию. */
1420
+ DEFAULT_ERROR_MESSAGE;
1421
+ /** Текст сообщения об отсутствии сети. */
1422
+ NO_INET;
1423
+ /** Коды ответа, по которым запрос считается отклонённым. */
1424
+ REJECT_CODES;
1108
1425
  constructor(settings) {
1109
1426
  super(settings);
1110
1427
  const {
@@ -1133,49 +1450,76 @@ var ApiBase = class extends ApiRequestCreators_default {
1133
1450
  };
1134
1451
  var ApiBase_default = ApiBase;
1135
1452
 
1136
- // src/Classes/RESTAPI/partials/CredentialsProcessing.js
1453
+ // src/Classes/RESTAPI/partials/CredentialsProcessing.ts
1137
1454
  function decodeJWT(token) {
1138
1455
  try {
1139
- const payload = token.split(".")[1];
1140
- return JSON.parse(atob(payload));
1141
- } catch (e) {
1456
+ const payload = token.split(".")[1] ?? "";
1457
+ const decoded = JSON.parse(atob(payload));
1458
+ return getIsOnlyAnObject(decoded) ? decoded : null;
1459
+ } catch {
1142
1460
  return null;
1143
1461
  }
1144
1462
  }
1145
1463
  var CredentialsProcessing = class {
1464
+ /** Включён ли флоу рефреша токенов. */
1465
+ isUseRefreshTokensPropcessing = false;
1466
+ /** Учётные данные по умолчанию (пустые). */
1467
+ DEFAULT_CREDENTIALS = {};
1468
+ /** Внешний метод получения учётных данных. */
1469
+ getCredentialsByOuter;
1470
+ /** Внешний метод формирования заголовков авторизации по токену. */
1471
+ getHeadersForAuthorize;
1472
+ /** Необязательный преобразователь учётных данных после getCredentials. */
1473
+ importCredentials;
1474
+ /** Необязательный метод сохранения учётных данных (обязателен для флоу рефреша). */
1475
+ saveCredentials;
1476
+ /** Внешний метод рефреша учётных данных. */
1477
+ refreshCredentialsByOuter;
1478
+ /** Полный путь до эндпоинта рефреша токена. */
1479
+ REFRESH_TOKEN_PATH;
1480
+ /** Коды ответа, по которым триггерится попытка рефреша. */
1481
+ CODES_USING_THE_REFRESH_ATTEMPT;
1482
+ /** Ключ флага «рефреш начат» в localStorage. */
1483
+ REFRESH_TOKEN_FLAG = "refreshTokenFlag";
1484
+ /** Интервал опроса флага обновления токена, мс. */
1485
+ INTERVAL_FOR_CHECKING_TOKEN_UPDATE = 50;
1486
+ /** Колбэк, вызываемый после неудачного рефреша. */
1487
+ callbackAfterRejectRefresh;
1488
+ /** Доступ к верхнему контексту RESTAPI (навешивается из конструктора RESTAPI). */
1489
+ getRESTAPIContext;
1146
1490
  constructor(settings) {
1147
1491
  const { credentialsProcessing } = settings;
1148
1492
  const {
1149
- //? Для корректной работы установки токенов в запросы от API
1150
- //? нужно передавать методы getCredentials и getHeadersForAuthorize
1493
+ // ? Для корректной работы установки токенов в запросы от API
1494
+ // ? нужно передавать методы getCredentials и getHeadersForAuthorize
1151
1495
  getCredentials,
1152
1496
  getHeadersForAuthorize,
1153
- //? На вход получит токен, должна вернуть объект для коструктора Headers
1154
- //? Так же опционально можно передавать
1497
+ // ? На вход получит токен, должна вернуть объект для коструктора Headers
1498
+ // ? Так же опционально можно передавать
1155
1499
  importCredentials,
1156
- //? если он передается, то он будет применяться к выводу от вызова getCredentials
1500
+ // ? если он передается, то он будет применяться к выводу от вызова getCredentials
1157
1501
  saveCredentials,
1158
- //? можно будет найти в объекте credentialsProcessing, чтобы использовать кастомными методами
1159
- //! Либо вызов getCredentials, либо цепочка вызовов importCredentials(getCredentials())
1160
- //! должна возвращать требуемую классом структуру
1161
- //! Класс требует структуры
1162
- //! - { token }, если флоу рефреш токена НЕ используется
1163
- //! - { token, refreshToken, expires }, если используется флоу рефреш токена
1502
+ // ? можно будет найти в объекте credentialsProcessing, чтобы использовать кастомными методами
1503
+ // ! Либо вызов getCredentials, либо цепочка вызовов importCredentials(getCredentials())
1504
+ // ! должна возвращать требуемую классом структуру
1505
+ // ! Класс требует структуры
1506
+ // ! - { token }, если флоу рефреш токена НЕ используется
1507
+ // ! - { token, refreshToken, expires }, если используется флоу рефреш токена
1164
1508
  // *********
1165
- //? Подключает флоу рефреша токенов
1509
+ // ? Подключает флоу рефреша токенов
1166
1510
  isUseRefreshTokensPropcessing = false,
1167
- //! Для корректной работы флоу рефреша токенов передача метода saveCredentials становится ОБЯЗАТЕЛЬНОЙ
1168
- //? Так же для корректной работы флоу рефреша токенов нужно
1169
- //? - либо
1511
+ // ! Для корректной работы флоу рефреша токенов передача метода saveCredentials становится ОБЯЗАТЕЛЬНОЙ
1512
+ // ? Так же для корректной работы флоу рефреша токенов нужно
1513
+ // ? - либо
1170
1514
  refreshCredentials,
1171
- //! метод должен возвращать такую же структуру как и метод getCredentials,
1172
- //? на вход получит текущие креды, к выходу будет применен importCredentials, если этот метод передавался
1173
- //? - либо
1515
+ // ! метод должен возвращать такую же структуру как и метод getCredentials,
1516
+ // ? на вход получит текущие креды, к выходу будет применен importCredentials, если этот метод передавался
1517
+ // ? - либо
1174
1518
  REFRESH_TOKEN_PATH,
1175
- //! REFRESH_TOKEN_PATH передается ПОЛНОСТЬЮ (глобальная адресация)!
1519
+ // ! REFRESH_TOKEN_PATH передается ПОЛНОСТЬЮ (глобальная адресация)!
1176
1520
  CODES_USING_THE_REFRESH_ATTEMPT,
1177
- //? указывает по каким кодам ответа триггериться рефреш, массив чисел
1178
- //? Опционально
1521
+ // ? указывает по каким кодам ответа триггериться рефреш, массив чисел
1522
+ // ? Опционально
1179
1523
  REFRESH_TOKEN_FLAG = "refreshTokenFlag",
1180
1524
  INTERVAL_FOR_CHECKING_TOKEN_UPDATE = 50,
1181
1525
  // ms
@@ -1183,40 +1527,44 @@ var CredentialsProcessing = class {
1183
1527
  } = credentialsProcessing || {};
1184
1528
  if (typeof getCredentials !== "function") throw new Error("No getCredentials method [CredentialsProcessing]");
1185
1529
  if (typeof getHeadersForAuthorize !== "function") {
1186
- throw new Error("No getHeadersForAuthorize method [CredentialsProcessing]");
1530
+ throw new TypeError("No getHeadersForAuthorize method [CredentialsProcessing]");
1187
1531
  }
1188
1532
  if (importCredentials && typeof importCredentials !== "function") {
1189
1533
  throw new Error("Bad importCredentials method [CredentialsProcessing]");
1190
1534
  }
1191
- this.isUseRefreshTokensPropcessing = isUseRefreshTokensPropcessing;
1535
+ this.isUseRefreshTokensPropcessing = Boolean(isUseRefreshTokensPropcessing);
1192
1536
  this.DEFAULT_CREDENTIALS = {};
1193
- this.getCredentialsByOuter = getCredentials;
1194
- this.getHeadersForAuthorize = getHeadersForAuthorize;
1195
- this.importCredentials = importCredentials;
1537
+ this.getCredentialsByOuter = () => getCredentials();
1538
+ this.getHeadersForAuthorize = (token) => {
1539
+ const result = getHeadersForAuthorize(token);
1540
+ return getIsOnlyAnObject(result) ? result : {};
1541
+ };
1542
+ if (typeof importCredentials === "function") this.importCredentials = (cred) => importCredentials(cred);
1196
1543
  if (saveCredentials || isUseRefreshTokensPropcessing) {
1197
1544
  if (typeof saveCredentials !== "function") throw new Error("No saveCredentials method [CredentialsProcessing]");
1198
- else this.saveCredentials = saveCredentials;
1545
+ else this.saveCredentials = (cred) => saveCredentials(cred);
1199
1546
  }
1200
1547
  if (isUseRefreshTokensPropcessing) {
1201
- if (typeof refreshCredentials === "function") this.refreshCredentialsByOuter = refreshCredentials;
1202
- else {
1548
+ if (typeof refreshCredentials === "function") {
1549
+ this.refreshCredentialsByOuter = (cred) => refreshCredentials(cred);
1550
+ } else {
1203
1551
  if (typeof this.refreshCredentialsByOuter === "function" && typeof REFRESH_TOKEN_PATH !== "string") {
1204
- throw new Error("No REFRESH_TOKEN_PATH [CredentialsProcessing]");
1552
+ throw new TypeError("No REFRESH_TOKEN_PATH [CredentialsProcessing]");
1205
1553
  }
1206
- this.REFRESH_TOKEN_PATH = REFRESH_TOKEN_PATH;
1554
+ this.REFRESH_TOKEN_PATH = typeof REFRESH_TOKEN_PATH === "string" ? REFRESH_TOKEN_PATH : void 0;
1207
1555
  }
1208
1556
  if (!Array.isArray(CODES_USING_THE_REFRESH_ATTEMPT)) {
1209
- throw new Error("No CODES_USING_THE_REFRESH_ATTEMPT [CredentialsProcessing]");
1557
+ throw new TypeError("No CODES_USING_THE_REFRESH_ATTEMPT [CredentialsProcessing]");
1210
1558
  }
1211
1559
  if (!CODES_USING_THE_REFRESH_ATTEMPT.every((i) => typeof i === "number")) {
1212
1560
  throw new Error("Invalid format of CODES_USING_THE_REFRESH_ATTEMPT elements [CredentialsProcessing]");
1213
1561
  }
1214
1562
  if (typeof REFRESH_TOKEN_FLAG !== "string") throw new Error("Bad REFRESH_TOKEN_FLAG [CredentialsProcessing]");
1215
1563
  if (typeof INTERVAL_FOR_CHECKING_TOKEN_UPDATE !== "number") {
1216
- throw new Error("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1564
+ throw new TypeError("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1217
1565
  }
1218
1566
  if (typeof INTERVAL_FOR_CHECKING_TOKEN_UPDATE !== "number") {
1219
- throw new Error("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1567
+ throw new TypeError("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1220
1568
  }
1221
1569
  if (callbackAfterRejectRefresh && typeof callbackAfterRejectRefresh !== "function") {
1222
1570
  throw new Error("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
@@ -1224,23 +1572,33 @@ var CredentialsProcessing = class {
1224
1572
  this.CODES_USING_THE_REFRESH_ATTEMPT = CODES_USING_THE_REFRESH_ATTEMPT;
1225
1573
  this.REFRESH_TOKEN_FLAG = REFRESH_TOKEN_FLAG;
1226
1574
  this.INTERVAL_FOR_CHECKING_TOKEN_UPDATE = INTERVAL_FOR_CHECKING_TOKEN_UPDATE;
1227
- if (callbackAfterRejectRefresh) this.callbackAfterRejectRefresh = callbackAfterRejectRefresh;
1575
+ if (typeof callbackAfterRejectRefresh === "function") this.callbackAfterRejectRefresh = () => callbackAfterRejectRefresh();
1228
1576
  }
1229
1577
  }
1578
+ /** Возвращает значение флага «рефреш начат» из localStorage. */
1230
1579
  getIsTokenStartRefresh() {
1231
1580
  return localStorage.getItem(this.REFRESH_TOKEN_FLAG);
1232
1581
  }
1582
+ /** Выставляет флаг «рефреш начат» в localStorage. */
1233
1583
  setIsTokenStartRefresh() {
1234
- localStorage.setItem(this.REFRESH_TOKEN_FLAG, true);
1584
+ localStorage.setItem(this.REFRESH_TOKEN_FLAG, String(true));
1235
1585
  }
1586
+ /** Снимает флаг «рефреш начат» из localStorage. */
1236
1587
  removeIsTokenStartRefresh() {
1237
1588
  localStorage.removeItem(this.REFRESH_TOKEN_FLAG);
1238
1589
  }
1590
+ /**
1591
+ * Возвращает текущие учётные данные (с учётом importCredentials и проверки истечения JWT).
1592
+ *
1593
+ * @param isCatchCallbackProcess - флаг процесса обработки ошибки (отключает проверку истечения).
1594
+ * @param callback - необязательный колбэк, получающий итоговые учётные данные.
1595
+ * @returns Промис с учётными данными.
1596
+ */
1239
1597
  async getCredentials(isCatchCallbackProcess, callback) {
1240
1598
  let credentials = await this.getCredentialsByOuter();
1241
1599
  if (typeof this.importCredentials === "function") credentials = await this.importCredentials(credentials);
1242
- if (!getIsOnlyAnObject(credentials)) credentials = {};
1243
- const token = credentials.token || null;
1600
+ const credObj = getIsOnlyAnObject(credentials) ? credentials : {};
1601
+ const token = credObj.token || null;
1244
1602
  if (token && !isCatchCallbackProcess) {
1245
1603
  let decoded;
1246
1604
  try {
@@ -1249,11 +1607,18 @@ var CredentialsProcessing = class {
1249
1607
  decoded = null;
1250
1608
  }
1251
1609
  const currentTime = Date.now() / 1e3;
1252
- if (decoded !== null && Number(decoded.exp) < currentTime) credentials = { ...credentials, isNeedRefresh: true };
1610
+ if (decoded !== null && Number(decoded.exp) < currentTime) credObj.isNeedRefresh = true;
1253
1611
  }
1254
- if (callback) await callback({ ...credentials, isCatchCallbackProcess });
1255
- return { ...credentials, isCatchCallbackProcess };
1612
+ if (callback) await callback({ ...credObj, isCatchCallbackProcess });
1613
+ return { ...credObj, isCatchCallbackProcess };
1256
1614
  }
1615
+ /**
1616
+ * Выполняет рефреш учётных данных (внешним методом либо дефолтным OAuth-флоу).
1617
+ *
1618
+ * @param currentCredentials - текущие учётные данные.
1619
+ * @param callback - необязательный колбэк сохранения новых учётных данных.
1620
+ * @returns Промис с новыми учётными данными.
1621
+ */
1257
1622
  async refreshCredentials(currentCredentials, callback) {
1258
1623
  const CONTEXT = this;
1259
1624
  async function finalize(cred) {
@@ -1266,11 +1631,10 @@ var CredentialsProcessing = class {
1266
1631
  if (!currentCredentials?.token || !currentCredentials?.refreshToken) return finalize(CONTEXT.DEFAULT_CREDENTIALS);
1267
1632
  async function refreshCredentialsByDefault() {
1268
1633
  const { token, refreshToken } = currentCredentials;
1269
- const headers = new Headers();
1270
- headers.append(...Object.entries(CONTEXT.getHeadersForAuthorize(token)));
1634
+ const headers = new Headers(Object.entries(CONTEXT.getHeadersForAuthorize(token || "")).map(([key, value]) => [key, `${value}`]));
1271
1635
  const body = new FormData();
1272
1636
  body.append("grant_type", "refresh_token");
1273
- body.append("refresh_token", refreshToken);
1637
+ body.append("refresh_token", refreshToken || "");
1274
1638
  body.append("client_id", "oauth");
1275
1639
  body.append("client_secret", "secret");
1276
1640
  body.append("access_type", "offline");
@@ -1283,8 +1647,14 @@ var CredentialsProcessing = class {
1283
1647
  });
1284
1648
  }
1285
1649
  const newCredentials = typeof CONTEXT.refreshCredentialsByOuter === "function" ? await CONTEXT.refreshCredentialsByOuter(currentCredentials) : await refreshCredentialsByDefault();
1286
- return finalize(newCredentials);
1650
+ return finalize(getIsOnlyAnObject(newCredentials) ? newCredentials : CONTEXT.DEFAULT_CREDENTIALS);
1287
1651
  }
1652
+ /**
1653
+ * Ожидает завершения рефреша токена (или запускает его флаг при необходимости).
1654
+ *
1655
+ * @param isNeedRefresh - выставить ли флаг «рефреш начат» при отсутствии активного рефреша.
1656
+ * @returns Промис, который резолвится по завершении ожидания.
1657
+ */
1288
1658
  async waitRefresh(isNeedRefresh) {
1289
1659
  return new Promise((resolve) => {
1290
1660
  if (!this.getIsTokenStartRefresh()) {
@@ -1300,10 +1670,16 @@ var CredentialsProcessing = class {
1300
1670
  }
1301
1671
  });
1302
1672
  }
1673
+ /**
1674
+ * Обрабатывает учётные данные: при необходимости рефрешит токен и возвращает актуальные данные.
1675
+ *
1676
+ * @param cred - текущие учётные данные.
1677
+ * @returns Промис с актуальными учётными данными (с флагом isRefreshFailed при неудаче).
1678
+ */
1303
1679
  async processCredentials(cred) {
1304
1680
  if (!cred.isNeedRefresh && !cred.isCatchCallbackProcess) return cred;
1305
1681
  const CONTEXT = this;
1306
- return CONTEXT.refreshCredentials(cred, (response) => CONTEXT.saveCredentials(response)).then(() => {
1682
+ return CONTEXT.refreshCredentials(cred, (response) => CONTEXT.saveCredentials?.(response)).then(() => {
1307
1683
  return new Promise((resolve) => {
1308
1684
  setTimeout(async () => {
1309
1685
  const newCredentials = await CONTEXT.getCredentials();
@@ -1321,11 +1697,15 @@ var CredentialsProcessing = class {
1321
1697
  };
1322
1698
  var CredentialsProcessing_default = CredentialsProcessing;
1323
1699
 
1324
- // src/Classes/RESTAPI/index.js
1700
+ // src/Classes/RESTAPI/index.ts
1325
1701
  function returnTheContext() {
1326
1702
  return this;
1327
1703
  }
1328
1704
  var RESTAPI = class extends ApiBase_default {
1705
+ /** Функция показа сообщений пользователю (или null, если информирование отключено). */
1706
+ sendMessage = null;
1707
+ /** Обработчик учётных данных (создаётся при наличии настройки credentialsProcessing). */
1708
+ credentialsProcessing;
1329
1709
  constructor(settings) {
1330
1710
  super(settings);
1331
1711
  const { sendMessage, credentialsProcessing } = settings || {};
@@ -1335,7 +1715,14 @@ var RESTAPI = class extends ApiBase_default {
1335
1715
  this.credentialsProcessing.getRESTAPIContext = returnTheContext.bind(this);
1336
1716
  }
1337
1717
  }
1338
- //! Основной (базовый) метод API, мультизапросы
1718
+ /**
1719
+ * Основной (базовый) метод API: выполняет мультизапрос (или одиночный запрос).
1720
+ *
1721
+ * @param inputRequests - путь, объект описания запроса или их массив.
1722
+ * @param settings - общие настройки запроса (формат ответа, тосты, сообщения и т.п.).
1723
+ * @returns Промис с результатом (форма зависит от isResponseAsObject).
1724
+ */
1725
+ // ! Основной (базовый) метод API, мультизапросы
1339
1726
  async doRequest(inputRequests, settings) {
1340
1727
  if (typeof inputRequests !== "string" && typeof inputRequests !== "object") {
1341
1728
  return Promise.reject(new Error(this.BAD_REQUEST_DATA_TEXT));
@@ -1359,24 +1746,29 @@ var RESTAPI = class extends ApiBase_default {
1359
1746
  throw new Error("It is impossible to make a request!");
1360
1747
  }
1361
1748
  instance.setIsResponseAsObject(isResponseAsObject ?? true);
1362
- if (callback) instance.setCallback(callback);
1749
+ if (typeof callback === "function") instance.setCallback(callback);
1363
1750
  function getRequests() {
1364
1751
  let output;
1365
1752
  if (typeof inputRequests === "string") output = [{ path: inputRequests }];
1366
1753
  else output = Array.isArray(inputRequests) ? inputRequests : [inputRequests];
1367
1754
  function getCallback(item, mesageOptions) {
1368
- const { getBodyAs } = item;
1755
+ const getBodyAs = typeof item.getBodyAs === "string" ? item.getBodyAs : void 0;
1369
1756
  const finalIsGetBody = typeof item.isGetBody === "boolean" || typeof item.isGetBody === "string" ? item.isGetBody : isGetBody;
1370
1757
  const finalIsGetBodyFirst = finalIsGetBody === "first";
1371
- const checkResponseCallback = finalIsGetBodyFirst ? async (res, mesageOptions2) => API_CONTEXT.getResponseBody(await API_CONTEXT.checkResponseCode(res, mesageOptions2), getBodyAs) : async (res, mesageOptions2) => API_CONTEXT.checkResponseCode(res, mesageOptions2);
1372
- const callback2 = item.callback ? async (res) => item.callback(await checkResponseCallback(res, mesageOptions)) : async (res) => checkResponseCallback(res, mesageOptions);
1373
- return finalIsGetBody && !finalIsGetBodyFirst ? async (res) => API_CONTEXT.getResponseBody(await callback2(res), getBodyAs) : callback2;
1758
+ const checkResponseCallback = finalIsGetBodyFirst ? async (res, options) => API_CONTEXT.getResponseBody(await API_CONTEXT.checkResponseCode(res, options), getBodyAs) : async (res, options) => API_CONTEXT.checkResponseCode(res, options);
1759
+ const itemCallback = item.callback;
1760
+ const callbackFn = typeof itemCallback === "function" ? async (res) => itemCallback(await checkResponseCallback(res, mesageOptions)) : async (res) => checkResponseCallback(res, mesageOptions);
1761
+ return finalIsGetBody && !finalIsGetBodyFirst ? async (res) => API_CONTEXT.getResponseBody(await callbackFn(res), getBodyAs) : callbackFn;
1374
1762
  }
1375
1763
  async function getRequestItem(item, idx) {
1376
- const { type, ...partialRestFirst } = item;
1764
+ const itemObj = getIsOnlyAnObject(item) ? item : { path: item };
1765
+ const { type, ...partialRestFirst } = itemObj;
1377
1766
  const itemAfterRequestCreating = await (async () => {
1378
- const key = `createRequest_${type ?? "default"}`;
1379
- return key in API_CONTEXT ? API_CONTEXT[key](partialRestFirst, "doRequestMapping") : API_CONTEXT.createRequest_default(partialRestFirst, "doRequestMapping");
1767
+ const key = `createRequest_${typeof type === "string" ? type : "default"}`;
1768
+ const creator = key in API_CONTEXT ? API_CONTEXT[key] : void 0;
1769
+ const result = typeof creator === "function" ? creator.call(API_CONTEXT, partialRestFirst, "doRequestMapping") : API_CONTEXT.createRequest_default(partialRestFirst, "doRequestMapping");
1770
+ const awaited = await result;
1771
+ return getIsOnlyAnObject(awaited) ? awaited : {};
1380
1772
  })();
1381
1773
  const { fullPath, api, path, query, queryParameters, ...partialRestSecond } = itemAfterRequestCreating;
1382
1774
  const {
@@ -1392,23 +1784,25 @@ var RESTAPI = class extends ApiBase_default {
1392
1784
  isNoToast,
1393
1785
  ...rest
1394
1786
  } = partialRestSecond;
1787
+ const successMessagesArr = Array.isArray(successMessages) ? successMessages : void 0;
1788
+ const errorMessagesArr = Array.isArray(errorMessages) ? errorMessages : void 0;
1395
1789
  const useSuccessMessageFlag = Boolean(
1396
- successMess || commonSuccessMessage || successMessages?.[idx] || CSMfromSettings || isToastResult || isToastFromSettings
1790
+ successMess || commonSuccessMessage || successMessagesArr?.[idx] || CSMfromSettings || isToastResult || isToastFromSettings
1397
1791
  );
1398
1792
  const isUseSuccessToast = useSuccessMessageFlag && !isNoToast && !isNoToastFromSettings && !isNoToastSuccess && !isNTSFromSettings;
1399
1793
  const isUseErrorToast = !isNoToast && !isNoToastFromSettings && !isNoToastError && !isNTEFromSettings;
1400
1794
  const mesageOptions = {
1401
- successMess: successMess || commonSuccessMessage || successMessages?.[idx] || CSMfromSettings,
1795
+ successMess: successMess || commonSuccessMessage || successMessagesArr?.[idx] || CSMfromSettings,
1402
1796
  successMessageType: successMessageType || SMTfromSettings,
1403
- errorMess: errorMess || commonErrorMessage || errorMessages?.[idx] || CEMfromSettings,
1797
+ errorMess: errorMess || commonErrorMessage || errorMessagesArr?.[idx] || CEMfromSettings,
1404
1798
  isUseSuccessToast,
1405
1799
  isUseErrorToast,
1406
1800
  toastOptions: toastOptions || TOFomSettings
1407
1801
  };
1408
1802
  return {
1409
1803
  ...rest,
1410
- path: `${fullPath || await API_CONTEXT.getRootPath(api) + (path || "")}`,
1411
- //? Запускаем самовызывающуюся асинхронную ф-ю, ждем резолва промиса от нее
1804
+ path: `${fullPath || await API_CONTEXT.getRootPath() + (typeof path === "string" ? path : "")}`,
1805
+ // ? Запускаем самовызывающуюся асинхронную ф-ю, ждем резолва промиса от нее
1412
1806
  queryParameters: await (async () => {
1413
1807
  const queryParams = query || queryParameters || "";
1414
1808
  const preparedQueryParams = await API_CONTEXT.processQueryParams(queryParams);
@@ -1418,16 +1812,25 @@ var RESTAPI = class extends ApiBase_default {
1418
1812
  callback: getCallback(itemAfterRequestCreating, mesageOptions)
1419
1813
  };
1420
1814
  }
1421
- return output?.map((item, idx) => getRequestItem(item, idx));
1815
+ return output.map((item, idx) => getRequestItem(item, idx));
1422
1816
  }
1423
1817
  return instance.request(await Promise.all(getRequests()));
1424
1818
  }
1425
- //! Метод API для одиночных запросов
1819
+ /**
1820
+ * Метод API для одиночных запросов: применяет крейтер по `type` и делегирует в {@link RESTAPI.doRequest}.
1821
+ *
1822
+ * @param requestSettings - объект описания одиночного запроса (с необязательным `type`).
1823
+ * @returns Промис с результатом запроса.
1824
+ */
1825
+ // ! Метод API для одиночных запросов
1426
1826
  async doMonoRequest(requestSettings) {
1427
1827
  if (!getIsOnlyAnObject(requestSettings)) throw new Error(`${this.BAD_REQUEST_DATA_TEXT} [RESTAPI.doMonoRequest]`);
1428
1828
  const { type, ...requestSettingsRest } = requestSettings;
1429
- const doRequestArgs = type && this[`createRequest_${type}`] ? [...await this[`createRequest_${type}`](requestSettingsRest)] : [...await this.createRequest_default(requestSettingsRest)];
1430
- return this.doRequest(...doRequestArgs);
1829
+ const key = `createRequest_${typeof type === "string" ? type : ""}`;
1830
+ const creator = type && key in this ? this[key] : void 0;
1831
+ const created = typeof creator === "function" ? await creator.call(this, requestSettingsRest) : await this.createRequest_default(requestSettingsRest);
1832
+ const doRequestArgs = Array.isArray(created) ? created : [created];
1833
+ return this.doRequest(doRequestArgs[0], doRequestArgs[1]);
1431
1834
  }
1432
1835
  };
1433
1836
  var RESTAPI_default = RESTAPI;
@@ -23053,17 +23456,6 @@ export {
23053
23456
  uuid,
23054
23457
  voidFn
23055
23458
  };
23056
- //! При получении экземпляра, если sendMessage не является ф-ей,
23057
- //! то это воспринимается как отключение шага информирования об ошибке запроса как такового
23058
- //! Планируемая структура { headers, queryParameters, options }, где
23059
- //! - headers и options - объекты,
23060
- //! - queryParameters - строка, массив или объект
23061
- //! ВНИМАНИЕ! Данный механизм рефреша принят на проекте finturfreactfrontend (админка)
23062
- //! На кабинете он ТОЧНО НЕ ТАКОЙ
23063
- //! currentCredentials передаются в формате класса! ({ token, refreshToken, expires })
23064
- //! Наличие credentialsProcessing подключает ДОБАВЛЕНИЕ ТОКЕНОВ В ЗАПРОСЫ,
23065
- //! НО по умолчанию НЕ добавляет флоу рефреша токенов
23066
- //! (флоу рефреша подключается пропой isUseRefreshTokensPropcessing из credentialsProcessing)
23067
23459
  //! Важно! Если придет велью с количеством дробных разрядов БОЛЬШИМ
23068
23460
  //! чем указано в quantity - округлит по правилам округления
23069
23461
  //! чем указано в decimalPlaces - округлит по правилам округления