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/classes.js CHANGED
@@ -393,7 +393,11 @@ var AnimatedHandler = class {
393
393
  };
394
394
  var AnimatedHandler_default = AnimatedHandler;
395
395
 
396
- // src/Classes/RESTAPI/partials/AbortableFetch.js
396
+ // src/Classes/RESTAPI/partials/AbortableFetch.ts
397
+ var HTTP_METHODS = ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"];
398
+ function isHttpMethod(value) {
399
+ return HTTP_METHODS.includes(value);
400
+ }
397
401
  var RESPONSE_AS_OBJECT_ALWAYS_VALUE2 = "always";
398
402
  var AbortableFetch2 = class {
399
403
  #pathPrefix = null;
@@ -406,6 +410,8 @@ var AbortableFetch2 = class {
406
410
  #catchCallback = null;
407
411
  #everyPromiseCallback = null;
408
412
  #isResponseAsObject = false;
413
+ // ? Последний вход request() — используется repeatRequest() для повторного запроса той же пачки.
414
+ requestInput = [];
409
415
  constructor(input) {
410
416
  if (input && !getIsOnlyAnObject(input)) throw new Error("Not valid input value!");
411
417
  this.getPathPrefix = this.getPathPrefix.bind(this);
@@ -436,20 +442,30 @@ var AbortableFetch2 = class {
436
442
  this.repeatRequest = this.repeatRequest.bind(this);
437
443
  this.setProps(input || {});
438
444
  }
445
+ /**
446
+ * Выполняет один или несколько HTTP-запросов (нативный fetch) с возможностью отмены.
447
+ *
448
+ * Метод `abort()` навешивается на прототип возвращаемого промиса (как в исходной реализации),
449
+ * что позволяет отменить всю цепочку запросов вызовом `abort()` на возвращённом промисе.
450
+ *
451
+ * @param props - путь, объект описания запроса или их массив.
452
+ * @returns Промис с результатом (форма зависит от isResponseAsObject); на прототипе доступен `abort()`.
453
+ */
439
454
  async request(props) {
440
455
  if (!getIsOnlyAnObject(props) && !Array.isArray(props) && typeof props !== "string") throw new Error("Not valid props value!");
441
- const stringifyBody = (b) => b?.constructor === FormData ? b : JSON.stringify(b);
456
+ const stringifyBody = (b) => b instanceof FormData ? b : JSON.stringify(b);
442
457
  this.requestInput = props;
443
458
  const requests = getRequestsArray.call(this, props);
444
459
  const ABORTABLE_FETCH_CONTEXT = this;
445
460
  const abortController = new AbortController();
446
461
  const addProps = (response, request) => {
447
- response.request = request;
448
- if (ABORTABLE_FETCH_CONTEXT.#isResponseAsObject) response.name = getIsOnlyAnObject(request) ? request.name || "" : "";
449
- return response;
462
+ return Object.assign(response, {
463
+ request,
464
+ ...ABORTABLE_FETCH_CONTEXT.#isResponseAsObject ? { name: getIsOnlyAnObject(request) ? request.name || "" : "" } : {}
465
+ });
450
466
  };
451
- let externalRequest = Promise.all(
452
- requests.map(async (item) => {
467
+ const externalRequest = Promise.all(
468
+ requests.map((item) => {
453
469
  const safelyQuery = item.path.includes("?") ? `&${item.queryParameters.replace(/\?/g, "")}` : item.queryParameters;
454
470
  const internalRequest = fetch(`${item.pathPrefix}${item.path}${safelyQuery}`, {
455
471
  ...item.options,
@@ -460,12 +476,15 @@ var AbortableFetch2 = class {
460
476
  }).then(async (response) => addProps(response, item)).catch(async (response) => {
461
477
  if (response instanceof Response) return Promise.resolve(addProps(response, item));
462
478
  return Promise.resolve(
463
- addProps({
464
- ok: false,
465
- status: 0,
466
- statusText: response,
467
- request: item
468
- })
479
+ addProps(
480
+ {
481
+ ok: false,
482
+ status: 0,
483
+ statusText: response,
484
+ request: item
485
+ },
486
+ item
487
+ )
469
488
  );
470
489
  }).then(async (res) => {
471
490
  return typeof ABORTABLE_FETCH_CONTEXT.#everyPromiseCallback === "function" && !item.isSkipEveryPromiseCallback ? await ABORTABLE_FETCH_CONTEXT.#everyPromiseCallback(res) : res;
@@ -474,7 +493,8 @@ var AbortableFetch2 = class {
474
493
  }).then(async (res) => {
475
494
  return { request: item, response: res, ...item.name ? { name: item.name } : {} };
476
495
  });
477
- internalRequest.__proto__.abort = () => abortController.abort();
496
+ const internalProto = Object.getPrototypeOf(internalRequest);
497
+ internalProto.abort = () => abortController.abort();
478
498
  return internalRequest;
479
499
  })
480
500
  ).then(async (resArr) => {
@@ -482,16 +502,17 @@ var AbortableFetch2 = class {
482
502
  return ABORTABLE_FETCH_CONTEXT.#isResponseAsObject ? {} : [];
483
503
  }
484
504
  if (ABORTABLE_FETCH_CONTEXT.#isResponseAsObject === RESPONSE_AS_OBJECT_ALWAYS_VALUE2) {
485
- return resArr.reduce((ac, item) => ({ ...ac, [item.name]: item.response }), {});
505
+ return resArr.reduce((ac, item) => ({ ...ac, [String(item.name)]: item.response }), {});
486
506
  }
487
507
  if (resArr.length === 1) return resArr[0].response;
488
- return ABORTABLE_FETCH_CONTEXT.#isResponseAsObject === true ? resArr.reduce((ac, item) => ({ ...ac, [item.name]: item.response }), {}) : resArr.map((item) => item.response);
508
+ return ABORTABLE_FETCH_CONTEXT.#isResponseAsObject === true ? resArr.reduce((ac, item) => ({ ...ac, [String(item.name)]: item.response }), {}) : resArr.map((item) => item.response);
489
509
  }).then(async (res) => {
490
510
  return typeof ABORTABLE_FETCH_CONTEXT.#callback === "function" ? await ABORTABLE_FETCH_CONTEXT.#callback(res) : res;
491
511
  }).catch(async (res) => {
492
512
  return typeof ABORTABLE_FETCH_CONTEXT.#catchCallback === "function" ? await ABORTABLE_FETCH_CONTEXT.#catchCallback(res) : res;
493
513
  });
494
- externalRequest.__proto__.abort = () => abortController.abort();
514
+ const externalProto = Object.getPrototypeOf(externalRequest);
515
+ externalProto.abort = () => abortController.abort();
495
516
  return externalRequest;
496
517
  function getRequestsArray(input) {
497
518
  const requestsArray = (() => {
@@ -516,15 +537,17 @@ var AbortableFetch2 = class {
516
537
  callback: omitCallback,
517
538
  mergeProps: omitMergeProps,
518
539
  ...optionsRest
519
- } = options || {};
540
+ } = getIsOnlyAnObject(options) ? options : {};
541
+ const localMethod = typeof method === "string" && isHttpMethod(method) ? method : null;
542
+ const localCallback = typeof callback === "function" ? (res) => callback(res) : void 0;
520
543
  return [
521
544
  ...ac,
522
545
  {
523
546
  path,
524
547
  pathPrefix: getMergeProps("pathPrefix") === "onlyLocal" || isNoPathPrefix ? "" : this.#pathPrefix || "",
525
548
  method: (() => {
526
- if (getMergeProps("method") === "onlyLocal") return method || "GET";
527
- return getMergeProps("method") === "onlyGlobal" ? this.#method || "GET" : method || this.#method || "GET";
549
+ if (getMergeProps("method") === "onlyLocal") return localMethod || "GET";
550
+ return getMergeProps("method") === "onlyGlobal" ? this.#method || "GET" : localMethod || this.#method || "GET";
528
551
  })(),
529
552
  queryParameters: (() => {
530
553
  if ((getMergeProps("queryParameters") ?? getMergeProps("query")) === "onlyLocal") {
@@ -533,31 +556,34 @@ var AbortableFetch2 = class {
533
556
  return (getMergeProps("queryParameters") ?? getMergeProps("query")) === "onlyGlobal" ? this.getQueryString(this.getQueryArray(this.#queryParameters)) : this.getQueryString([...this.getQueryArray(this.#queryParameters), ...this.getQueryArray(queryParameters)]);
534
557
  })(),
535
558
  headers: (() => {
536
- if (getMergeProps("headers") === "onlyLocal") return this.getHeadersObj(headers || {});
559
+ if (getMergeProps("headers") === "onlyLocal") return this.getHeadersObj(getIsOnlyAnObject(headers) ? headers : {});
537
560
  return getMergeProps("headers") === "onlyGlobal" ? this.getHeadersObj({ ...this.#headers || {} }) : this.getHeadersObj({
538
561
  ...this.#headers || {},
539
- ...headers || {}
562
+ ...getIsOnlyAnObject(headers) ? headers : {}
540
563
  });
541
564
  })(),
542
565
  body: (() => {
543
566
  if (getMergeProps("body") === "onlyLocal") return body || null;
544
567
  if (getMergeProps("body") === "onlyGlobal") return this.#body || null;
545
568
  if (body && this.#body && typeof body === typeof this.#body && typeof body === "object") {
546
- return Array.isArray(body) ? [...this.#body, ...body] : { ...this.#body, ...body };
547
- } else return body || this.#body || null;
569
+ return Array.isArray(body) ? [...Array.isArray(this.#body) ? this.#body : [], ...body] : { ...getIsOnlyAnObject(this.#body) ? this.#body : {}, ...getIsOnlyAnObject(body) ? body : {} };
570
+ } else {
571
+ return body || this.#body || null;
572
+ }
548
573
  })(),
549
574
  options: (() => {
550
- if (getMergeProps("options") === "onlyLocal") return { ...optionsRest || {} };
551
- return getMergeProps("options") === "onlyGlobal" ? { ...this.#options || {} } : { ...this.#options || {}, ...optionsRest || {} };
575
+ if (getMergeProps("options") === "onlyLocal") return { ...optionsRest };
576
+ return getMergeProps("options") === "onlyGlobal" ? { ...this.#options || {} } : { ...this.#options || {}, ...optionsRest };
552
577
  })(),
553
- callback,
554
- isSkipEveryPromiseCallback,
578
+ callback: localCallback,
579
+ isSkipEveryPromiseCallback: Boolean(isSkipEveryPromiseCallback),
555
580
  ...this.getIsResponseAsObject() ? { name: name && typeof name === "string" ? name : index } : {}
556
581
  }
557
582
  ];
558
583
  }, []);
559
584
  }
560
585
  }
586
+ /** Повторяет последний выполненный запрос (ту же пачку). */
561
587
  repeatRequest() {
562
588
  return this.request(this.requestInput);
563
589
  }
@@ -573,19 +599,23 @@ var AbortableFetch2 = class {
573
599
  return this.#method;
574
600
  }
575
601
  setMethod(value) {
576
- const methods = ["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"];
577
- if (value && !methods.includes(value)) throw new Error("Not valid method value!");
602
+ if (value && !isHttpMethod(value)) throw new Error("Not valid method value!");
578
603
  this.#method = value || null;
579
604
  }
580
605
  getQueryParameters() {
581
606
  return this.#queryParameters;
582
607
  }
583
608
  getQueryArray(value) {
584
- if (typeof value === "string") return (value[0] === "?" ? value.slice(1) : value).split("&");
585
- else if (Array.isArray(value)) return value;
586
- else if (typeof value === "object" && value !== null) {
587
- return Object.keys(value).filter((key) => Boolean(key) && Boolean(value[key])).map((key) => `${key}=${value[key]}`);
588
- } else return [];
609
+ if (typeof value === "string") {
610
+ return (value[0] === "?" ? value.slice(1) : value).split("&");
611
+ } else if (Array.isArray(value)) {
612
+ return value.map((item) => `${item}`);
613
+ } else if (typeof value === "object" && value !== null) {
614
+ const record = getIsOnlyAnObject(value) ? value : {};
615
+ return Object.keys(record).filter((key) => Boolean(key) && Boolean(record[key])).map((key) => `${key}=${record[key]}`);
616
+ } else {
617
+ return [];
618
+ }
589
619
  }
590
620
  getQueryString(value) {
591
621
  if (!value) return "";
@@ -604,7 +634,7 @@ var AbortableFetch2 = class {
604
634
  if (!obj) return headers;
605
635
  if (typeof obj !== "object" || Array.isArray(obj)) throw new Error("Not valid headers value!");
606
636
  Object.keys(obj).forEach((key) => {
607
- headers.append(key, obj[key]);
637
+ headers.append(key, `${obj[key]}`);
608
638
  });
609
639
  return headers;
610
640
  }
@@ -680,39 +710,64 @@ var AbortableFetch2 = class {
680
710
  // isAnywayRunCallback,
681
711
  isResponseAsObject
682
712
  } = input;
683
- if (pathPrefix) this.setPathPrefix(pathPrefix);
684
- if (method) this.setMethod(method);
713
+ if (pathPrefix) this.setPathPrefix(typeof pathPrefix === "string" ? pathPrefix : null);
714
+ if (method) this.setMethod(typeof method === "string" && isHttpMethod(method) ? method : null);
685
715
  if (queryParameters) this.setQueryParameters(this.getQueryArray(queryParameters));
686
- if (headers) this.setHeaders(headers);
716
+ if (headers) this.setHeaders(getIsOnlyAnObject(headers) ? headers : null);
687
717
  if (body) this.setBody(body);
688
- if (options) this.setOptions(options);
689
- if (callback) this.setCallback(callback);
690
- if (catchCallback) this.setCatchCallback(catchCallback);
691
- if (everyPromiseCallback) this.setEveryPromiseCallback(everyPromiseCallback);
718
+ if (options) this.setOptions(getIsOnlyAnObject(options) ? options : null);
719
+ if (callback && typeof callback === "function") {
720
+ const fn = callback;
721
+ this.setCallback(function wrappedCallback(response) {
722
+ return fn.call(this, response);
723
+ });
724
+ }
725
+ if (catchCallback && typeof catchCallback === "function") {
726
+ const fn = catchCallback;
727
+ this.setCatchCallback(function wrappedCatchCallback(response) {
728
+ return fn.call(this, response);
729
+ });
730
+ }
731
+ if (everyPromiseCallback && typeof everyPromiseCallback === "function") {
732
+ const fn = everyPromiseCallback;
733
+ this.setEveryPromiseCallback(function wrappedEveryPromiseCallback(response) {
734
+ return fn.call(this, response);
735
+ });
736
+ }
692
737
  if (isResponseAsObject !== void 0) this.setIsResponseAsObject(isResponseAsObject);
693
738
  }
694
739
  };
695
740
  var AbortableFetch_default2 = AbortableFetch2;
696
741
 
697
- // src/Classes/RESTAPI/partials/_utils.js
742
+ // src/Classes/RESTAPI/partials/_utils.ts
698
743
  function getIsOnlyAnObject(input) {
699
- return typeof input === "object" && // "отбивает" примитивы и функции
700
- input instanceof Object && // "отбивает" null
701
- !Array.isArray(input) && // "отбивает" массивы
702
- !(input instanceof Set) && // "отбивает" сеты
703
- !(input instanceof Map);
744
+ return typeof input === "object" && input instanceof Object && !Array.isArray(input) && !(input instanceof Set) && !(input instanceof Map);
704
745
  }
705
- var clone = (input) => {
746
+ function clone(input) {
706
747
  if (input === null || typeof input !== "object") return input;
707
- const data = input instanceof Array ? [] : {};
708
- for (const i in input) data[i] = clone(input[i]);
748
+ if (Array.isArray(input)) return input.map((item) => clone(item));
749
+ const source = getIsOnlyAnObject(input) ? input : {};
750
+ const data = {};
751
+ Object.keys(source).forEach((key) => {
752
+ data[key] = clone(source[key]);
753
+ });
709
754
  return data;
710
- };
711
- var omitKeys = (obj = {}, keys = []) => keys.reduce((acc, key) => {
712
- const { [key]: omit, ...rest } = acc;
713
- return rest;
714
- }, obj);
715
- var getResponseClone = async (res) => typeof res?.clone === "function" ? await res.clone() : clone(res);
755
+ }
756
+ function omitKeys(obj, keys = []) {
757
+ const source = obj ?? {};
758
+ const keySet = new Set(keys);
759
+ const result = {};
760
+ Object.keys(source).forEach((key) => {
761
+ if (!keySet.has(key)) result[key] = source[key];
762
+ });
763
+ return result;
764
+ }
765
+ async function getResponseClone(res) {
766
+ if (res && typeof res === "object" && "clone" in res && typeof res.clone === "function") {
767
+ return res.clone();
768
+ }
769
+ return clone(res);
770
+ }
716
771
  function addCustomMethods(data, prefix) {
717
772
  const preparedPrefix = (prefix || "").toString();
718
773
  Object.keys(data).forEach((key) => {
@@ -726,7 +781,7 @@ async function getInstanceOfFetchSystem(isGetBody) {
726
781
  let credentials = {};
727
782
  if (CREDENTIALS_CONTEXT) {
728
783
  const cred = await CREDENTIALS_CONTEXT.getCredentials();
729
- credentials = CREDENTIALS_CONTEXT.isUseRefreshTokensPropcessing ? await CREDENTIALS_CONTEXT.waitRefresh(cred.isNeedRefresh && !CREDENTIALS_CONTEXT.getIsTokenStartRefresh()).then(
784
+ credentials = CREDENTIALS_CONTEXT.isUseRefreshTokensPropcessing ? await CREDENTIALS_CONTEXT.waitRefresh(Boolean(cred.isNeedRefresh) && !CREDENTIALS_CONTEXT.getIsTokenStartRefresh()).then(
730
785
  async () => CREDENTIALS_CONTEXT.processCredentials(await CREDENTIALS_CONTEXT.getCredentials())
731
786
  ) : cred;
732
787
  }
@@ -744,52 +799,57 @@ async function getInstanceOfFetchSystem(isGetBody) {
744
799
  }
745
800
  return (CREDENTIALS_CONTEXT?.isUseRefreshTokensPropcessing ? CREDENTIALS_CONTEXT.waitRefresh() : Promise.resolve()).then(
746
801
  async () => new AbortableFetch_default2({
747
- //? Метод по умолчанию
802
+ // ? Метод по умолчанию
748
803
  method: "GET",
749
- //? Заголовки по умолчанию
804
+ // ? Заголовки по умолчанию
750
805
  headers: {
751
806
  ...headersToAbortableFetchInstance,
752
- //? (*) Тут обрабатываются кейсы
753
- //? - когда нет this.credentialsProcessing
754
- //? (мы НЕ хотим добавлять токены в принципе, не зашли в верхнюю if-ку)
755
- //? - когда есть this.credentialsProcessing, но нет credentials.token (не авторизованы)
756
- //? (зашли в верхнюю if-ку, попробовали получить/обновить креды)
807
+ // ? (*) Тут обрабатываются кейсы
808
+ // ? - когда нет this.credentialsProcessing
809
+ // ? (мы НЕ хотим добавлять токены в принципе, не зашли в верхнюю if-ку)
810
+ // ? - когда есть this.credentialsProcessing, но нет credentials.token (не авторизованы)
811
+ // ? (зашли в верхнюю if-ку, попробовали получить/обновить креды)
757
812
  ...credentials.token ? CREDENTIALS_CONTEXT?.getHeadersForAuthorize?.(credentials.token) || {} : {}
758
813
  },
759
814
  queryParameters: await API_CONTEXT.processQueryParams(queryParamsToAbortableFetchInstance),
760
- //? Опции по умолчанию
815
+ // ? Опции по умолчанию
761
816
  options: {
762
817
  mode: "cors",
763
818
  redirect: "follow",
764
819
  ...optionsToAbortableFetchInstance
765
820
  },
766
- //? Каждый запрос (каждый запрос мультизапроса), сделаный методом request этого экземпляра выполнит этот колбек
821
+ // ? Каждый запрос (каждый запрос мультизапроса), сделаный методом request этого экземпляра выполнит этот колбек
767
822
  everyPromiseCallback: async function everyPromiseCallback(response) {
768
823
  const ABORTABLE_FETCH_INSTANCE = this;
769
824
  if (!response.status) {
770
- const request = ABORTABLE_FETCH_INSTANCE.requestInput.find((item) => item?.path === response?.request?.path);
771
- const isUseErrorToast = request?.mesageOptions?.isUseErrorToast;
825
+ const reqInput = ABORTABLE_FETCH_INSTANCE.requestInput;
826
+ const responseRequest = getIsOnlyAnObject(response.request) ? response.request : {};
827
+ const request = Array.isArray(reqInput) ? reqInput.find((item) => getIsOnlyAnObject(item) && item.path === responseRequest.path) : void 0;
828
+ const mesageOptions = getIsOnlyAnObject(request) && getIsOnlyAnObject(request.mesageOptions) ? request.mesageOptions : void 0;
829
+ const isUseErrorToast = mesageOptions?.isUseErrorToast;
772
830
  if (isUseErrorToast) {
773
- API_CONTEXT.sendMessage?.(API_CONTEXT.NO_INET, request.mesageOptions, response);
831
+ API_CONTEXT.sendMessage?.(API_CONTEXT.NO_INET, mesageOptions, response);
774
832
  }
775
833
  }
776
- 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));
834
+ 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));
777
835
  },
778
- //? Если хоть один запрос из пачки будет зареджекчен, зареджектится вся пачка.
779
- //? В этом случае будет выполнен этот колбэк
836
+ // ? Если хоть один запрос из пачки будет зареджекчен, зареджектится вся пачка.
837
+ // ? В этом случае будет выполнен этот колбэк
780
838
  catchCallback: async function catchCallback(res) {
781
839
  const ABORTABLE_FETCH_INSTANCE = this;
782
- const code = Number(res.message.split(":")[1]);
783
- if (CREDENTIALS_CONTEXT?.CODES_USING_THE_REFRESH_ATTEMPT?.includes?.(code)) {
784
- const isDoRefresh = !CREDENTIALS_CONTEXT?.getIsTokenStartRefresh?.();
785
- return CREDENTIALS_CONTEXT?.waitRefresh(isDoRefresh).then(async () => {
786
- const newCredentials = await CREDENTIALS_CONTEXT?.processCredentials({
787
- ...await CREDENTIALS_CONTEXT?.getCredentials(true),
840
+ if (!CREDENTIALS_CONTEXT) return Promise.reject(res);
841
+ const code = Number(res instanceof Error ? res.message.split(":")[1] : "");
842
+ if (CREDENTIALS_CONTEXT.CODES_USING_THE_REFRESH_ATTEMPT?.includes(code)) {
843
+ const isDoRefresh = !CREDENTIALS_CONTEXT.getIsTokenStartRefresh();
844
+ return CREDENTIALS_CONTEXT.waitRefresh(isDoRefresh).then(async () => {
845
+ const newCredentials = await CREDENTIALS_CONTEXT.processCredentials({
846
+ ...await CREDENTIALS_CONTEXT.getCredentials(true),
788
847
  isCatchCallbackProcess: isDoRefresh
789
848
  });
849
+ const currentHeaders = ABORTABLE_FETCH_INSTANCE.getHeaders();
790
850
  ABORTABLE_FETCH_INSTANCE.setHeaders({
791
- ...ABORTABLE_FETCH_INSTANCE.getHeaders(),
792
- ...newCredentials?.token ? { Authorization: `Bearer ${newCredentials?.token}` } : {}
851
+ ...getIsOnlyAnObject(currentHeaders) ? currentHeaders : {},
852
+ ...newCredentials.token ? { Authorization: `Bearer ${newCredentials.token}` } : {}
793
853
  });
794
854
  if (newCredentials.token) return ABORTABLE_FETCH_INSTANCE.repeatRequest();
795
855
  return Promise.reject(res);
@@ -801,13 +861,23 @@ async function getInstanceOfFetchSystem(isGetBody) {
801
861
  );
802
862
  }
803
863
 
804
- // src/Classes/RESTAPI/partials/Utils.js
864
+ // src/Classes/RESTAPI/partials/Utils.ts
805
865
  var Utils = class {
806
- //! Могут содержаться НЕасинхронные методы!
807
- //? Ф-я normalizeQueryParams является нормализатором сложных квери
808
- //? Например: &key1=&&&===&&&key2====&&&&&&&&key3=....
809
- //? Для корректной работы на вход нужно подавать НЕ кодированные значения
810
- //? По умолчанию выходные значения квери-параметров НЕ кодируются
866
+ // ! Могут содержаться НЕасинхронные методы!
867
+ /**
868
+ * Нормализатор сложных query-параметров.
869
+ *
870
+ * Например: `&key1=&&&===&&&key2====&&&&&&&&key3=...`. Для корректной работы на вход нужно подавать
871
+ * НЕ кодированные значения. По умолчанию выходные значения query-параметров НЕ кодируются.
872
+ *
873
+ * @param queryParams - query в виде строки, массива или объекта.
874
+ * @param settings - формат вывода (`array` | `string` | `object`) и флаг кодирования.
875
+ * @returns Нормализованные query-параметры в выбранном формате.
876
+ */
877
+ // ? Ф-я normalizeQueryParams является нормализатором сложных квери
878
+ // ? Например: &key1=&&&===&&&key2====&&&&&&&&key3=....
879
+ // ? Для корректной работы на вход нужно подавать НЕ кодированные значения
880
+ // ? По умолчанию выходные значения квери-параметров НЕ кодируются
811
881
  normalizeQueryParams(queryParams, settings) {
812
882
  if (settings && !getIsOnlyAnObject(settings)) {
813
883
  throw new Error("Bad settings [class Utils, normalizeQueryParams]");
@@ -826,9 +896,13 @@ var Utils = class {
826
896
  if (index === -1) return [item];
827
897
  return [item.slice(0, index), item.slice(index + 1)];
828
898
  }).filter(([key]) => Boolean(key)).map(([key, value]) => prepareParam(key, value));
829
- } else if (getIsOnlyAnObject(input)) return Object.keys(input).map((key) => prepareParam(key, input[key]));
830
- else if (typeof input === "string") return (input[0] === "?" ? input.slice(1) : input).split("&");
831
- else return [];
899
+ } else if (getIsOnlyAnObject(input)) {
900
+ return Object.keys(input).map((key) => prepareParam(key, input[key]));
901
+ } else if (typeof input === "string") {
902
+ return (input[0] === "?" ? input.slice(1) : input).split("&");
903
+ } else {
904
+ return [];
905
+ }
832
906
  };
833
907
  const { isEncode = false, outputAs = "array" } = settings || {};
834
908
  const initialStructure = getInitialArr(queryParams);
@@ -845,7 +919,9 @@ var Utils = class {
845
919
  if (index !== -1 && index !== 0) {
846
920
  const key = str.slice(0, index);
847
921
  acc.result.push(`${key}=${encodeURIComponent(str.slice(index + 1))}`);
848
- } else acc.toJoin = str;
922
+ } else {
923
+ acc.toJoin = str;
924
+ }
849
925
  if (idx === initialStructure.length - 1 && typeof acc.toJoin === "string") processToJoin(acc.toJoin);
850
926
  return acc;
851
927
  },
@@ -853,7 +929,7 @@ var Utils = class {
853
929
  ).result;
854
930
  const outputStructure = normalizedStructure.map((item) => {
855
931
  const [key, value] = item.split("=");
856
- return [key, !isEncode ? decodeURIComponent(value) : value];
932
+ return [key, !isEncode ? decodeURIComponent(value ?? "") : value ?? ""];
857
933
  });
858
934
  switch (outputAs) {
859
935
  case "string":
@@ -867,16 +943,25 @@ var Utils = class {
867
943
  };
868
944
  var Utils_default = Utils;
869
945
 
870
- // src/Classes/RESTAPI/partials/ApiUtils.js
946
+ // src/Classes/RESTAPI/partials/ApiUtils.ts
871
947
  var ApiUtils = class extends Utils_default {
948
+ /** Корневой путь API (раскладывается в ApiBase из constants.API_PATH). */
949
+ API_PATH;
872
950
  constructor(settings) {
873
951
  super();
874
952
  const { utils } = settings || {};
875
953
  if (getIsOnlyAnObject(utils)) addCustomMethods.call(this, utils);
876
954
  }
877
- //? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
878
- //? Метод не планировался как асинхронный,
879
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
955
+ /**
956
+ * Разбирает единый объект параметров запроса на части в зависимости от варианта использования.
957
+ *
958
+ * @param apiParams - объединённые параметры запроса.
959
+ * @param variant - `'doRequestMapping'` для мультизапроса либо `undefined` для одиночного.
960
+ * @returns Для `doRequestMapping` — объект параметров; иначе кортеж `[параметры, настройки]`.
961
+ */
962
+ // ? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
963
+ // ? Метод не планировался как асинхронный,
964
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
880
965
  async splitProperties(apiParams, variant) {
881
966
  const {
882
967
  isResponseAsObject,
@@ -935,79 +1020,224 @@ var ApiUtils = class extends Utils_default {
935
1020
  ];
936
1021
  }
937
1022
  }
938
- //! Обработчик пропы api из объекта описания запроса
939
- //? Планируется, что метод будет перегружаться на экземпляре,
940
- //? т.к. на разных проектах могут быть разные интерпретации пропы api
941
- //? Метод не планировался как асинхронный,
942
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1023
+ /**
1024
+ * Обработчик пропы `api` из объекта описания запроса — возвращает корневой путь API.
1025
+ *
1026
+ * @returns Корневой путь (по умолчанию — API_PATH).
1027
+ */
1028
+ // ! Обработчик пропы api из объекта описания запроса
1029
+ // ? Планируется, что метод будет перегружаться на экземпляре,
1030
+ // ? т.к. на разных проектах могут быть разные интерпретации пропы api
1031
+ // ? Метод не планировался как асинхронный,
1032
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
943
1033
  async getRootPath() {
944
1034
  return this.API_PATH;
945
1035
  }
946
- //? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
947
- //? Метод планировался как асинхронный
1036
+ /**
1037
+ * Извлекает тело ответа в нужном виде (json/blob/text/arrayBuffer/formData) либо по content-type.
1038
+ *
1039
+ * @param response - объект Response (иначе значение возвращается как есть).
1040
+ * @param getBodyAs - желаемый способ извлечения тела.
1041
+ * @returns Промис с телом ответа (или исходным значением / null при ошибке).
1042
+ */
1043
+ // ? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
1044
+ // ? Метод планировался как асинхронный
948
1045
  async getResponseBody(response, getBodyAs) {
949
1046
  if (!(response instanceof Response)) return response;
950
1047
  const contentType = response.headers.get("content-type");
951
1048
  if (!contentType) return "";
952
- const executor = (() => {
953
- if (typeof getBodyAs === "string" && getBodyAs in response && typeof response[getBodyAs] === "function") {
954
- return response[getBodyAs];
955
- }
956
- if (typeof contentType === "string" && contentType.includes("text/csv")) {
957
- return response.blob;
958
- }
959
- return typeof contentType === "string" && contentType.includes("json") ? response.json : response.text;
960
- })();
1049
+ const bodyReaders = {
1050
+ json: (r) => r.json(),
1051
+ blob: (r) => r.blob(),
1052
+ text: (r) => r.text(),
1053
+ arrayBuffer: (r) => r.arrayBuffer(),
1054
+ formData: (r) => r.formData()
1055
+ };
1056
+ const isBodyKey = (key) => key in bodyReaders;
1057
+ const reader = typeof getBodyAs === "string" && isBodyKey(getBodyAs) ? bodyReaders[getBodyAs] : contentType.includes("text/csv") ? bodyReaders.blob : contentType.includes("json") ? bodyReaders.json : bodyReaders.text;
961
1058
  try {
962
- return await executor.call(response);
1059
+ return await reader(response);
963
1060
  } catch {
964
1061
  console.log("Failed to extract the body");
965
1062
  return null;
966
1063
  }
967
1064
  }
968
- //! Обработчик структуры для ошибки (не рендер месседжа, а имеено формирование ошибки),
969
- //? Планируется, что метод будет перегружаться на экземпляре,
970
- //? т.к. на разных проектах могут быть разные структуры тела ответа для ошибки
971
- //? Метод не планировался как асинхронный,
972
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
973
- //? res - уже тело ответа
1065
+ /**
1066
+ * Формирует структуру ошибки из тела ответа (точка расширения под формат бэкенда).
1067
+ *
1068
+ * @param res - уже извлечённое тело ответа.
1069
+ * @returns Структура сообщения об ошибке.
1070
+ */
1071
+ // ! Обработчик структуры для ошибки (не рендер месседжа, а имеено формирование ошибки),
1072
+ // ? Планируется, что метод будет перегружаться на экземпляре,
1073
+ // ? т.к. на разных проектах могут быть разные структуры тела ответа для ошибки
1074
+ // ? Метод не планировался как асинхронный,
1075
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1076
+ // ? res - уже тело ответа
974
1077
  async getErrorMessage(res) {
975
1078
  return res;
976
1079
  }
977
- //? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
978
- //? Метод планировался как асинхронный
1080
+ /**
1081
+ * Проверяет код ответа и (если задан sendMessage) информирует пользователя об успехе/ошибке.
1082
+ *
1083
+ * @param res - объект Response (или совместимый с полем `ok`).
1084
+ * @param settings - сообщения и настройки тостов для данного запроса.
1085
+ * @returns Исходный `res` (метод не меняет ответ, только сигналит сообщением).
1086
+ */
1087
+ // ? Планируется, что метод будет использоваться неизменно, однако технически его можно перегрузить на экземпляре
1088
+ // ? Метод планировался как асинхронный
979
1089
  async checkResponseCode(res, settings) {
980
- if (typeof this.sendMessage !== "function") return res;
1090
+ const send = this.sendMessage;
1091
+ if (typeof send !== "function") return res;
981
1092
  const { successMess, errorMess } = settings || {};
982
- const message = res.ok ? successMess || this.DEFAULT_SUCCESS_MESSAGE : errorMess || await this.getErrorMessage(await this.getResponseBody(await getResponseClone(res)));
1093
+ const isOk = getIsOnlyAnObject(res) ? Boolean(res.ok) : false;
1094
+ const message = isOk ? successMess || this.DEFAULT_SUCCESS_MESSAGE : errorMess || await this.getErrorMessage(await this.getResponseBody(await getResponseClone(res)));
983
1095
  try {
984
- this.sendMessage(message, settings, await getResponseClone(res));
985
- } catch (_error) {
1096
+ send(message, settings, await getResponseClone(res));
1097
+ } catch {
986
1098
  }
987
1099
  return res;
988
1100
  }
989
- //? Суть метода:
990
- //? передать из вне структуры, которые будут использоваться для КАЖДОГО запроса сделанного экземпляром RESTAPI
991
- //! Данные затрут прочие настройки КРОМЕ данных по логике авторизации
992
- //? Планируется, что метод будет перегружаться на экземпляре
993
- //? Метод не планировался как асинхронный,
994
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1101
+ /**
1102
+ * Структуры, которые будут использоваться для КАЖДОГО запроса, сделанного экземпляром RESTAPI.
1103
+ *
1104
+ * @returns Объект `{ headers, queryParameters, options }` (по умолчанию пустой).
1105
+ */
1106
+ // ? Суть метода:
1107
+ // ? передать из вне структуры, которые будут использоваться для КАЖДОГО запроса сделанного экземпляром RESTAPI
1108
+ // ! Данные затрут прочие настройки КРОМЕ данных по логике авторизации
1109
+ // ? Планируется, что метод будет перегружаться на экземпляре
1110
+ // ? Метод не планировался как асинхронный,
1111
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
995
1112
  async addAsCommon() {
996
1113
  return {};
997
1114
  }
998
- //! Обработчик квери-параметров для общего процессинга,
999
- //! Например для кодирования decodeURIComponent или/и приведения в формат массива
1000
- //? Планируется, что метод будет перегружаться на экземпляре,
1001
- //? т.к. на разных проектах могут быть разные договоренности по форматам
1002
- //? Метод не планировался как асинхронный,
1003
- //? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1115
+ /**
1116
+ * Общий обработчик query-параметров (точка расширения, напр. кодирование/приведение к массиву).
1117
+ *
1118
+ * @param queryParams - входные query-параметры.
1119
+ * @returns Обработанные query-параметры (по умолчанию — без изменений).
1120
+ */
1121
+ // ! Обработчик квери-параметров для общего процессинга,
1122
+ // ! Например для кодирования decodeURIComponent или/и приведения в формат массива
1123
+ // ? Планируется, что метод будет перегружаться на экземпляре,
1124
+ // ? т.к. на разных проектах могут быть разные договоренности по форматам
1125
+ // ? Метод не планировался как асинхронный,
1126
+ // ? однако ввиду того что он может быть перегружен на экземпляре асинхронность предусматривается
1004
1127
  async processQueryParams(queryParams) {
1005
1128
  return queryParams;
1006
1129
  }
1007
1130
  };
1008
1131
  var ApiUtils_default = ApiUtils;
1009
1132
 
1010
- // src/Classes/RESTAPI/partials/ApiRequestCreators.js
1133
+ // src/Classes/RESTAPI/partials/sse.ts
1134
+ function parseSSEEvent(block) {
1135
+ if (typeof block !== "string") return null;
1136
+ const event = { event: "message", data: "", id: void 0, retry: void 0 };
1137
+ const dataLines = [];
1138
+ let hasField = false;
1139
+ block.split("\n").forEach((line) => {
1140
+ if (line === "" || line[0] === ":") return;
1141
+ const colonIdx = line.indexOf(":");
1142
+ const field = colonIdx === -1 ? line : line.slice(0, colonIdx);
1143
+ let value = colonIdx === -1 ? "" : line.slice(colonIdx + 1);
1144
+ if (value[0] === " ") value = value.slice(1);
1145
+ switch (field) {
1146
+ case "event":
1147
+ event.event = value;
1148
+ hasField = true;
1149
+ break;
1150
+ case "data":
1151
+ dataLines.push(value);
1152
+ hasField = true;
1153
+ break;
1154
+ case "id":
1155
+ event.id = value;
1156
+ hasField = true;
1157
+ break;
1158
+ case "retry":
1159
+ if (/^\d+$/.test(value)) {
1160
+ event.retry = Number(value);
1161
+ hasField = true;
1162
+ }
1163
+ break;
1164
+ default:
1165
+ break;
1166
+ }
1167
+ });
1168
+ if (!hasField) return null;
1169
+ event.data = dataLines.join("\n");
1170
+ return event;
1171
+ }
1172
+ function safeCall(fn, ...args) {
1173
+ if (typeof fn !== "function") return;
1174
+ try {
1175
+ fn(...args);
1176
+ } catch {
1177
+ }
1178
+ }
1179
+ async function readSSE(response, { onEvent, onChunk, handlers, parseJson } = {}) {
1180
+ const events = [];
1181
+ const stream = response.body;
1182
+ if (!stream) return events;
1183
+ const reader = stream.getReader();
1184
+ const decoder = new TextDecoder("utf-8");
1185
+ let buffer = "";
1186
+ let pendingCR = "";
1187
+ const normalize = (chunk) => chunk.replace(/\r\n|\r/g, "\n");
1188
+ const flush = (rawBlock) => {
1189
+ const event = parseSSEEvent(rawBlock);
1190
+ if (!event) return;
1191
+ if (parseJson && typeof event.data === "string" && event.data !== "") {
1192
+ try {
1193
+ event.data = JSON.parse(event.data);
1194
+ } catch {
1195
+ }
1196
+ }
1197
+ events.push(event);
1198
+ safeCall(onEvent, event);
1199
+ safeCall(onChunk, event.data, event);
1200
+ if (handlers) safeCall(handlers[event.event], event.data, event);
1201
+ };
1202
+ try {
1203
+ while (true) {
1204
+ const { done, value } = await reader.read();
1205
+ if (done) break;
1206
+ let chunk = pendingCR + decoder.decode(value, { stream: true });
1207
+ pendingCR = "";
1208
+ if (chunk.endsWith("\r")) {
1209
+ pendingCR = "\r";
1210
+ chunk = chunk.slice(0, -1);
1211
+ }
1212
+ buffer += normalize(chunk);
1213
+ let sepIdx;
1214
+ while ((sepIdx = buffer.indexOf("\n\n")) !== -1) {
1215
+ const rawBlock = buffer.slice(0, sepIdx);
1216
+ buffer = buffer.slice(sepIdx + 2);
1217
+ flush(rawBlock);
1218
+ }
1219
+ }
1220
+ buffer += normalize(pendingCR + decoder.decode());
1221
+ buffer = buffer.replace(/\n+$/g, "");
1222
+ if (buffer !== "") flush(buffer);
1223
+ } catch (error) {
1224
+ const name = error && typeof error === "object" && "name" in error ? error.name : void 0;
1225
+ if (name !== "AbortError") throw error;
1226
+ } finally {
1227
+ try {
1228
+ reader.releaseLock?.();
1229
+ } catch {
1230
+ }
1231
+ }
1232
+ return events;
1233
+ }
1234
+
1235
+ // src/Classes/RESTAPI/partials/ApiRequestCreators.ts
1236
+ function isStreamResponse(value) {
1237
+ if (!getIsOnlyAnObject(value) || !value.ok) return false;
1238
+ const body = value.body;
1239
+ return typeof body === "object" && body !== null && "getReader" in body && typeof body.getReader === "function";
1240
+ }
1011
1241
  var PREFIX_OF_CLASS_UTILS = "createRequest_";
1012
1242
  var ApiRequestCreators = class extends ApiUtils_default {
1013
1243
  constructor(settings) {
@@ -1015,8 +1245,14 @@ var ApiRequestCreators = class extends ApiUtils_default {
1015
1245
  const { requestsCreators } = settings || {};
1016
1246
  if (getIsOnlyAnObject(requestsCreators)) addCustomMethods.call(this, requestsCreators, PREFIX_OF_CLASS_UTILS);
1017
1247
  }
1018
- //? При типе toJson пользовательский callback на вход получит тело ответа реализованное методом Response.json()
1019
- //? независимо от насторойки isGetBody
1248
+ /**
1249
+ * Крейтер типа `toJson`: пользовательский callback получит тело ответа (Response.json()).
1250
+ *
1251
+ * @param props - объект описания запроса.
1252
+ * @param variant - вариант обработки splitProperties.
1253
+ */
1254
+ // ? При типе toJson пользовательский callback на вход получит тело ответа реализованное методом Response.json()
1255
+ // ? независимо от насторойки isGetBody
1020
1256
  async createRequest_toJson(props, variant) {
1021
1257
  const safelyProps = omitKeys(props, ["getBodyAs"]);
1022
1258
  return this.splitProperties(
@@ -1025,15 +1261,21 @@ var ApiRequestCreators = class extends ApiUtils_default {
1025
1261
  isGetBody: false,
1026
1262
  callback: async (res) => {
1027
1263
  const output = await this.getResponseBody(res, "json");
1028
- return await (safelyProps.callback?.(output) ?? output);
1264
+ return await (props.callback?.(output) ?? output);
1029
1265
  }
1030
1266
  },
1031
1267
  variant
1032
1268
  );
1033
1269
  }
1034
- //? При типе toJsonAdvanced пользовательский callback на вход получит структуру { response, result },
1035
- //? где response - объект Response, result - тело ответа реализованное методом Response.json()
1036
- //? независимо от насторойки isGetBody
1270
+ /**
1271
+ * Крейтер типа `toJsonAdvanced`: callback получит структуру `{ response, result }`.
1272
+ *
1273
+ * @param props - объект описания запроса.
1274
+ * @param variant - вариант обработки splitProperties.
1275
+ */
1276
+ // ? При типе toJsonAdvanced пользовательский callback на вход получит структуру { response, result },
1277
+ // ? где response - объект Response, result - тело ответа реализованное методом Response.json()
1278
+ // ? независимо от насторойки isGetBody
1037
1279
  async createRequest_toJsonAdvanced(props, variant) {
1038
1280
  const safelyProps = omitKeys(props, ["getBodyAs"]);
1039
1281
  return this.splitProperties(
@@ -1045,14 +1287,20 @@ var ApiRequestCreators = class extends ApiUtils_default {
1045
1287
  response: res,
1046
1288
  result: await this.getResponseBody(await getResponseClone(res), "json")
1047
1289
  };
1048
- return await (safelyProps.callback?.(output) ?? output);
1290
+ return await (props.callback?.(output) ?? output);
1049
1291
  }
1050
1292
  },
1051
1293
  variant
1052
1294
  );
1053
1295
  }
1054
- //? При типе blob пользовательский callback на вход получит тело ответа реализованное методом Response.blob(),
1055
- //? независимо от насторойки isGetBody
1296
+ /**
1297
+ * Крейтер типа `blob`: callback получит тело ответа (Response.blob()).
1298
+ *
1299
+ * @param props - объект описания запроса.
1300
+ * @param variant - вариант обработки splitProperties.
1301
+ */
1302
+ // ? При типе blob пользовательский callback на вход получит тело ответа реализованное методом Response.blob(),
1303
+ // ? независимо от насторойки isGetBody
1056
1304
  async createRequest_blob(props, variant) {
1057
1305
  const safelyProps = omitKeys(props, ["getBodyAs"]);
1058
1306
  return this.splitProperties(
@@ -1061,14 +1309,67 @@ var ApiRequestCreators = class extends ApiUtils_default {
1061
1309
  isGetBody: false,
1062
1310
  callback: async (res) => {
1063
1311
  const output = await this.getResponseBody(await getResponseClone(res), "blob");
1064
- return await (safelyProps.callback?.(output) ?? output);
1312
+ return await (props.callback?.(output) ?? output);
1065
1313
  }
1066
1314
  },
1067
1315
  variant
1068
1316
  );
1069
1317
  }
1070
- //? При типе testBadResponse пользовательский callback на вход получит объект Response в 401-м статусе
1071
- //? независимо независимо вообще ни от чего
1318
+ /**
1319
+ * Крейтер типа `sse`: обрабатывает ответ как поток Server-Sent Events (text/event-stream).
1320
+ *
1321
+ * Дополнительные пропы объекта описания запроса: `onEvent`, `onChunk`, `handlers`, `parseJson`.
1322
+ * По умолчанию добавляется заголовок `Accept: text/event-stream`. Метод doRequest резолвится
1323
+ * массивом всех событий ПОСЛЕ закрытия потока; отмена — методом `.abort()` возвращённого промиса.
1324
+ *
1325
+ * @param props - объект описания запроса (плюс onEvent/onChunk/handlers/parseJson).
1326
+ * @param variant - вариант обработки splitProperties.
1327
+ */
1328
+ // ? При типе sse запрос обрабатывается как поток Server-Sent Events (text/event-stream).
1329
+ // ? Дополнительные пропы объекта описания запроса:
1330
+ // ? - onEvent(event) — вызывается на каждое распарсенное событие { event, data, id, retry };
1331
+ // ? - onChunk(data, event) — вызывается на полезную нагрузку (поле data) каждого события;
1332
+ // ? - handlers — карта { имяСобытия: cb } для типизированной обработки по полю event
1333
+ // ? (например { delta, status, done }); cb получает (data, event);
1334
+ // ? - parseJson — если true, поле data каждого события прогоняется через JSON.parse.
1335
+ // ? По умолчанию добавляется заголовок Accept: text/event-stream (его можно переопределить через headers).
1336
+ // ? Пользовательский callback (если передан) на вход получит итоговый массив всех событий.
1337
+ // ? Метод doRequest резолвится массивом всех событий ПОСЛЕ закрытия потока;
1338
+ // ? отмена потока выполняется методом .abort() возвращённого промиса (через встроенный AbortController).
1339
+ async createRequest_sse(props, variant) {
1340
+ const safelyProps = omitKeys(props, ["getBodyAs", "onChunk", "onEvent", "handlers", "parseJson"]);
1341
+ const { onChunk, onEvent, handlers, parseJson } = props;
1342
+ const sseOptions = {
1343
+ onChunk: typeof onChunk === "function" ? (data, event) => onChunk(data, event) : void 0,
1344
+ onEvent: typeof onEvent === "function" ? (event) => onEvent(event) : void 0,
1345
+ parseJson: Boolean(parseJson),
1346
+ handlers: getIsOnlyAnObject(handlers) ? Object.keys(handlers).reduce((acc, key) => {
1347
+ const fn = handlers[key];
1348
+ acc[key] = typeof fn === "function" ? (data, event) => fn(data, event) : void 0;
1349
+ return acc;
1350
+ }, {}) : void 0
1351
+ };
1352
+ return this.splitProperties(
1353
+ {
1354
+ ...safelyProps,
1355
+ headers: { Accept: "text/event-stream", ...getIsOnlyAnObject(safelyProps.headers) ? safelyProps.headers : {} },
1356
+ isGetBody: false,
1357
+ callback: async (res) => {
1358
+ const output = isStreamResponse(res) ? await readSSE(res, sseOptions) : res;
1359
+ return await (props.callback?.(output) ?? output);
1360
+ }
1361
+ },
1362
+ variant
1363
+ );
1364
+ }
1365
+ /**
1366
+ * Крейтер типа `testBadResponse`: callback получит синтетический Response со статусом 401.
1367
+ *
1368
+ * @param props - объект описания запроса.
1369
+ * @param variant - вариант обработки splitProperties.
1370
+ */
1371
+ // ? При типе testBadResponse пользовательский callback на вход получит объект Response в 401-м статусе
1372
+ // ? независимо независимо вообще ни от чего
1072
1373
  async createRequest_testBadResponse(props, variant) {
1073
1374
  return this.splitProperties(
1074
1375
  {
@@ -1088,17 +1389,33 @@ var ApiRequestCreators = class extends ApiUtils_default {
1088
1389
  variant
1089
1390
  );
1090
1391
  }
1091
- //? По умолчанию пользовательский callback на вход получит
1092
- //? - либо объект Response
1093
- //? - либо тело ответа (в случае isGetBody: 'first') полученное методом getResponseBody (смотри класс ApiUtils)
1392
+ /**
1393
+ * Крейтер по умолчанию: callback получит объект Response (или тело ответа при isGetBody: 'first').
1394
+ *
1395
+ * @param props - объект описания запроса.
1396
+ * @param variant - вариант обработки splitProperties.
1397
+ */
1398
+ // ? По умолчанию пользовательский callback на вход получит
1399
+ // ? - либо объект Response
1400
+ // ? - либо тело ответа (в случае isGetBody: 'first') полученное методом getResponseBody (смотри класс ApiUtils)
1094
1401
  async createRequest_default(props, variant) {
1095
1402
  return this.splitProperties(props, variant);
1096
1403
  }
1097
1404
  };
1098
1405
  var ApiRequestCreators_default = ApiRequestCreators;
1099
1406
 
1100
- // src/Classes/RESTAPI/partials/ApiBase.js
1407
+ // src/Classes/RESTAPI/partials/ApiBase.ts
1101
1408
  var ApiBase = class extends ApiRequestCreators_default {
1409
+ /** Текст ошибки невалидных данных запроса. */
1410
+ BAD_REQUEST_DATA_TEXT;
1411
+ /** Текст сообщения об успехе по умолчанию. */
1412
+ DEFAULT_SUCCESS_MESSAGE;
1413
+ /** Текст сообщения об ошибке по умолчанию. */
1414
+ DEFAULT_ERROR_MESSAGE;
1415
+ /** Текст сообщения об отсутствии сети. */
1416
+ NO_INET;
1417
+ /** Коды ответа, по которым запрос считается отклонённым. */
1418
+ REJECT_CODES;
1102
1419
  constructor(settings) {
1103
1420
  super(settings);
1104
1421
  const {
@@ -1127,49 +1444,76 @@ var ApiBase = class extends ApiRequestCreators_default {
1127
1444
  };
1128
1445
  var ApiBase_default = ApiBase;
1129
1446
 
1130
- // src/Classes/RESTAPI/partials/CredentialsProcessing.js
1447
+ // src/Classes/RESTAPI/partials/CredentialsProcessing.ts
1131
1448
  function decodeJWT(token) {
1132
1449
  try {
1133
- const payload = token.split(".")[1];
1134
- return JSON.parse(atob(payload));
1135
- } catch (e) {
1450
+ const payload = token.split(".")[1] ?? "";
1451
+ const decoded = JSON.parse(atob(payload));
1452
+ return getIsOnlyAnObject(decoded) ? decoded : null;
1453
+ } catch {
1136
1454
  return null;
1137
1455
  }
1138
1456
  }
1139
1457
  var CredentialsProcessing = class {
1458
+ /** Включён ли флоу рефреша токенов. */
1459
+ isUseRefreshTokensPropcessing = false;
1460
+ /** Учётные данные по умолчанию (пустые). */
1461
+ DEFAULT_CREDENTIALS = {};
1462
+ /** Внешний метод получения учётных данных. */
1463
+ getCredentialsByOuter;
1464
+ /** Внешний метод формирования заголовков авторизации по токену. */
1465
+ getHeadersForAuthorize;
1466
+ /** Необязательный преобразователь учётных данных после getCredentials. */
1467
+ importCredentials;
1468
+ /** Необязательный метод сохранения учётных данных (обязателен для флоу рефреша). */
1469
+ saveCredentials;
1470
+ /** Внешний метод рефреша учётных данных. */
1471
+ refreshCredentialsByOuter;
1472
+ /** Полный путь до эндпоинта рефреша токена. */
1473
+ REFRESH_TOKEN_PATH;
1474
+ /** Коды ответа, по которым триггерится попытка рефреша. */
1475
+ CODES_USING_THE_REFRESH_ATTEMPT;
1476
+ /** Ключ флага «рефреш начат» в localStorage. */
1477
+ REFRESH_TOKEN_FLAG = "refreshTokenFlag";
1478
+ /** Интервал опроса флага обновления токена, мс. */
1479
+ INTERVAL_FOR_CHECKING_TOKEN_UPDATE = 50;
1480
+ /** Колбэк, вызываемый после неудачного рефреша. */
1481
+ callbackAfterRejectRefresh;
1482
+ /** Доступ к верхнему контексту RESTAPI (навешивается из конструктора RESTAPI). */
1483
+ getRESTAPIContext;
1140
1484
  constructor(settings) {
1141
1485
  const { credentialsProcessing } = settings;
1142
1486
  const {
1143
- //? Для корректной работы установки токенов в запросы от API
1144
- //? нужно передавать методы getCredentials и getHeadersForAuthorize
1487
+ // ? Для корректной работы установки токенов в запросы от API
1488
+ // ? нужно передавать методы getCredentials и getHeadersForAuthorize
1145
1489
  getCredentials,
1146
1490
  getHeadersForAuthorize,
1147
- //? На вход получит токен, должна вернуть объект для коструктора Headers
1148
- //? Так же опционально можно передавать
1491
+ // ? На вход получит токен, должна вернуть объект для коструктора Headers
1492
+ // ? Так же опционально можно передавать
1149
1493
  importCredentials,
1150
- //? если он передается, то он будет применяться к выводу от вызова getCredentials
1494
+ // ? если он передается, то он будет применяться к выводу от вызова getCredentials
1151
1495
  saveCredentials,
1152
- //? можно будет найти в объекте credentialsProcessing, чтобы использовать кастомными методами
1153
- //! Либо вызов getCredentials, либо цепочка вызовов importCredentials(getCredentials())
1154
- //! должна возвращать требуемую классом структуру
1155
- //! Класс требует структуры
1156
- //! - { token }, если флоу рефреш токена НЕ используется
1157
- //! - { token, refreshToken, expires }, если используется флоу рефреш токена
1496
+ // ? можно будет найти в объекте credentialsProcessing, чтобы использовать кастомными методами
1497
+ // ! Либо вызов getCredentials, либо цепочка вызовов importCredentials(getCredentials())
1498
+ // ! должна возвращать требуемую классом структуру
1499
+ // ! Класс требует структуры
1500
+ // ! - { token }, если флоу рефреш токена НЕ используется
1501
+ // ! - { token, refreshToken, expires }, если используется флоу рефреш токена
1158
1502
  // *********
1159
- //? Подключает флоу рефреша токенов
1503
+ // ? Подключает флоу рефреша токенов
1160
1504
  isUseRefreshTokensPropcessing = false,
1161
- //! Для корректной работы флоу рефреша токенов передача метода saveCredentials становится ОБЯЗАТЕЛЬНОЙ
1162
- //? Так же для корректной работы флоу рефреша токенов нужно
1163
- //? - либо
1505
+ // ! Для корректной работы флоу рефреша токенов передача метода saveCredentials становится ОБЯЗАТЕЛЬНОЙ
1506
+ // ? Так же для корректной работы флоу рефреша токенов нужно
1507
+ // ? - либо
1164
1508
  refreshCredentials,
1165
- //! метод должен возвращать такую же структуру как и метод getCredentials,
1166
- //? на вход получит текущие креды, к выходу будет применен importCredentials, если этот метод передавался
1167
- //? - либо
1509
+ // ! метод должен возвращать такую же структуру как и метод getCredentials,
1510
+ // ? на вход получит текущие креды, к выходу будет применен importCredentials, если этот метод передавался
1511
+ // ? - либо
1168
1512
  REFRESH_TOKEN_PATH,
1169
- //! REFRESH_TOKEN_PATH передается ПОЛНОСТЬЮ (глобальная адресация)!
1513
+ // ! REFRESH_TOKEN_PATH передается ПОЛНОСТЬЮ (глобальная адресация)!
1170
1514
  CODES_USING_THE_REFRESH_ATTEMPT,
1171
- //? указывает по каким кодам ответа триггериться рефреш, массив чисел
1172
- //? Опционально
1515
+ // ? указывает по каким кодам ответа триггериться рефреш, массив чисел
1516
+ // ? Опционально
1173
1517
  REFRESH_TOKEN_FLAG = "refreshTokenFlag",
1174
1518
  INTERVAL_FOR_CHECKING_TOKEN_UPDATE = 50,
1175
1519
  // ms
@@ -1177,40 +1521,44 @@ var CredentialsProcessing = class {
1177
1521
  } = credentialsProcessing || {};
1178
1522
  if (typeof getCredentials !== "function") throw new Error("No getCredentials method [CredentialsProcessing]");
1179
1523
  if (typeof getHeadersForAuthorize !== "function") {
1180
- throw new Error("No getHeadersForAuthorize method [CredentialsProcessing]");
1524
+ throw new TypeError("No getHeadersForAuthorize method [CredentialsProcessing]");
1181
1525
  }
1182
1526
  if (importCredentials && typeof importCredentials !== "function") {
1183
1527
  throw new Error("Bad importCredentials method [CredentialsProcessing]");
1184
1528
  }
1185
- this.isUseRefreshTokensPropcessing = isUseRefreshTokensPropcessing;
1529
+ this.isUseRefreshTokensPropcessing = Boolean(isUseRefreshTokensPropcessing);
1186
1530
  this.DEFAULT_CREDENTIALS = {};
1187
- this.getCredentialsByOuter = getCredentials;
1188
- this.getHeadersForAuthorize = getHeadersForAuthorize;
1189
- this.importCredentials = importCredentials;
1531
+ this.getCredentialsByOuter = () => getCredentials();
1532
+ this.getHeadersForAuthorize = (token) => {
1533
+ const result = getHeadersForAuthorize(token);
1534
+ return getIsOnlyAnObject(result) ? result : {};
1535
+ };
1536
+ if (typeof importCredentials === "function") this.importCredentials = (cred) => importCredentials(cred);
1190
1537
  if (saveCredentials || isUseRefreshTokensPropcessing) {
1191
1538
  if (typeof saveCredentials !== "function") throw new Error("No saveCredentials method [CredentialsProcessing]");
1192
- else this.saveCredentials = saveCredentials;
1539
+ else this.saveCredentials = (cred) => saveCredentials(cred);
1193
1540
  }
1194
1541
  if (isUseRefreshTokensPropcessing) {
1195
- if (typeof refreshCredentials === "function") this.refreshCredentialsByOuter = refreshCredentials;
1196
- else {
1542
+ if (typeof refreshCredentials === "function") {
1543
+ this.refreshCredentialsByOuter = (cred) => refreshCredentials(cred);
1544
+ } else {
1197
1545
  if (typeof this.refreshCredentialsByOuter === "function" && typeof REFRESH_TOKEN_PATH !== "string") {
1198
- throw new Error("No REFRESH_TOKEN_PATH [CredentialsProcessing]");
1546
+ throw new TypeError("No REFRESH_TOKEN_PATH [CredentialsProcessing]");
1199
1547
  }
1200
- this.REFRESH_TOKEN_PATH = REFRESH_TOKEN_PATH;
1548
+ this.REFRESH_TOKEN_PATH = typeof REFRESH_TOKEN_PATH === "string" ? REFRESH_TOKEN_PATH : void 0;
1201
1549
  }
1202
1550
  if (!Array.isArray(CODES_USING_THE_REFRESH_ATTEMPT)) {
1203
- throw new Error("No CODES_USING_THE_REFRESH_ATTEMPT [CredentialsProcessing]");
1551
+ throw new TypeError("No CODES_USING_THE_REFRESH_ATTEMPT [CredentialsProcessing]");
1204
1552
  }
1205
1553
  if (!CODES_USING_THE_REFRESH_ATTEMPT.every((i) => typeof i === "number")) {
1206
1554
  throw new Error("Invalid format of CODES_USING_THE_REFRESH_ATTEMPT elements [CredentialsProcessing]");
1207
1555
  }
1208
1556
  if (typeof REFRESH_TOKEN_FLAG !== "string") throw new Error("Bad REFRESH_TOKEN_FLAG [CredentialsProcessing]");
1209
1557
  if (typeof INTERVAL_FOR_CHECKING_TOKEN_UPDATE !== "number") {
1210
- throw new Error("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1558
+ throw new TypeError("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1211
1559
  }
1212
1560
  if (typeof INTERVAL_FOR_CHECKING_TOKEN_UPDATE !== "number") {
1213
- throw new Error("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1561
+ throw new TypeError("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
1214
1562
  }
1215
1563
  if (callbackAfterRejectRefresh && typeof callbackAfterRejectRefresh !== "function") {
1216
1564
  throw new Error("Bad INTERVAL_FOR_CHECKING_TOKEN_UPDATE [CredentialsProcessing]");
@@ -1218,23 +1566,33 @@ var CredentialsProcessing = class {
1218
1566
  this.CODES_USING_THE_REFRESH_ATTEMPT = CODES_USING_THE_REFRESH_ATTEMPT;
1219
1567
  this.REFRESH_TOKEN_FLAG = REFRESH_TOKEN_FLAG;
1220
1568
  this.INTERVAL_FOR_CHECKING_TOKEN_UPDATE = INTERVAL_FOR_CHECKING_TOKEN_UPDATE;
1221
- if (callbackAfterRejectRefresh) this.callbackAfterRejectRefresh = callbackAfterRejectRefresh;
1569
+ if (typeof callbackAfterRejectRefresh === "function") this.callbackAfterRejectRefresh = () => callbackAfterRejectRefresh();
1222
1570
  }
1223
1571
  }
1572
+ /** Возвращает значение флага «рефреш начат» из localStorage. */
1224
1573
  getIsTokenStartRefresh() {
1225
1574
  return localStorage.getItem(this.REFRESH_TOKEN_FLAG);
1226
1575
  }
1576
+ /** Выставляет флаг «рефреш начат» в localStorage. */
1227
1577
  setIsTokenStartRefresh() {
1228
- localStorage.setItem(this.REFRESH_TOKEN_FLAG, true);
1578
+ localStorage.setItem(this.REFRESH_TOKEN_FLAG, String(true));
1229
1579
  }
1580
+ /** Снимает флаг «рефреш начат» из localStorage. */
1230
1581
  removeIsTokenStartRefresh() {
1231
1582
  localStorage.removeItem(this.REFRESH_TOKEN_FLAG);
1232
1583
  }
1584
+ /**
1585
+ * Возвращает текущие учётные данные (с учётом importCredentials и проверки истечения JWT).
1586
+ *
1587
+ * @param isCatchCallbackProcess - флаг процесса обработки ошибки (отключает проверку истечения).
1588
+ * @param callback - необязательный колбэк, получающий итоговые учётные данные.
1589
+ * @returns Промис с учётными данными.
1590
+ */
1233
1591
  async getCredentials(isCatchCallbackProcess, callback) {
1234
1592
  let credentials = await this.getCredentialsByOuter();
1235
1593
  if (typeof this.importCredentials === "function") credentials = await this.importCredentials(credentials);
1236
- if (!getIsOnlyAnObject(credentials)) credentials = {};
1237
- const token = credentials.token || null;
1594
+ const credObj = getIsOnlyAnObject(credentials) ? credentials : {};
1595
+ const token = credObj.token || null;
1238
1596
  if (token && !isCatchCallbackProcess) {
1239
1597
  let decoded;
1240
1598
  try {
@@ -1243,11 +1601,18 @@ var CredentialsProcessing = class {
1243
1601
  decoded = null;
1244
1602
  }
1245
1603
  const currentTime = Date.now() / 1e3;
1246
- if (decoded !== null && Number(decoded.exp) < currentTime) credentials = { ...credentials, isNeedRefresh: true };
1604
+ if (decoded !== null && Number(decoded.exp) < currentTime) credObj.isNeedRefresh = true;
1247
1605
  }
1248
- if (callback) await callback({ ...credentials, isCatchCallbackProcess });
1249
- return { ...credentials, isCatchCallbackProcess };
1250
- }
1606
+ if (callback) await callback({ ...credObj, isCatchCallbackProcess });
1607
+ return { ...credObj, isCatchCallbackProcess };
1608
+ }
1609
+ /**
1610
+ * Выполняет рефреш учётных данных (внешним методом либо дефолтным OAuth-флоу).
1611
+ *
1612
+ * @param currentCredentials - текущие учётные данные.
1613
+ * @param callback - необязательный колбэк сохранения новых учётных данных.
1614
+ * @returns Промис с новыми учётными данными.
1615
+ */
1251
1616
  async refreshCredentials(currentCredentials, callback) {
1252
1617
  const CONTEXT = this;
1253
1618
  async function finalize(cred) {
@@ -1260,11 +1625,10 @@ var CredentialsProcessing = class {
1260
1625
  if (!currentCredentials?.token || !currentCredentials?.refreshToken) return finalize(CONTEXT.DEFAULT_CREDENTIALS);
1261
1626
  async function refreshCredentialsByDefault() {
1262
1627
  const { token, refreshToken } = currentCredentials;
1263
- const headers = new Headers();
1264
- headers.append(...Object.entries(CONTEXT.getHeadersForAuthorize(token)));
1628
+ const headers = new Headers(Object.entries(CONTEXT.getHeadersForAuthorize(token || "")).map(([key, value]) => [key, `${value}`]));
1265
1629
  const body = new FormData();
1266
1630
  body.append("grant_type", "refresh_token");
1267
- body.append("refresh_token", refreshToken);
1631
+ body.append("refresh_token", refreshToken || "");
1268
1632
  body.append("client_id", "oauth");
1269
1633
  body.append("client_secret", "secret");
1270
1634
  body.append("access_type", "offline");
@@ -1277,8 +1641,14 @@ var CredentialsProcessing = class {
1277
1641
  });
1278
1642
  }
1279
1643
  const newCredentials = typeof CONTEXT.refreshCredentialsByOuter === "function" ? await CONTEXT.refreshCredentialsByOuter(currentCredentials) : await refreshCredentialsByDefault();
1280
- return finalize(newCredentials);
1281
- }
1644
+ return finalize(getIsOnlyAnObject(newCredentials) ? newCredentials : CONTEXT.DEFAULT_CREDENTIALS);
1645
+ }
1646
+ /**
1647
+ * Ожидает завершения рефреша токена (или запускает его флаг при необходимости).
1648
+ *
1649
+ * @param isNeedRefresh - выставить ли флаг «рефреш начат» при отсутствии активного рефреша.
1650
+ * @returns Промис, который резолвится по завершении ожидания.
1651
+ */
1282
1652
  async waitRefresh(isNeedRefresh) {
1283
1653
  return new Promise((resolve) => {
1284
1654
  if (!this.getIsTokenStartRefresh()) {
@@ -1294,10 +1664,16 @@ var CredentialsProcessing = class {
1294
1664
  }
1295
1665
  });
1296
1666
  }
1667
+ /**
1668
+ * Обрабатывает учётные данные: при необходимости рефрешит токен и возвращает актуальные данные.
1669
+ *
1670
+ * @param cred - текущие учётные данные.
1671
+ * @returns Промис с актуальными учётными данными (с флагом isRefreshFailed при неудаче).
1672
+ */
1297
1673
  async processCredentials(cred) {
1298
1674
  if (!cred.isNeedRefresh && !cred.isCatchCallbackProcess) return cred;
1299
1675
  const CONTEXT = this;
1300
- return CONTEXT.refreshCredentials(cred, (response) => CONTEXT.saveCredentials(response)).then(() => {
1676
+ return CONTEXT.refreshCredentials(cred, (response) => CONTEXT.saveCredentials?.(response)).then(() => {
1301
1677
  return new Promise((resolve) => {
1302
1678
  setTimeout(async () => {
1303
1679
  const newCredentials = await CONTEXT.getCredentials();
@@ -1315,11 +1691,15 @@ var CredentialsProcessing = class {
1315
1691
  };
1316
1692
  var CredentialsProcessing_default = CredentialsProcessing;
1317
1693
 
1318
- // src/Classes/RESTAPI/index.js
1694
+ // src/Classes/RESTAPI/index.ts
1319
1695
  function returnTheContext() {
1320
1696
  return this;
1321
1697
  }
1322
1698
  var RESTAPI = class extends ApiBase_default {
1699
+ /** Функция показа сообщений пользователю (или null, если информирование отключено). */
1700
+ sendMessage = null;
1701
+ /** Обработчик учётных данных (создаётся при наличии настройки credentialsProcessing). */
1702
+ credentialsProcessing;
1323
1703
  constructor(settings) {
1324
1704
  super(settings);
1325
1705
  const { sendMessage, credentialsProcessing } = settings || {};
@@ -1329,7 +1709,14 @@ var RESTAPI = class extends ApiBase_default {
1329
1709
  this.credentialsProcessing.getRESTAPIContext = returnTheContext.bind(this);
1330
1710
  }
1331
1711
  }
1332
- //! Основной (базовый) метод API, мультизапросы
1712
+ /**
1713
+ * Основной (базовый) метод API: выполняет мультизапрос (или одиночный запрос).
1714
+ *
1715
+ * @param inputRequests - путь, объект описания запроса или их массив.
1716
+ * @param settings - общие настройки запроса (формат ответа, тосты, сообщения и т.п.).
1717
+ * @returns Промис с результатом (форма зависит от isResponseAsObject).
1718
+ */
1719
+ // ! Основной (базовый) метод API, мультизапросы
1333
1720
  async doRequest(inputRequests, settings) {
1334
1721
  if (typeof inputRequests !== "string" && typeof inputRequests !== "object") {
1335
1722
  return Promise.reject(new Error(this.BAD_REQUEST_DATA_TEXT));
@@ -1353,24 +1740,29 @@ var RESTAPI = class extends ApiBase_default {
1353
1740
  throw new Error("It is impossible to make a request!");
1354
1741
  }
1355
1742
  instance.setIsResponseAsObject(isResponseAsObject ?? true);
1356
- if (callback) instance.setCallback(callback);
1743
+ if (typeof callback === "function") instance.setCallback(callback);
1357
1744
  function getRequests() {
1358
1745
  let output;
1359
1746
  if (typeof inputRequests === "string") output = [{ path: inputRequests }];
1360
1747
  else output = Array.isArray(inputRequests) ? inputRequests : [inputRequests];
1361
1748
  function getCallback(item, mesageOptions) {
1362
- const { getBodyAs } = item;
1749
+ const getBodyAs = typeof item.getBodyAs === "string" ? item.getBodyAs : void 0;
1363
1750
  const finalIsGetBody = typeof item.isGetBody === "boolean" || typeof item.isGetBody === "string" ? item.isGetBody : isGetBody;
1364
1751
  const finalIsGetBodyFirst = finalIsGetBody === "first";
1365
- const checkResponseCallback = finalIsGetBodyFirst ? async (res, mesageOptions2) => API_CONTEXT.getResponseBody(await API_CONTEXT.checkResponseCode(res, mesageOptions2), getBodyAs) : async (res, mesageOptions2) => API_CONTEXT.checkResponseCode(res, mesageOptions2);
1366
- const callback2 = item.callback ? async (res) => item.callback(await checkResponseCallback(res, mesageOptions)) : async (res) => checkResponseCallback(res, mesageOptions);
1367
- return finalIsGetBody && !finalIsGetBodyFirst ? async (res) => API_CONTEXT.getResponseBody(await callback2(res), getBodyAs) : callback2;
1752
+ const checkResponseCallback = finalIsGetBodyFirst ? async (res, options) => API_CONTEXT.getResponseBody(await API_CONTEXT.checkResponseCode(res, options), getBodyAs) : async (res, options) => API_CONTEXT.checkResponseCode(res, options);
1753
+ const itemCallback = item.callback;
1754
+ const callbackFn = typeof itemCallback === "function" ? async (res) => itemCallback(await checkResponseCallback(res, mesageOptions)) : async (res) => checkResponseCallback(res, mesageOptions);
1755
+ return finalIsGetBody && !finalIsGetBodyFirst ? async (res) => API_CONTEXT.getResponseBody(await callbackFn(res), getBodyAs) : callbackFn;
1368
1756
  }
1369
1757
  async function getRequestItem(item, idx) {
1370
- const { type, ...partialRestFirst } = item;
1758
+ const itemObj = getIsOnlyAnObject(item) ? item : { path: item };
1759
+ const { type, ...partialRestFirst } = itemObj;
1371
1760
  const itemAfterRequestCreating = await (async () => {
1372
- const key = `createRequest_${type ?? "default"}`;
1373
- return key in API_CONTEXT ? API_CONTEXT[key](partialRestFirst, "doRequestMapping") : API_CONTEXT.createRequest_default(partialRestFirst, "doRequestMapping");
1761
+ const key = `createRequest_${typeof type === "string" ? type : "default"}`;
1762
+ const creator = key in API_CONTEXT ? API_CONTEXT[key] : void 0;
1763
+ const result = typeof creator === "function" ? creator.call(API_CONTEXT, partialRestFirst, "doRequestMapping") : API_CONTEXT.createRequest_default(partialRestFirst, "doRequestMapping");
1764
+ const awaited = await result;
1765
+ return getIsOnlyAnObject(awaited) ? awaited : {};
1374
1766
  })();
1375
1767
  const { fullPath, api, path, query, queryParameters, ...partialRestSecond } = itemAfterRequestCreating;
1376
1768
  const {
@@ -1386,23 +1778,25 @@ var RESTAPI = class extends ApiBase_default {
1386
1778
  isNoToast,
1387
1779
  ...rest
1388
1780
  } = partialRestSecond;
1781
+ const successMessagesArr = Array.isArray(successMessages) ? successMessages : void 0;
1782
+ const errorMessagesArr = Array.isArray(errorMessages) ? errorMessages : void 0;
1389
1783
  const useSuccessMessageFlag = Boolean(
1390
- successMess || commonSuccessMessage || successMessages?.[idx] || CSMfromSettings || isToastResult || isToastFromSettings
1784
+ successMess || commonSuccessMessage || successMessagesArr?.[idx] || CSMfromSettings || isToastResult || isToastFromSettings
1391
1785
  );
1392
1786
  const isUseSuccessToast = useSuccessMessageFlag && !isNoToast && !isNoToastFromSettings && !isNoToastSuccess && !isNTSFromSettings;
1393
1787
  const isUseErrorToast = !isNoToast && !isNoToastFromSettings && !isNoToastError && !isNTEFromSettings;
1394
1788
  const mesageOptions = {
1395
- successMess: successMess || commonSuccessMessage || successMessages?.[idx] || CSMfromSettings,
1789
+ successMess: successMess || commonSuccessMessage || successMessagesArr?.[idx] || CSMfromSettings,
1396
1790
  successMessageType: successMessageType || SMTfromSettings,
1397
- errorMess: errorMess || commonErrorMessage || errorMessages?.[idx] || CEMfromSettings,
1791
+ errorMess: errorMess || commonErrorMessage || errorMessagesArr?.[idx] || CEMfromSettings,
1398
1792
  isUseSuccessToast,
1399
1793
  isUseErrorToast,
1400
1794
  toastOptions: toastOptions || TOFomSettings
1401
1795
  };
1402
1796
  return {
1403
1797
  ...rest,
1404
- path: `${fullPath || await API_CONTEXT.getRootPath(api) + (path || "")}`,
1405
- //? Запускаем самовызывающуюся асинхронную ф-ю, ждем резолва промиса от нее
1798
+ path: `${fullPath || await API_CONTEXT.getRootPath() + (typeof path === "string" ? path : "")}`,
1799
+ // ? Запускаем самовызывающуюся асинхронную ф-ю, ждем резолва промиса от нее
1406
1800
  queryParameters: await (async () => {
1407
1801
  const queryParams = query || queryParameters || "";
1408
1802
  const preparedQueryParams = await API_CONTEXT.processQueryParams(queryParams);
@@ -1412,16 +1806,25 @@ var RESTAPI = class extends ApiBase_default {
1412
1806
  callback: getCallback(itemAfterRequestCreating, mesageOptions)
1413
1807
  };
1414
1808
  }
1415
- return output?.map((item, idx) => getRequestItem(item, idx));
1809
+ return output.map((item, idx) => getRequestItem(item, idx));
1416
1810
  }
1417
1811
  return instance.request(await Promise.all(getRequests()));
1418
1812
  }
1419
- //! Метод API для одиночных запросов
1813
+ /**
1814
+ * Метод API для одиночных запросов: применяет крейтер по `type` и делегирует в {@link RESTAPI.doRequest}.
1815
+ *
1816
+ * @param requestSettings - объект описания одиночного запроса (с необязательным `type`).
1817
+ * @returns Промис с результатом запроса.
1818
+ */
1819
+ // ! Метод API для одиночных запросов
1420
1820
  async doMonoRequest(requestSettings) {
1421
1821
  if (!getIsOnlyAnObject(requestSettings)) throw new Error(`${this.BAD_REQUEST_DATA_TEXT} [RESTAPI.doMonoRequest]`);
1422
1822
  const { type, ...requestSettingsRest } = requestSettings;
1423
- const doRequestArgs = type && this[`createRequest_${type}`] ? [...await this[`createRequest_${type}`](requestSettingsRest)] : [...await this.createRequest_default(requestSettingsRest)];
1424
- return this.doRequest(...doRequestArgs);
1823
+ const key = `createRequest_${typeof type === "string" ? type : ""}`;
1824
+ const creator = type && key in this ? this[key] : void 0;
1825
+ const created = typeof creator === "function" ? await creator.call(this, requestSettingsRest) : await this.createRequest_default(requestSettingsRest);
1826
+ const doRequestArgs = Array.isArray(created) ? created : [created];
1827
+ return this.doRequest(doRequestArgs[0], doRequestArgs[1]);
1425
1828
  }
1426
1829
  };
1427
1830
  var RESTAPI_default = RESTAPI;
@@ -1430,15 +1833,4 @@ export {
1430
1833
  AnimatedHandler_default as AnimatedHandler,
1431
1834
  RESTAPI_default as RESTAPI
1432
1835
  };
1433
- //! При получении экземпляра, если sendMessage не является ф-ей,
1434
- //! то это воспринимается как отключение шага информирования об ошибке запроса как такового
1435
- //! Планируемая структура { headers, queryParameters, options }, где
1436
- //! - headers и options - объекты,
1437
- //! - queryParameters - строка, массив или объект
1438
- //! ВНИМАНИЕ! Данный механизм рефреша принят на проекте finturfreactfrontend (админка)
1439
- //! На кабинете он ТОЧНО НЕ ТАКОЙ
1440
- //! currentCredentials передаются в формате класса! ({ token, refreshToken, expires })
1441
- //! Наличие credentialsProcessing подключает ДОБАВЛЕНИЕ ТОКЕНОВ В ЗАПРОСЫ,
1442
- //! НО по умолчанию НЕ добавляет флоу рефреша токенов
1443
- //! (флоу рефреша подключается пропой isUseRefreshTokensPropcessing из credentialsProcessing)
1444
1836
  //# sourceMappingURL=classes.js.map