bx-rest 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +177 -0
- package/README.en.md +116 -5
- package/README.md +117 -5
- package/esm2022/functions/errors.mjs +17 -5
- package/esm2022/functions/mapResult.mjs +4 -2
- package/esm2022/functions/uniqueElementCode.mjs +24 -0
- package/esm2022/map/disk.mjs +13 -0
- package/esm2022/map/im/recent.mjs +1 -9
- package/esm2022/map/task.mjs +11 -5
- package/esm2022/map/tasks/task.mjs +3 -3
- package/esm2022/map/tasks.mjs +4 -3
- package/esm2022/map/user.mjs +5 -4
- package/esm2022/public-api.mjs +2 -2
- package/esm2022/request-navvy/bizproc.mjs +19 -10
- package/esm2022/request-navvy/calendar/event.mjs +1 -9
- package/esm2022/request-navvy/disk/operation.mjs +3 -10
- package/esm2022/request-navvy/pull/config.mjs +1 -3
- package/esm2022/request-navvy/socialnetwork/api/livefeed.mjs +1 -5
- package/esm2022/request-navvy/task/operation/elapseditem.mjs +14 -71
- package/esm2022/request-navvy/tasks/task.mjs +1 -119
- package/esm2022/rest/map.mjs +3 -3
- package/esm2022/rest/navvy.mjs +66 -64
- package/esm2022/services/base.mjs +7 -7
- package/esm2022/services/context.mjs +59 -0
- package/esm2022/services/http/HttpBX.mjs +55 -20
- package/esm2022/services/http/authRefresh.mjs +25 -23
- package/esm2022/services/http/http.mjs +14 -69
- package/esm2022/services/http/middleware.mjs +149 -0
- package/esm2022/services/http/sessionKey.mjs +16 -5
- package/esm2022/services/http/transport.mjs +5 -0
- package/esm2022/services/navvy/extends/navvy-pag-base.mjs +63 -9
- package/esm2022/services/navvy/navvy-alternative-pagination-navigation.mjs +21 -71
- package/esm2022/services/navvy/navvy-pag-nav-result-key-object.mjs +10 -49
- package/esm2022/services/navvy/navvy-pag-nav-result-key.mjs +14 -73
- package/esm2022/services/navvy/navvy-pag-nav-tasks.mjs +4 -76
- package/esm2022/services/navvy/navvy-pag-nav-with-useless-key.mjs +10 -76
- package/esm2022/services/navvy/navvy-pag.mjs +7 -65
- package/esm2022/services/navvy/navvy-support.mjs +2 -15
- package/esm2022/services/navvy.mjs +18 -31
- package/esm2022/typification/rest/calendar/event/get.mjs +1 -1
- package/esm2022/typification/rest/settings.mjs +1 -1
- package/esm2022/typification/rest/tasks/task/get.mjs +1 -1
- package/esm2022/typification/rest/user/user.mjs +1 -1
- package/esm2022/typification/settings.mjs +1 -1
- package/fesm2022/bx-rest.mjs +860 -2038
- package/fesm2022/bx-rest.mjs.map +1 -1
- package/functions/errors.d.ts +9 -0
- package/functions/uniqueElementCode.d.ts +12 -0
- package/map/disk.d.ts +10 -0
- package/map/task.d.ts +3 -3
- package/map/tasks/task.d.ts +1 -1
- package/map/tasks.d.ts +1 -1
- package/package.json +5 -2
- package/public-api.d.ts +7 -3
- package/request-navvy/pull/config.d.ts +0 -2
- package/rest/map.d.ts +2 -2
- package/rest/navvy.d.ts +9 -0
- package/services/context.d.ts +43 -0
- package/services/http/HttpBX.d.ts +10 -0
- package/services/http/authRefresh.d.ts +5 -1
- package/services/http/http.d.ts +12 -9
- package/services/http/middleware.d.ts +31 -0
- package/services/http/sessionKey.d.ts +10 -0
- package/services/http/transport.d.ts +28 -0
- package/services/navvy/extends/navvy-pag-base.d.ts +16 -2
- package/services/navvy/navvy-alternative-pagination-navigation.d.ts +5 -2
- package/services/navvy/navvy-pag-nav-result-key-object.d.ts +0 -2
- package/services/navvy/navvy-pag-nav-result-key.d.ts +1 -4
- package/services/navvy/navvy-pag-nav-tasks.d.ts +2 -9
- package/services/navvy/navvy-pag-nav-with-useless-key.d.ts +0 -2
- package/services/navvy/navvy-pag.d.ts +0 -2
- package/services/navvy/navvy-support.d.ts +0 -10
- package/services/navvy.d.ts +1 -0
- package/typification/rest/calendar/event/get.d.ts +1 -1
- package/typification/rest/settings.d.ts +1 -0
- package/typification/rest/user/user.d.ts +3 -3
- package/typification/settings.d.ts +34 -0
- package/esm2022/functions/errorHandler.mjs +0 -34
- package/esm2022/request/app.mjs +0 -13
- package/esm2022/request/bizproc/activity.mjs +0 -3
- package/esm2022/request/bizproc/event.mjs +0 -3
- package/esm2022/request/bizproc/robot.mjs +0 -3
- package/esm2022/request/bizproc/task.mjs +0 -3
- package/esm2022/request/bizproc/workflow/instance.mjs +0 -3
- package/esm2022/request/bizproc/workflow/template.mjs +0 -3
- package/esm2022/request/bizproc/workflow.mjs +0 -18
- package/esm2022/request/bizproc.mjs +0 -15
- package/esm2022/request/department.mjs +0 -26
- package/esm2022/request/disk/attachedObject.mjs +0 -14
- package/esm2022/request/disk/file.mjs +0 -18
- package/esm2022/request/disk/folder.mjs +0 -117
- package/esm2022/request/disk.mjs +0 -11
- package/esm2022/request/lists/element.mjs +0 -18
- package/esm2022/request/lists/field.mjs +0 -35
- package/esm2022/request/lists.mjs +0 -86
- package/esm2022/request/log/blogcomment.mjs +0 -3
- package/esm2022/request/log/blogpost.mjs +0 -18
- package/esm2022/request/log.mjs +0 -9
- package/esm2022/request/pull/application/config.mjs +0 -11
- package/esm2022/request/pull/channel/public.mjs +0 -18
- package/esm2022/request/pull/config.mjs +0 -13
- package/esm2022/request/pull.mjs +0 -11
- package/esm2022/request/server.mjs +0 -14
- package/esm2022/request/socialnetwork/api/contentview.mjs +0 -14
- package/esm2022/request/socialnetwork/api/livefeed/blogpost/important.mjs +0 -14
- package/esm2022/request/socialnetwork/api/livefeed/blogpost.mjs +0 -7
- package/esm2022/request/socialnetwork/api/livefeed.mjs +0 -7
- package/esm2022/request/socialnetwork/api.mjs +0 -9
- package/esm2022/request/socialnetwork.mjs +0 -8
- package/esm2022/request/sonet_group.mjs +0 -24
- package/esm2022/request/task/commentitem.mjs +0 -32
- package/esm2022/request/task/elapseditem.mjs +0 -40
- package/esm2022/request/task/item/userfield.mjs +0 -14
- package/esm2022/request/task/item.mjs +0 -7
- package/esm2022/request/task/planner.mjs +0 -11
- package/esm2022/request/task.mjs +0 -13
- package/esm2022/request/tasks/task/result.mjs +0 -22
- package/esm2022/request/tasks/task.mjs +0 -110
- package/esm2022/request/tasks.mjs +0 -7
- package/esm2022/request/user/userfield.mjs +0 -14
- package/esm2022/request/user.mjs +0 -40
- package/esm2022/rest/base.mjs +0 -39
- package/esm2022/services/http/HttpData.mjs +0 -77
- package/esm2022/services/http/base/base.mjs +0 -4
- package/esm2022/services/http/httpNavvy.mjs +0 -14
- package/esm2022/typification/base/answers.mjs +0 -438
- package/esm2022/typification/base/params.mjs +0 -525
- package/esm2022/typification/base/workpiece/methods-list.mjs +0 -2
- package/esm2022/typification/base/workpiece/methods.mjs +0 -2
- package/functions/errorHandler.d.ts +0 -10
- package/request/app.d.ts +0 -8
- package/request/bizproc/activity.d.ts +0 -2
- package/request/bizproc/event.d.ts +0 -2
- package/request/bizproc/robot.d.ts +0 -2
- package/request/bizproc/task.d.ts +0 -2
- package/request/bizproc/workflow/instance.d.ts +0 -2
- package/request/bizproc/workflow/template.d.ts +0 -2
- package/request/bizproc/workflow.d.ts +0 -13
- package/request/bizproc.d.ts +0 -12
- package/request/department.d.ts +0 -18
- package/request/disk/attachedObject.d.ts +0 -8
- package/request/disk/file.d.ts +0 -10
- package/request/disk/folder.d.ts +0 -96
- package/request/disk.d.ts +0 -8
- package/request/lists/element.d.ts +0 -11
- package/request/lists/field.d.ts +0 -11
- package/request/lists.d.ts +0 -31
- package/request/log/blogcomment.d.ts +0 -2
- package/request/log/blogpost.d.ts +0 -11
- package/request/log.d.ts +0 -6
- package/request/pull/application/config.d.ts +0 -5
- package/request/pull/channel/public.d.ts +0 -5
- package/request/pull/config.d.ts +0 -7
- package/request/pull.d.ts +0 -8
- package/request/server.d.ts +0 -7
- package/request/socialnetwork/api/contentview.d.ts +0 -6
- package/request/socialnetwork/api/livefeed/blogpost/important.d.ts +0 -6
- package/request/socialnetwork/api/livefeed/blogpost.d.ts +0 -4
- package/request/socialnetwork/api/livefeed.d.ts +0 -4
- package/request/socialnetwork/api.d.ts +0 -6
- package/request/socialnetwork.d.ts +0 -4
- package/request/sonet_group.d.ts +0 -8
- package/request/task/commentitem.d.ts +0 -23
- package/request/task/elapseditem.d.ts +0 -26
- package/request/task/item/userfield.d.ts +0 -6
- package/request/task/item.d.ts +0 -4
- package/request/task/planner.d.ts +0 -4
- package/request/task.d.ts +0 -10
- package/request/tasks/task/result.d.ts +0 -13
- package/request/tasks/task.d.ts +0 -37
- package/request/tasks.d.ts +0 -4
- package/request/user/userfield.d.ts +0 -8
- package/request/user.d.ts +0 -24
- package/rest/base.d.ts +0 -33
- package/services/http/HttpData.d.ts +0 -7
- package/services/http/base/base.d.ts +0 -7
- package/services/http/httpNavvy.d.ts +0 -10
- package/typification/base/answers.d.ts +0 -12
- package/typification/base/params.d.ts +0 -16
- package/typification/base/workpiece/methods-list.d.ts +0 -247
- package/typification/base/workpiece/methods.d.ts +0 -20
package/fesm2022/bx-rest.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Subscription, of, defer, throwError, from, forkJoin, Observable, concatMap, toArray, mergeMap, shareReplay, tap, catchError as catchError$1 } from 'rxjs';
|
|
2
|
+
import { catchError, switchMap, map, take, mergeMap as mergeMap$1 } from 'rxjs/operators';
|
|
3
3
|
import clone from 'just-clone';
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import flatten from 'just-flatten-it';
|
|
6
6
|
import { stringify } from 'qs-esm';
|
|
7
7
|
import values from 'just-values';
|
|
8
8
|
import camelCase from 'just-camel-case';
|
|
9
|
-
import { __decorate } from 'tslib';
|
|
10
9
|
|
|
11
10
|
const DEFAULT_BX_REST_SETTINGS = {
|
|
12
11
|
auth: {
|
|
@@ -55,7 +54,9 @@ function BXRestMapResult(v) {
|
|
|
55
54
|
return undefined;
|
|
56
55
|
}
|
|
57
56
|
function instanceOfiBXRestAnswerSuccess(object) {
|
|
58
|
-
|
|
57
|
+
// Без проверки типа `in` бросает TypeError на строке, числе и null вместо false.
|
|
58
|
+
// Строка приходит, если вместо Bitrix ответил прокси: HTML axios отдаёт текстом
|
|
59
|
+
return typeof object === 'object' && object !== null && 'result' in object;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
function toLocalAtom(date) {
|
|
@@ -215,8 +216,12 @@ function parseDateWithFormat(val, format) {
|
|
|
215
216
|
if (month < 1 || month > 12 || day < 1 || day > 31 || hour > 23 || minute > 59 || second > 59) {
|
|
216
217
|
return null;
|
|
217
218
|
}
|
|
219
|
+
return buildDate(year, month, day, hour, minute, second);
|
|
220
|
+
}
|
|
221
|
+
/** Собирает дату, отбрасывая несуществующие дни месяца: new Date() превратил бы 31 февраля в 3 марта. */
|
|
222
|
+
function buildDate(year, month, day, hour, minute, second) {
|
|
218
223
|
const date = new Date(year, month - 1, day, hour, minute, second);
|
|
219
|
-
return isNaN(date.getTime()) ? null : date;
|
|
224
|
+
return (isNaN(date.getTime()) || date.getMonth() !== month - 1 || date.getDate() !== day) ? null : date;
|
|
220
225
|
}
|
|
221
226
|
/**
|
|
222
227
|
* Последний резервный разбор — без знания конкретного формата. Работает только для чисто
|
|
@@ -259,8 +264,7 @@ function parseDateHeuristically(val) {
|
|
|
259
264
|
if (hour > 23 || minute > 59 || second > 59) {
|
|
260
265
|
return null;
|
|
261
266
|
}
|
|
262
|
-
|
|
263
|
-
return isNaN(date.getTime()) ? null : date;
|
|
267
|
+
return buildDate(year, month, day, hour, minute, second);
|
|
264
268
|
}
|
|
265
269
|
/**
|
|
266
270
|
* Преобразует значение в дату.
|
|
@@ -410,9 +414,6 @@ async function getBase64FileLikeStr(file) {
|
|
|
410
414
|
return undefined;
|
|
411
415
|
}
|
|
412
416
|
function prepareBaseAddress(url, add = '') {
|
|
413
|
-
// if (url.search('https://') !== 0 && url.search('http://')) {
|
|
414
|
-
// url = 'https://' + url
|
|
415
|
-
// }
|
|
416
417
|
if (add && add.length > 0) {
|
|
417
418
|
if (url.lastIndexOf('/') !== (url.length - 1)) {
|
|
418
419
|
url = url + '/';
|
|
@@ -519,6 +520,64 @@ class SessionStorage {
|
|
|
519
520
|
}
|
|
520
521
|
}
|
|
521
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Контекст клиента: его настройки, экземпляр axios и общее состояние
|
|
525
|
+
* продления авторизации и очереди `throttle`.
|
|
526
|
+
*
|
|
527
|
+
* Объекты библиотеки запоминают контекст в момент создания
|
|
528
|
+
* (`currentContext()`), поэтому все запросы клиента `new BXRestNavvy(settings)`
|
|
529
|
+
* идут с его настройками, а не с глобальными. Внутренняя деталь библиотеки.
|
|
530
|
+
*/
|
|
531
|
+
class BXRestContext {
|
|
532
|
+
constructor(own) {
|
|
533
|
+
this.own = own;
|
|
534
|
+
/** Сколько продлений уже завершилось успешно. */
|
|
535
|
+
this.refreshCount = 0;
|
|
536
|
+
/** Очередь `throttle`: когда можно отправить следующий запрос клиента (мс, Date.now()). */
|
|
537
|
+
this.throttleNextSlot = 0;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Свои настройки клиента, а без них — глобальные `BXRestSettings.value`,
|
|
541
|
+
* прочитанные в момент обращения: `BXRestSettings.update()` заменяет объект.
|
|
542
|
+
*/
|
|
543
|
+
get settings() {
|
|
544
|
+
return this.own ?? BXRestSettings.value;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Контекст глобальных настроек. С ним работают `new BXRestNavvy()` без
|
|
549
|
+
* аргумента и объекты, созданные приложением напрямую (`new Navvy()`,
|
|
550
|
+
* `new BXRestRequest()`).
|
|
551
|
+
*/
|
|
552
|
+
const globalContext = /* @__PURE__ */ new BXRestContext();
|
|
553
|
+
let current = globalContext;
|
|
554
|
+
function currentContext() {
|
|
555
|
+
return current;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Делает `ctx` текущим и возвращает прежний контекст. Вызывающий обязан
|
|
559
|
+
* вернуть его через `restoreContext()` в `finally`: иначе после исключения
|
|
560
|
+
* чужие настройки достанутся объектам, созданным позже.
|
|
561
|
+
*/
|
|
562
|
+
function enterContext(ctx) {
|
|
563
|
+
const previous = current;
|
|
564
|
+
current = ctx;
|
|
565
|
+
return previous;
|
|
566
|
+
}
|
|
567
|
+
function restoreContext(previous) {
|
|
568
|
+
current = previous;
|
|
569
|
+
}
|
|
570
|
+
/** Создаёт объекты в контексте `ctx` и возвращает прежний контекст, даже при исключении. */
|
|
571
|
+
function runInContext(ctx, build) {
|
|
572
|
+
const previous = enterContext(ctx);
|
|
573
|
+
try {
|
|
574
|
+
return build();
|
|
575
|
+
}
|
|
576
|
+
finally {
|
|
577
|
+
restoreContext(previous);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
522
581
|
class SessionKeyError extends Error {
|
|
523
582
|
constructor(message) {
|
|
524
583
|
super(message);
|
|
@@ -530,12 +589,18 @@ class SessionKeyServices {
|
|
|
530
589
|
// НОВЫЙ объект (this.value = {...this.value, ...}), а не мутирует старый —
|
|
531
590
|
// поэтому `= BXRestSettings.value` в виде обычного поля навсегда
|
|
532
591
|
// "заморозил" бы то, что было на момент создания SessionKeyServices.
|
|
533
|
-
// Геттер вместо этого читает
|
|
534
|
-
//
|
|
592
|
+
// Геттер вместо этого читает актуальные настройки при каждом обращении:
|
|
593
|
+
// свои настройки клиента или глобальные BXRestSettings.value.
|
|
535
594
|
get BX_REST_SETTINGS() {
|
|
536
|
-
return
|
|
595
|
+
return this.ctx.settings;
|
|
537
596
|
}
|
|
538
597
|
constructor() {
|
|
598
|
+
/**
|
|
599
|
+
* Контекст клиента, в котором создан объект: внутри `new BXRestNavvy(settings)`
|
|
600
|
+
* — контекст этого клиента, в остальных случаях — глобальные настройки.
|
|
601
|
+
* Объявлен первым: конструктор ниже уже читает настройки.
|
|
602
|
+
*/
|
|
603
|
+
this.ctx = currentContext();
|
|
539
604
|
this.authHave = false;
|
|
540
605
|
this.subscribe = {
|
|
541
606
|
authData: new Subscription()
|
|
@@ -594,6 +659,10 @@ class SessionKeyServices {
|
|
|
594
659
|
getHeaders() {
|
|
595
660
|
return { ...this.BX_REST_SETTINGS.headers };
|
|
596
661
|
}
|
|
662
|
+
/** Свои middleware из настроек (`middleware`), читаются при каждом запросе — как и остальные настройки. */
|
|
663
|
+
getMiddleware() {
|
|
664
|
+
return this.BX_REST_SETTINGS.middleware ?? [];
|
|
665
|
+
}
|
|
597
666
|
getSessid() {
|
|
598
667
|
const check = this.getSearchParam('sessid');
|
|
599
668
|
if (check) {
|
|
@@ -759,151 +828,21 @@ class SessionKeyServices {
|
|
|
759
828
|
}
|
|
760
829
|
}
|
|
761
830
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
levelOut: false
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
}
|
|
771
|
-
getHttpParamsPost(obj, sendHttpParams = new FormData(), nesting = [], settings = this.defSettings) {
|
|
772
|
-
if (obj instanceof Blob) {
|
|
773
|
-
let first = nesting[0];
|
|
774
|
-
let setKey = (nesting.length > 1)
|
|
775
|
-
? first + '[' + nesting.slice(1).join('][') + ']'
|
|
776
|
-
: first;
|
|
777
|
-
sendHttpParams.set(setKey, obj);
|
|
778
|
-
return sendHttpParams;
|
|
779
|
-
}
|
|
780
|
-
else if (obj instanceof Date) {
|
|
781
|
-
let first = nesting[0];
|
|
782
|
-
let tzoffset = (settings.timeZone.calc) ? obj.getTimezoneOffset() * 60000 : 0; // вычисляем влияние часового пояса
|
|
783
|
-
let levelOut = (settings.timeZone.levelOut) ? obj.getTimezoneOffset() * 60000 : 0; // вычисляем влияние часового пояса
|
|
784
|
-
let setKey = (nesting.length > 1)
|
|
785
|
-
? first + '[' + nesting.slice(1).join('][') + ']'
|
|
786
|
-
: first;
|
|
787
|
-
sendHttpParams.set(setKey, (new Date(obj.valueOf() + tzoffset - levelOut)).toISOString());
|
|
788
|
-
return sendHttpParams;
|
|
789
|
-
}
|
|
790
|
-
else {
|
|
791
|
-
for (const key in obj) {
|
|
792
|
-
let setKey = '';
|
|
793
|
-
if (nesting.length) {
|
|
794
|
-
let first = nesting[0];
|
|
795
|
-
setKey = (nesting.length > 1)
|
|
796
|
-
? first + '[' + nesting.slice(1).join('][') + '][' + key + ']'
|
|
797
|
-
: first + '[' + key + ']';
|
|
798
|
-
}
|
|
799
|
-
else {
|
|
800
|
-
setKey = key;
|
|
801
|
-
}
|
|
802
|
-
switch (typeof obj[key]) {
|
|
803
|
-
case 'string':
|
|
804
|
-
sendHttpParams.set(setKey, obj[key]);
|
|
805
|
-
break;
|
|
806
|
-
case 'symbol':
|
|
807
|
-
case 'number':
|
|
808
|
-
case 'bigint':
|
|
809
|
-
case 'boolean':
|
|
810
|
-
sendHttpParams.set(setKey, String(obj[key]));
|
|
811
|
-
break;
|
|
812
|
-
case 'object':
|
|
813
|
-
nesting.push(key);
|
|
814
|
-
sendHttpParams = this.getHttpParamsPost(obj[key], sendHttpParams, nesting, settings);
|
|
815
|
-
nesting.pop();
|
|
816
|
-
break;
|
|
817
|
-
case 'function':
|
|
818
|
-
case 'undefined':
|
|
819
|
-
default:
|
|
820
|
-
console.error('You sent something wrong', obj[key], typeof obj[key], typeof obj);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
return sendHttpParams;
|
|
825
|
-
}
|
|
826
|
-
sliceArrayIntoChunks(arr, chunkSize) {
|
|
827
|
-
const res = [];
|
|
828
|
-
for (let i = 0; i < arr.length; i += chunkSize) {
|
|
829
|
-
const chunk = arr.slice(i, i + chunkSize);
|
|
830
|
-
res.push(chunk);
|
|
831
|
-
}
|
|
832
|
-
return res;
|
|
833
|
-
}
|
|
834
|
-
removingMultipleSlashes(str) {
|
|
835
|
-
return str.replace(/\/{2,}/g, '/');
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
class BaseHttp extends HttpData {
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
class HttpServices extends BaseHttp {
|
|
831
|
+
/**
|
|
832
|
+
* Общая часть HTTP-клиента: экземпляр axios и источник токена и адреса.
|
|
833
|
+
* Сами запросы отправляет `HttpBXServices` (`BXRestRequest`).
|
|
834
|
+
*/
|
|
835
|
+
class HttpServices {
|
|
843
836
|
constructor() {
|
|
844
|
-
super();
|
|
845
837
|
this.session = new SessionKeyServices();
|
|
846
|
-
this.axiosInstance = axios.create();
|
|
847
|
-
}
|
|
848
|
-
httpPost(url, params = {}, settings = this.defSettings) {
|
|
849
|
-
const auth = this.session.getAuthParams();
|
|
850
|
-
const checkIsOn = this.session.getCheckAuthParamsIsOn();
|
|
851
|
-
const paramsClone = clone(params);
|
|
852
|
-
if (checkIsOn) {
|
|
853
|
-
if (!auth) {
|
|
854
|
-
return throwError(() => this.session.getAuthError('post'));
|
|
855
|
-
}
|
|
856
|
-
paramsClone[this.session.getKeyAuth()] = auth;
|
|
857
|
-
}
|
|
858
|
-
return this.session.getBaseUrl().pipe(switchMap((baseUrl) => {
|
|
859
|
-
if (!baseUrl) {
|
|
860
|
-
return throwError(() => this.session.getBaseUrlError('post'));
|
|
861
|
-
}
|
|
862
|
-
const fullUrl = prepareBaseAddress(baseUrl) + url;
|
|
863
|
-
if (this.session.getKeyAuth() === 'sessid') {
|
|
864
|
-
const urlEncodedBody = new URLSearchParams();
|
|
865
|
-
Object.keys(paramsClone).forEach((key) => {
|
|
866
|
-
const value = paramsClone[key];
|
|
867
|
-
if (typeof value === 'object' && value !== null) {
|
|
868
|
-
for (const subKey in value) {
|
|
869
|
-
if (Object.prototype.hasOwnProperty.call(value, subKey)) {
|
|
870
|
-
urlEncodedBody.append(`${key}[${subKey}]`, value[subKey]);
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
else {
|
|
875
|
-
urlEncodedBody.append(key, value);
|
|
876
|
-
}
|
|
877
|
-
});
|
|
878
|
-
return from(this.axiosInstance.post(fullUrl, urlEncodedBody.toString(), {
|
|
879
|
-
headers: {
|
|
880
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
881
|
-
},
|
|
882
|
-
}).then((response) => response.data));
|
|
883
|
-
}
|
|
884
|
-
const body = this.getHttpParamsPost(paramsClone, new FormData(), [], settings);
|
|
885
|
-
return from(this.axiosInstance.post(fullUrl, body).then((response) => response.data));
|
|
886
|
-
}));
|
|
887
838
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
paramsClone[this.session.getKeyAuth()] = auth;
|
|
897
|
-
}
|
|
898
|
-
return this.session.getBaseUrl().pipe(switchMap((baseUrl) => {
|
|
899
|
-
if (!baseUrl) {
|
|
900
|
-
return throwError(() => this.session.getBaseUrlError('get'));
|
|
901
|
-
}
|
|
902
|
-
const fullUrl = prepareBaseAddress(baseUrl) + url;
|
|
903
|
-
const queryString = new URLSearchParams(paramsClone).toString();
|
|
904
|
-
const finalUrl = `${fullUrl}?${queryString}`;
|
|
905
|
-
return from(this.axiosInstance.get(finalUrl).then((response) => response.data));
|
|
906
|
-
}));
|
|
839
|
+
/**
|
|
840
|
+
* Экземпляр axios клиента. Один на контекст (клиента со своими настройками
|
|
841
|
+
* или глобальные настройки) и создаётся при первом запросе — раньше каждый
|
|
842
|
+
* объект запроса создавал свой.
|
|
843
|
+
*/
|
|
844
|
+
get axiosInstance() {
|
|
845
|
+
return this.session.ctx.axios ??= axios.create();
|
|
907
846
|
}
|
|
908
847
|
}
|
|
909
848
|
|
|
@@ -1004,20 +943,33 @@ function parseBXRestErrorBody(body) {
|
|
|
1004
943
|
* Bitrix error body, so the caller can keep its own handling for them.
|
|
1005
944
|
*/
|
|
1006
945
|
function bxRestApiErrorFromHttp(err, method) {
|
|
1007
|
-
|
|
946
|
+
const response = httpErrorResponse(err);
|
|
947
|
+
if (!response) {
|
|
1008
948
|
return undefined;
|
|
1009
949
|
}
|
|
1010
|
-
const parsed = parseBXRestErrorBody(
|
|
950
|
+
const parsed = parseBXRestErrorBody(response.data);
|
|
1011
951
|
if (!parsed) {
|
|
1012
952
|
return undefined;
|
|
1013
953
|
}
|
|
1014
954
|
return new BXRestApiError(parsed.error, parsed.error_description, {
|
|
1015
|
-
status:
|
|
955
|
+
status: response.status,
|
|
1016
956
|
method,
|
|
1017
957
|
cause: err,
|
|
1018
958
|
authRefreshError: getAuthRefreshError(err)
|
|
1019
959
|
});
|
|
1020
960
|
}
|
|
961
|
+
/**
|
|
962
|
+
* HTTP-ответ из ошибки транспорта: `response: { status, data }`. Так устроен
|
|
963
|
+
* `AxiosError`, и так же должны отклоняться свои транспорты (middleware).
|
|
964
|
+
* Для сетевых ошибок, отмены и прочих ошибок — `undefined`.
|
|
965
|
+
*/
|
|
966
|
+
function httpErrorResponse(error) {
|
|
967
|
+
const response = (error && typeof error === 'object') ? error.response : undefined;
|
|
968
|
+
if (!response || typeof response !== 'object' || typeof response.status !== 'number') {
|
|
969
|
+
return undefined;
|
|
970
|
+
}
|
|
971
|
+
return response;
|
|
972
|
+
}
|
|
1021
973
|
|
|
1022
974
|
/**
|
|
1023
975
|
* Коды ошибок Bitrix, которые лечатся продлением токена. `expired_token` —
|
|
@@ -1040,34 +992,34 @@ const AUTH_ERROR_CODES = ['expired_token', 'invalid_token'];
|
|
|
1040
992
|
* Ответ 401 с другим кодом Bitrix ошибкой авторизации не считается.
|
|
1041
993
|
*/
|
|
1042
994
|
function isBXRestAuthError(error) {
|
|
1043
|
-
|
|
995
|
+
const response = httpErrorResponse(error);
|
|
996
|
+
if (!response) {
|
|
1044
997
|
return false;
|
|
1045
998
|
}
|
|
1046
|
-
const parsed = parseBXRestErrorBody(
|
|
999
|
+
const parsed = parseBXRestErrorBody(response.data);
|
|
1047
1000
|
if (parsed) {
|
|
1048
1001
|
return AUTH_ERROR_CODES.includes(parsed.error);
|
|
1049
1002
|
}
|
|
1050
|
-
return
|
|
1003
|
+
return response.status === 401;
|
|
1051
1004
|
}
|
|
1052
|
-
//
|
|
1053
|
-
//
|
|
1054
|
-
//
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
pendingRefresh = Promise.resolve()
|
|
1005
|
+
// Состояние продления живёт в контексте клиента (BXRestContext): у глобальных
|
|
1006
|
+
// настроек оно одно на всю библиотеку, у каждого new BXRestNavvy(settings) —
|
|
1007
|
+
// своё. pendingRefresh — идущее сейчас продление, его ждут все упавшие
|
|
1008
|
+
// запросы клиента; refreshCount — сколько продлений уже завершилось успешно.
|
|
1009
|
+
function sharedRefresh(refresh, ctx) {
|
|
1010
|
+
if (!ctx.pendingRefresh) {
|
|
1011
|
+
ctx.pendingRefresh = Promise.resolve()
|
|
1060
1012
|
// Через then, чтобы синхронное исключение в refresh() тоже стало
|
|
1061
1013
|
// отклонённым промисом, а не вылетело из catchError
|
|
1062
1014
|
.then(() => refresh())
|
|
1063
1015
|
.then(() => {
|
|
1064
|
-
refreshCount++;
|
|
1016
|
+
ctx.refreshCount++;
|
|
1065
1017
|
})
|
|
1066
1018
|
.finally(() => {
|
|
1067
|
-
pendingRefresh = undefined;
|
|
1019
|
+
ctx.pendingRefresh = undefined;
|
|
1068
1020
|
});
|
|
1069
1021
|
}
|
|
1070
|
-
return pendingRefresh;
|
|
1022
|
+
return ctx.pendingRefresh;
|
|
1071
1023
|
}
|
|
1072
1024
|
/**
|
|
1073
1025
|
* Повтор запроса после продления авторизации (`BXRestSettings.auth.refresh`).
|
|
@@ -1076,23 +1028,26 @@ function sharedRefresh(refresh) {
|
|
|
1076
1028
|
* `defer()` в HttpBXServices): повтор — это повторная подписка, поэтому
|
|
1077
1029
|
* токен, адрес и заголовки берутся уже новые. На второй попытке ошибка не
|
|
1078
1030
|
* перехватывается — запрос повторяется не больше одного раза.
|
|
1031
|
+
*
|
|
1032
|
+
* `ctx` — контекст клиента, из которого берутся `refresh`, `isAuthError` и
|
|
1033
|
+
* общее состояние продления.
|
|
1079
1034
|
*/
|
|
1080
|
-
function withAuthRefresh(request
|
|
1035
|
+
function withAuthRefresh(request$, ctx = globalContext) {
|
|
1081
1036
|
return defer(() => {
|
|
1082
|
-
const { refresh, isAuthError = isBXRestAuthError } =
|
|
1037
|
+
const { refresh, isAuthError = isBXRestAuthError } = ctx.settings.auth;
|
|
1083
1038
|
if (!refresh) {
|
|
1084
1039
|
return request$;
|
|
1085
1040
|
}
|
|
1086
|
-
const refreshCountAtStart = refreshCount;
|
|
1041
|
+
const refreshCountAtStart = ctx.refreshCount;
|
|
1087
1042
|
return request$.pipe(catchError((error) => {
|
|
1088
1043
|
if (!isAuthError(error)) {
|
|
1089
1044
|
return throwError(() => error);
|
|
1090
1045
|
}
|
|
1091
1046
|
// Пока этот запрос был в пути, токен уже продлили по ошибке другого
|
|
1092
1047
|
// запроса — повторяем без нового продления
|
|
1093
|
-
const refreshed = (refreshCount !== refreshCountAtStart)
|
|
1048
|
+
const refreshed = (ctx.refreshCount !== refreshCountAtStart)
|
|
1094
1049
|
? Promise.resolve()
|
|
1095
|
-
: sharedRefresh(refresh);
|
|
1050
|
+
: sharedRefresh(refresh, ctx);
|
|
1096
1051
|
return from(refreshed).pipe(catchError((refreshError) => {
|
|
1097
1052
|
if (error && typeof error === 'object') {
|
|
1098
1053
|
error.authRefreshError = refreshError;
|
|
@@ -1103,6 +1058,159 @@ function withAuthRefresh(request$) {
|
|
|
1103
1058
|
});
|
|
1104
1059
|
}
|
|
1105
1060
|
|
|
1061
|
+
/** Первый middleware в списке — внешний: он первым видит запрос и последним — ответ. */
|
|
1062
|
+
function composeMiddleware(middleware, terminal) {
|
|
1063
|
+
return middleware.reduceRight((next, step) => config => step(config, next), terminal);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/** `retryOnQueryLimit: true`: всего 3 попытки, пауза перед второй — 1000 мс, дальше вдвое больше. */
|
|
1067
|
+
const DEFAULT_RETRY_ON_QUERY_LIMIT = { attempts: 3, delay: 1000 };
|
|
1068
|
+
/** `timeout: true`: 60 000 мс на один HTTP-запрос. */
|
|
1069
|
+
const DEFAULT_TIMEOUT$1 = 60_000;
|
|
1070
|
+
/** `throttle: true`: 2 запроса в секунду — лимит Bitrix24 на обычных тарифах. */
|
|
1071
|
+
const DEFAULT_THROTTLE = { perSecond: 2 };
|
|
1072
|
+
/**
|
|
1073
|
+
* Запрос не завершился за время из `timeout` в настройках. В `.resVanilla()`
|
|
1074
|
+
* приходит сама эта ошибка, в `.res()` — в `cause`.
|
|
1075
|
+
*/
|
|
1076
|
+
class BXRestTimeoutError extends Error {
|
|
1077
|
+
constructor(timeout) {
|
|
1078
|
+
super(`The request did not finish in ${timeout} ms`);
|
|
1079
|
+
this.timeout = timeout;
|
|
1080
|
+
this.name = 'BXRestTimeoutError';
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Встроенные шаги из настроек, в этом порядке: повтор, очередь, таймаут.
|
|
1085
|
+
* Повтор — снаружи: каждая попытка заново встаёт в очередь и получает свой
|
|
1086
|
+
* таймаут. Таймаут — внутри очереди: ожидание своей очереди его не тратит.
|
|
1087
|
+
*/
|
|
1088
|
+
function builtInMiddleware(settings, state) {
|
|
1089
|
+
const steps = [];
|
|
1090
|
+
if (settings.retryOnQueryLimit) {
|
|
1091
|
+
const own = (settings.retryOnQueryLimit === true) ? {} : settings.retryOnQueryLimit;
|
|
1092
|
+
const attempts = own.attempts ?? DEFAULT_RETRY_ON_QUERY_LIMIT.attempts;
|
|
1093
|
+
const delay = own.delay ?? DEFAULT_RETRY_ON_QUERY_LIMIT.delay;
|
|
1094
|
+
if (!Number.isInteger(attempts) || attempts < 1) {
|
|
1095
|
+
throw invalid('retryOnQueryLimit.attempts', attempts, 'a whole number from 1');
|
|
1096
|
+
}
|
|
1097
|
+
if (!Number.isFinite(delay) || delay < 0) {
|
|
1098
|
+
throw invalid('retryOnQueryLimit.delay', delay, 'a number of milliseconds from 0');
|
|
1099
|
+
}
|
|
1100
|
+
steps.push(retryOnQueryLimit(attempts, delay));
|
|
1101
|
+
}
|
|
1102
|
+
if (settings.throttle) {
|
|
1103
|
+
const own = (settings.throttle === true) ? {} : settings.throttle;
|
|
1104
|
+
const perSecond = own.perSecond ?? DEFAULT_THROTTLE.perSecond;
|
|
1105
|
+
if (!Number.isFinite(perSecond) || perSecond <= 0) {
|
|
1106
|
+
throw invalid('throttle.perSecond', perSecond, 'a number above 0');
|
|
1107
|
+
}
|
|
1108
|
+
steps.push(throttle(perSecond, state));
|
|
1109
|
+
}
|
|
1110
|
+
if (settings.timeout) {
|
|
1111
|
+
const ms = (settings.timeout === true) ? DEFAULT_TIMEOUT$1 : settings.timeout;
|
|
1112
|
+
// setTimeout считает больше 2^31 − 1 мс за 0 и сработал бы сразу
|
|
1113
|
+
if (!Number.isFinite(ms) || ms <= 0 || ms > 2_147_483_647) {
|
|
1114
|
+
throw invalid('timeout', ms, 'a number of milliseconds from 1 to 2147483647');
|
|
1115
|
+
}
|
|
1116
|
+
steps.push(timeout(ms));
|
|
1117
|
+
}
|
|
1118
|
+
return steps;
|
|
1119
|
+
}
|
|
1120
|
+
function invalid(name, value, expected) {
|
|
1121
|
+
return new TypeError(`bx-rest settings: ${name} must be ${expected}, got ${String(value)}`);
|
|
1122
|
+
}
|
|
1123
|
+
function abortReason(signal) {
|
|
1124
|
+
return signal.reason ?? new Error('The request was aborted');
|
|
1125
|
+
}
|
|
1126
|
+
/** Пауза, которую прерывает отмена запроса. */
|
|
1127
|
+
function wait(ms, signal) {
|
|
1128
|
+
return new Promise((resolve, reject) => {
|
|
1129
|
+
if (signal?.aborted) {
|
|
1130
|
+
reject(abortReason(signal));
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
const onAbort = () => {
|
|
1134
|
+
clearTimeout(timer);
|
|
1135
|
+
reject(abortReason(signal));
|
|
1136
|
+
};
|
|
1137
|
+
const timer = setTimeout(() => {
|
|
1138
|
+
signal?.removeEventListener('abort', onAbort);
|
|
1139
|
+
resolve();
|
|
1140
|
+
}, ms);
|
|
1141
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Повтор при `QUERY_LIMIT_EXCEEDED`: портал отвечает так (HTTP 503), когда
|
|
1146
|
+
* превышен лимит частоты запросов. Пауза растёт вдвое: `delay`, `2 × delay`, ...
|
|
1147
|
+
* `attempts` — сколько всего попыток, вместе с первой.
|
|
1148
|
+
*/
|
|
1149
|
+
function retryOnQueryLimit(attempts, delay) {
|
|
1150
|
+
return async (config, next) => {
|
|
1151
|
+
for (let attempt = 1;; attempt++) {
|
|
1152
|
+
try {
|
|
1153
|
+
return await next(config);
|
|
1154
|
+
}
|
|
1155
|
+
catch (error) {
|
|
1156
|
+
const code = parseBXRestErrorBody(httpErrorResponse(error)?.data)?.error;
|
|
1157
|
+
if (attempt >= attempts || code !== 'QUERY_LIMIT_EXCEEDED') {
|
|
1158
|
+
throw error;
|
|
1159
|
+
}
|
|
1160
|
+
await wait(delay * 2 ** (attempt - 1), config.signal);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Не больше `perSecond` запросов в секунду: лишние ждут своей очереди.
|
|
1167
|
+
* Очередь общая для всех запросов клиента (`state` — его контекст).
|
|
1168
|
+
*/
|
|
1169
|
+
function throttle(perSecond, state) {
|
|
1170
|
+
const interval = 1000 / perSecond;
|
|
1171
|
+
return (config, next) => {
|
|
1172
|
+
const now = Date.now();
|
|
1173
|
+
const start = Math.max(now, state.throttleNextSlot);
|
|
1174
|
+
const reserved = start + interval;
|
|
1175
|
+
state.throttleNextSlot = reserved;
|
|
1176
|
+
if (start <= now) {
|
|
1177
|
+
return next(config);
|
|
1178
|
+
}
|
|
1179
|
+
return wait(start - now, config.signal).then(() => next(config), (error) => {
|
|
1180
|
+
// Отменённый запрос освобождает своё место, если за ним никто не встал
|
|
1181
|
+
if (state.throttleNextSlot === reserved) {
|
|
1182
|
+
state.throttleNextSlot = start;
|
|
1183
|
+
}
|
|
1184
|
+
throw error;
|
|
1185
|
+
});
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
/** Отменяет запрос, если он не завершился за `ms` миллисекунд. */
|
|
1189
|
+
function timeout(ms) {
|
|
1190
|
+
return (config, next) => {
|
|
1191
|
+
const controller = new AbortController();
|
|
1192
|
+
const onAbort = () => controller.abort(abortReason(config.signal));
|
|
1193
|
+
if (config.signal?.aborted) {
|
|
1194
|
+
onAbort();
|
|
1195
|
+
}
|
|
1196
|
+
else {
|
|
1197
|
+
config.signal?.addEventListener('abort', onAbort, { once: true });
|
|
1198
|
+
}
|
|
1199
|
+
let timer;
|
|
1200
|
+
const timedOut = new Promise((_, reject) => {
|
|
1201
|
+
timer = setTimeout(() => {
|
|
1202
|
+
const error = new BXRestTimeoutError(ms);
|
|
1203
|
+
controller.abort(error);
|
|
1204
|
+
reject(error);
|
|
1205
|
+
}, ms);
|
|
1206
|
+
});
|
|
1207
|
+
return Promise.race([next({ ...config, signal: controller.signal }), timedOut]).finally(() => {
|
|
1208
|
+
clearTimeout(timer);
|
|
1209
|
+
config.signal?.removeEventListener('abort', onAbort);
|
|
1210
|
+
});
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1106
1214
|
class HttpBXServices extends HttpServices {
|
|
1107
1215
|
/**
|
|
1108
1216
|
* Не считайте этот метод образцом/финальным API.
|
|
@@ -1167,8 +1275,8 @@ class HttpBXServices extends HttpServices {
|
|
|
1167
1275
|
get(name, params = {}, headers) {
|
|
1168
1276
|
return this.httpGet(this.getNameMethod(name), params, undefined, headers);
|
|
1169
1277
|
}
|
|
1170
|
-
// settings
|
|
1171
|
-
//
|
|
1278
|
+
// settings не используется и оставлен ради прежней сигнатуры: headers
|
|
1279
|
+
// остаётся четвёртым параметром у httpPost и httpGet.
|
|
1172
1280
|
httpPost(url, params = {}, settings, headers) {
|
|
1173
1281
|
// defer() откладывает всё содержимое (в том числе чтение BXRestSettings
|
|
1174
1282
|
// через this.session.*) до реальной подписки — иначе даже с "живым"
|
|
@@ -1199,19 +1307,19 @@ class HttpBXServices extends HttpServices {
|
|
|
1199
1307
|
return throwError(() => this.session.getBaseUrlError('post'));
|
|
1200
1308
|
}
|
|
1201
1309
|
const fullUrl = prepareBaseAddress(baseUrl) + url;
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
}
|
|
1209
|
-
return from(this.axiosInstance.post(fullUrl, paramsClone, {
|
|
1310
|
+
// sessid — тело x-www-form-urlencoded, остальные ключи — JSON
|
|
1311
|
+
const urlencoded = key === 'sessid';
|
|
1312
|
+
return this.send({
|
|
1313
|
+
method: 'POST',
|
|
1314
|
+
url: fullUrl,
|
|
1315
|
+
data: urlencoded ? this.serializeBitrixParams(paramsClone) : paramsClone,
|
|
1210
1316
|
withCredentials: this.session.getWithCredentials(),
|
|
1211
|
-
headers: this.buildHeaders(headers, {
|
|
1212
|
-
|
|
1317
|
+
headers: this.buildHeaders(headers, {
|
|
1318
|
+
'Content-Type': urlencoded ? 'application/x-www-form-urlencoded' : 'application/json'
|
|
1319
|
+
}),
|
|
1320
|
+
});
|
|
1213
1321
|
}));
|
|
1214
|
-
}));
|
|
1322
|
+
}), this.session.ctx);
|
|
1215
1323
|
}
|
|
1216
1324
|
httpGet(url, params = {}, settings, headers) {
|
|
1217
1325
|
// Та же причина, что и у httpPost выше: откладываем чтение BXRestSettings
|
|
@@ -1221,26 +1329,59 @@ class HttpBXServices extends HttpServices {
|
|
|
1221
1329
|
// авторизации — как в httpPost.
|
|
1222
1330
|
return withAuthRefresh(defer(() => {
|
|
1223
1331
|
const paramsClone = clone(params);
|
|
1332
|
+
const key = this.session.getKeyAuth();
|
|
1224
1333
|
const auth = this.session.getAuthParams();
|
|
1225
1334
|
const checkIsOn = this.session.getCheckAuthParamsIsOn();
|
|
1226
1335
|
if (checkIsOn) {
|
|
1227
1336
|
if (!auth) {
|
|
1228
1337
|
return throwError(() => this.session.getAuthError('get'));
|
|
1229
1338
|
}
|
|
1230
|
-
|
|
1339
|
+
if (key !== 'OAuth2') {
|
|
1340
|
+
paramsClone[key] = auth;
|
|
1341
|
+
}
|
|
1231
1342
|
}
|
|
1232
1343
|
return this.session.getBaseUrl().pipe(switchMap((baseUrl) => {
|
|
1233
1344
|
if (!baseUrl) {
|
|
1234
1345
|
return throwError(() => this.session.getBaseUrlError('get'));
|
|
1235
1346
|
}
|
|
1236
1347
|
const fullUrl = prepareBaseAddress(baseUrl) + url;
|
|
1237
|
-
const queryString =
|
|
1348
|
+
const queryString = this.serializeBitrixParams(paramsClone);
|
|
1238
1349
|
const finalUrl = `${fullUrl}?${queryString}`;
|
|
1239
|
-
return
|
|
1350
|
+
return this.send({
|
|
1351
|
+
method: 'GET',
|
|
1352
|
+
url: finalUrl,
|
|
1353
|
+
withCredentials: this.session.getWithCredentials(),
|
|
1240
1354
|
headers: this.buildHeaders(headers),
|
|
1241
|
-
})
|
|
1355
|
+
});
|
|
1242
1356
|
}));
|
|
1243
|
-
}));
|
|
1357
|
+
}), this.session.ctx);
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Отправка через шаги из настроек: `retryOnQueryLimit`, `throttle`,
|
|
1361
|
+
* `timeout`, затем `middleware`; последним идёт axios клиента. Настройки
|
|
1362
|
+
* читаются при подписке. Отписка отменяет HTTP-запрос (AbortSignal).
|
|
1363
|
+
* Ошибка транспорта уходит дальше как есть: у axios в ней весь запрос,
|
|
1364
|
+
* вместе с токеном и секретом вебхука (см. README, «Обработка ошибок»).
|
|
1365
|
+
*/
|
|
1366
|
+
send(config) {
|
|
1367
|
+
return new Observable(subscriber => {
|
|
1368
|
+
const controller = new AbortController();
|
|
1369
|
+
const ctx = this.session.ctx;
|
|
1370
|
+
const send = composeMiddleware([...builtInMiddleware(ctx.settings, ctx), ...this.session.getMiddleware()], request => this.axiosSend(request));
|
|
1371
|
+
send({ ...config, signal: controller.signal }).then(data => {
|
|
1372
|
+
subscriber.next(data);
|
|
1373
|
+
subscriber.complete();
|
|
1374
|
+
}, (error) => subscriber.error(error));
|
|
1375
|
+
return () => controller.abort();
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
/** Транспорт по умолчанию: axios клиента, как и раньше через post()/get(). */
|
|
1379
|
+
axiosSend(config) {
|
|
1380
|
+
const options = { headers: config.headers, withCredentials: config.withCredentials, signal: config.signal };
|
|
1381
|
+
const request = (config.method === 'GET')
|
|
1382
|
+
? this.axiosInstance.get(config.url, options)
|
|
1383
|
+
: this.axiosInstance.post(config.url, config.data, options);
|
|
1384
|
+
return request.then(response => response.data);
|
|
1244
1385
|
}
|
|
1245
1386
|
/**
|
|
1246
1387
|
* Заголовки запроса: `BXRestSettings.headers`, поверх них — заголовки
|
|
@@ -1259,6 +1400,19 @@ class HttpBXServices extends HttpServices {
|
|
|
1259
1400
|
}
|
|
1260
1401
|
}
|
|
1261
1402
|
|
|
1403
|
+
/** Больше команд в одном запросе `batch` Bitrix не принимает. */
|
|
1404
|
+
const BATCH_COMMANDS_LIMIT = 50;
|
|
1405
|
+
/**
|
|
1406
|
+
* Параметры остальных страниц для методов с постраничной навигацией через `start`.
|
|
1407
|
+
* Отсчёт идёт от `start` самого запроса: первая страница уже получена именно с него.
|
|
1408
|
+
*/
|
|
1409
|
+
function offsetPageParams(param, total, pageSize) {
|
|
1410
|
+
const pages = [];
|
|
1411
|
+
for (let start = (Number(param?.start) || 0) + pageSize; start < (total ?? 0); start += pageSize) {
|
|
1412
|
+
pages.push({ ...clone(param), start });
|
|
1413
|
+
}
|
|
1414
|
+
return pages;
|
|
1415
|
+
}
|
|
1262
1416
|
class NavvyPagBase {
|
|
1263
1417
|
constructor(url, param, map = undefined, restApi = false) {
|
|
1264
1418
|
this.url = url;
|
|
@@ -1302,13 +1456,7 @@ class NavvyPagBase {
|
|
|
1302
1456
|
}
|
|
1303
1457
|
mapAndError(request, options) {
|
|
1304
1458
|
const method = this.http.getNameMethod(this.url);
|
|
1305
|
-
return request.pipe(
|
|
1306
|
-
if (options?.throwOnApiError && v && !instanceOfiBXRestAnswerSuccess(v)) {
|
|
1307
|
-
throw this.apiErrorFromBody(v);
|
|
1308
|
-
}
|
|
1309
|
-
return BXRestMapResult(v);
|
|
1310
|
-
}), catchError((err) => {
|
|
1311
|
-
console.error(err);
|
|
1459
|
+
return request.pipe(catchError((err) => {
|
|
1312
1460
|
if (err instanceof BXRestApiError) {
|
|
1313
1461
|
throw err;
|
|
1314
1462
|
}
|
|
@@ -1328,6 +1476,14 @@ class NavvyPagBase {
|
|
|
1328
1476
|
Object.assign(error, { authRefreshError });
|
|
1329
1477
|
}
|
|
1330
1478
|
throw error;
|
|
1479
|
+
}), map(v => {
|
|
1480
|
+
if (v && typeof v !== 'object') {
|
|
1481
|
+
throw this.notRestAnswerError();
|
|
1482
|
+
}
|
|
1483
|
+
if (options?.throwOnApiError && v && !instanceOfiBXRestAnswerSuccess(v)) {
|
|
1484
|
+
throw this.apiErrorFromBody(v);
|
|
1485
|
+
}
|
|
1486
|
+
return BXRestMapResult(v);
|
|
1331
1487
|
}));
|
|
1332
1488
|
}
|
|
1333
1489
|
/**
|
|
@@ -1336,12 +1492,48 @@ class NavvyPagBase {
|
|
|
1336
1492
|
*/
|
|
1337
1493
|
resFirstPage() {
|
|
1338
1494
|
return this.resVanilla().pipe(map(v => {
|
|
1339
|
-
if (v
|
|
1495
|
+
if (!v || typeof v !== 'object') {
|
|
1496
|
+
throw this.notRestAnswerError();
|
|
1497
|
+
}
|
|
1498
|
+
if (!instanceOfiBXRestAnswerSuccess(v)) {
|
|
1340
1499
|
throw this.apiErrorFromBody(v);
|
|
1341
1500
|
}
|
|
1342
1501
|
return v;
|
|
1343
1502
|
}));
|
|
1344
1503
|
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Остальные страницы для `.resAll()`, в порядке `params`. Команды уходят через `batch`,
|
|
1506
|
+
* пакеты — по очереди. Ошибка любой страницы завершает весь запрос: неполный список
|
|
1507
|
+
* выглядел бы для вызывающего кода как полный.
|
|
1508
|
+
*/
|
|
1509
|
+
resPages(params) {
|
|
1510
|
+
const method = this.http.getNameMethod(this.url);
|
|
1511
|
+
const commands = params.map(param => method + '?' + serializeBitrixParams(param));
|
|
1512
|
+
const batches = [];
|
|
1513
|
+
for (let i = 0; i < commands.length; i += BATCH_COMMANDS_LIMIT) {
|
|
1514
|
+
batches.push(commands.slice(i, i + BATCH_COMMANDS_LIMIT));
|
|
1515
|
+
}
|
|
1516
|
+
return from(batches).pipe(concatMap(cmd => this.http.post(['batch'], { halt: 1, cmd }, false, this.requestHeaders)), map(answer => this.batchPages(answer)), toArray(), map(pages => pages.flat()));
|
|
1517
|
+
}
|
|
1518
|
+
batchPages(answer) {
|
|
1519
|
+
if (!answer || typeof answer !== 'object') {
|
|
1520
|
+
throw this.notRestAnswerError();
|
|
1521
|
+
}
|
|
1522
|
+
if (!instanceOfiBXRestAnswerSuccess(answer)) {
|
|
1523
|
+
throw this.apiErrorFromBody(answer);
|
|
1524
|
+
}
|
|
1525
|
+
// Портал отдаёт result_error массивом, когда ошибок нет, и объектом с ключами команд, когда есть
|
|
1526
|
+
const failed = Object.values(answer.result?.result_error ?? {})[0];
|
|
1527
|
+
if (failed) {
|
|
1528
|
+
const parsed = parseBXRestErrorBody(failed);
|
|
1529
|
+
throw new BXRestApiError(parsed?.error, parsed?.error_description, { method: this.http.getNameMethod(this.url) });
|
|
1530
|
+
}
|
|
1531
|
+
return Object.values(answer.result?.result ?? {}).filter(Boolean);
|
|
1532
|
+
}
|
|
1533
|
+
// В тексте ошибки — только метод, без тела ответа: это может быть целая HTML-страница
|
|
1534
|
+
notRestAnswerError() {
|
|
1535
|
+
return new Error(`Bitrix24 answered ${this.http.getNameMethod(this.url)} with a body that is not a REST response.`);
|
|
1536
|
+
}
|
|
1345
1537
|
apiErrorFromBody(v) {
|
|
1346
1538
|
const parsed = parseBXRestErrorBody(v);
|
|
1347
1539
|
return new BXRestApiError(parsed ? parsed.error : v.error, parsed ? parsed.error_description : v.error_description, { method: this.http.getNameMethod(this.url) });
|
|
@@ -1351,6 +1543,138 @@ class NavvyPagBase {
|
|
|
1351
1543
|
class NavvySimple extends NavvyPagBase {
|
|
1352
1544
|
}
|
|
1353
1545
|
|
|
1546
|
+
/**
|
|
1547
|
+
* Класс-прослойка-обработчик для методов работающих на альтернативной постраничной навигации тика как методы по
|
|
1548
|
+
* затраченному времени на задачи https://dev.1c-bitrix.ru/rest_help/tasks/task/elapseditem/index.php
|
|
1549
|
+
*
|
|
1550
|
+
* не завершенный класс, работаем от частного к общему
|
|
1551
|
+
*/
|
|
1552
|
+
class NavvyAlterPagNav extends NavvyPagBase {
|
|
1553
|
+
resAll() {
|
|
1554
|
+
return this.resFirstPage().pipe(mergeMap(first => this.resPages(first.next ? this.pageParams(first.total) : []).pipe(map(pages => {
|
|
1555
|
+
const items = [first.result ?? [], ...pages].flat();
|
|
1556
|
+
return ((this.map ? this.map(items) : items) ?? []);
|
|
1557
|
+
}))),
|
|
1558
|
+
// refCount: без подписчиков оставшиеся страницы запрашивать незачем
|
|
1559
|
+
shareReplay({ bufferSize: 1, refCount: true }));
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* Параметры остальных страниц. Размер страницы берётся из запроса: портал ограничивает
|
|
1563
|
+
* его 50 записями, но вызывающий код может попросить и меньше.
|
|
1564
|
+
*/
|
|
1565
|
+
pageParams(total = 0) {
|
|
1566
|
+
const nav = this.param.PARAMS?.NAV_PARAMS;
|
|
1567
|
+
const nPageSize = Math.min(nav?.nPageSize || this.pageSize, this.pageSize);
|
|
1568
|
+
const pages = [];
|
|
1569
|
+
for (let iNumPage = (nav?.iNumPage || 1) + 1; iNumPage <= Math.ceil(total / nPageSize); iNumPage++) {
|
|
1570
|
+
pages.push({ ...clone(this.param), PARAMS: { ...this.param.PARAMS, NAV_PARAMS: { ...nav, nPageSize, iNumPage } } });
|
|
1571
|
+
}
|
|
1572
|
+
return pages;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
class NavvyPagNavWithUselessKey extends NavvyPagBase {
|
|
1577
|
+
resAll() {
|
|
1578
|
+
return this.resFirstPage().pipe(mergeMap(first => {
|
|
1579
|
+
const params = first.next ? offsetPageParams(this.param, first.total, this.pageSize) : [];
|
|
1580
|
+
return this.resPages(params).pipe(map(pages => {
|
|
1581
|
+
const merged = Object.assign({}, first.result, ...pages);
|
|
1582
|
+
return (this.map ? this.map(merged) : [merged]);
|
|
1583
|
+
}));
|
|
1584
|
+
}));
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
class NavvyPagNavResultKey extends NavvyPagBase {
|
|
1589
|
+
constructor(url, param, key, map, restApi) {
|
|
1590
|
+
// Без своего map результат — массив по ключу, как и обещают типы `.res()` и `.resAll()`.
|
|
1591
|
+
// Иначе `.res()` отдал бы весь объект `{ items: [...] }`.
|
|
1592
|
+
super(url, param, map ?? (result => (result?.[key] ?? [])), restApi);
|
|
1593
|
+
this.key = key;
|
|
1594
|
+
}
|
|
1595
|
+
resAll() {
|
|
1596
|
+
return this.resFirstPage().pipe(mergeMap(first => this.resPages(offsetPageParams(this.param, first.total, this.pageSize)).pipe(map(pages => {
|
|
1597
|
+
const items = [first.result, ...pages].flatMap(page => page?.[this.key] ?? []);
|
|
1598
|
+
const joined = { ...first.result, [this.key]: items };
|
|
1599
|
+
return (this.map?.(joined) ?? []);
|
|
1600
|
+
}))),
|
|
1601
|
+
// refCount: без подписчиков оставшиеся страницы запрашивать незачем
|
|
1602
|
+
shareReplay({ bufferSize: 1, refCount: true }));
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
class NavvyPagNavTasks extends NavvyPagNavResultKey {
|
|
1607
|
+
constructor(url, param, map, restApi) {
|
|
1608
|
+
super(url, param, 'tasks', map, restApi);
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
class NavvyPag extends NavvyPagBase {
|
|
1613
|
+
resAll() {
|
|
1614
|
+
return this.resFirstPage().pipe(mergeMap(first => this.resPages(offsetPageParams(this.param, first.total, this.pageSize)).pipe(map(pages => {
|
|
1615
|
+
const items = [first.result ?? [], ...pages].flat();
|
|
1616
|
+
return ((this.map ? this.map(items) : items) ?? []);
|
|
1617
|
+
}))));
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
/** Пагинация для методов, возвращающих коллекцию как объект с идентификаторами в ключах. */
|
|
1622
|
+
class NavvyPagNavResultKeyObject extends NavvyPagBase {
|
|
1623
|
+
constructor(url, param, key, mapResult) {
|
|
1624
|
+
// Без своего map результат — значения объекта по ключу, как и обещают типы `.res()` и `.resAll()`.
|
|
1625
|
+
super(url, param, mapResult ?? (result => Object.values(result?.[key] ?? {})));
|
|
1626
|
+
this.key = key;
|
|
1627
|
+
}
|
|
1628
|
+
resAll() {
|
|
1629
|
+
return this.resFirstPage().pipe(mergeMap(first => this.resPages(offsetPageParams(this.param, first.total, this.pageSize)).pipe(map(pages => {
|
|
1630
|
+
const merged = Object.assign({}, first.result?.[this.key], ...pages.map(page => page[this.key]));
|
|
1631
|
+
return this.map?.({ ...first.result, [this.key]: merged });
|
|
1632
|
+
}))),
|
|
1633
|
+
// refCount: без подписчиков оставшиеся страницы запрашивать незачем
|
|
1634
|
+
shareReplay({ bufferSize: 1, refCount: true }));
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
class Navvy {
|
|
1639
|
+
constructor() {
|
|
1640
|
+
// Контекст, в котором создан Navvy. Запросы создаются позже, при вызове
|
|
1641
|
+
// метода, поэтому их HTTP-объекты получают этот контекст явно, а не текущий.
|
|
1642
|
+
this.ctx = currentContext();
|
|
1643
|
+
}
|
|
1644
|
+
simple(url, arg, map) {
|
|
1645
|
+
return runInContext(this.ctx, () => new NavvySimple(url, arg !== undefined ? arg : undefined, map));
|
|
1646
|
+
}
|
|
1647
|
+
simpleV3(url, arg, map) {
|
|
1648
|
+
return runInContext(this.ctx, () => new NavvySimple(url, arg !== undefined ? arg : undefined, map, true));
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Новый, пока тестируемый метод для api методов с пагинацией
|
|
1652
|
+
*
|
|
1653
|
+
* @param url
|
|
1654
|
+
* @param arg
|
|
1655
|
+
* @param map
|
|
1656
|
+
* @constructor
|
|
1657
|
+
*/
|
|
1658
|
+
pagNav(url, arg, map) {
|
|
1659
|
+
return runInContext(this.ctx, () => new NavvyPag(url, arg, map));
|
|
1660
|
+
}
|
|
1661
|
+
pagNavTasks(url, arg, map) {
|
|
1662
|
+
return runInContext(this.ctx, () => new NavvyPagNavTasks(url, arg, map));
|
|
1663
|
+
}
|
|
1664
|
+
pagNavResultKey(url, arg, key, map) {
|
|
1665
|
+
return runInContext(this.ctx, () => new NavvyPagNavResultKey(url, arg, key, map));
|
|
1666
|
+
}
|
|
1667
|
+
pagNavResultKeyObject(url, arg, key, map) {
|
|
1668
|
+
return runInContext(this.ctx, () => new NavvyPagNavResultKeyObject(url, arg, key, map));
|
|
1669
|
+
}
|
|
1670
|
+
pagNavWithUselessKey(url, arg, map) {
|
|
1671
|
+
return runInContext(this.ctx, () => new NavvyPagNavWithUselessKey(url, arg, map));
|
|
1672
|
+
}
|
|
1673
|
+
alterPagNav(url, arg, map) {
|
|
1674
|
+
return runInContext(this.ctx, () => new NavvyAlterPagNav(url, arg, map));
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1354
1678
|
const $get = 'get';
|
|
1355
1679
|
const $add = 'add';
|
|
1356
1680
|
const $set = 'set';
|
|
@@ -2263,1496 +2587,180 @@ var partNameMethods$1 = /*#__PURE__*/Object.freeze({
|
|
|
2263
2587
|
$quote: $quote,
|
|
2264
2588
|
$ratio: $ratio,
|
|
2265
2589
|
$reaction: $reaction,
|
|
2266
|
-
$read: $read,
|
|
2267
|
-
$reading: $reading,
|
|
2268
|
-
$recall: $recall,
|
|
2269
|
-
$recent: $recent,
|
|
2270
|
-
$recipient: $recipient,
|
|
2271
|
-
$record: $record,
|
|
2272
|
-
$recurring: $recurring,
|
|
2273
|
-
$region: $region,
|
|
2274
|
-
$register: $register,
|
|
2275
|
-
$remove: $remove,
|
|
2276
|
-
$removeAttachments: $removeAttachments,
|
|
2277
|
-
$removeCard: $removeCard,
|
|
2278
|
-
$removeEntities: $removeEntities,
|
|
2279
|
-
$removecrmactivity: $removecrmactivity,
|
|
2280
|
-
$rename: $rename,
|
|
2281
|
-
$renew: $renew,
|
|
2282
|
-
$reply: $reply,
|
|
2283
|
-
$repo: $repo,
|
|
2284
|
-
$report: $report,
|
|
2285
|
-
$reports: $reports,
|
|
2286
|
-
$repowidget: $repowidget,
|
|
2287
|
-
$request: $request,
|
|
2288
|
-
$requisite: $requisite,
|
|
2289
|
-
$reset: $reset,
|
|
2290
|
-
$resolveIdByPublicUrl: $resolveIdByPublicUrl,
|
|
2291
|
-
$resource: $resource,
|
|
2292
|
-
$resourcetype: $resourcetype,
|
|
2293
|
-
$restore: $restore,
|
|
2294
|
-
$restoreFromVersion: $restoreFromVersion,
|
|
2295
|
-
$result: $result,
|
|
2296
|
-
$resume: $resume,
|
|
2297
|
-
$revision: $revision,
|
|
2298
|
-
$rights: $rights,
|
|
2299
|
-
$robot: $robot,
|
|
2300
|
-
$role: $role,
|
|
2301
|
-
$roundingRule: $roundingRule,
|
|
2302
|
-
$sale: $sale,
|
|
2303
|
-
$save: $save,
|
|
2304
|
-
$schedule: $schedule,
|
|
2305
|
-
$schema: $schema,
|
|
2306
|
-
$search: $search,
|
|
2307
|
-
$searchCrmEntities: $searchCrmEntities,
|
|
2308
|
-
$section: $section,
|
|
2309
|
-
$send: $send,
|
|
2310
|
-
$sendContext: $sendContext,
|
|
2311
|
-
$sendMessage: $sendMessage,
|
|
2312
|
-
$sender: $sender,
|
|
2313
|
-
$senders: $senders,
|
|
2314
|
-
$server: $server,
|
|
2315
|
-
$service: $service,
|
|
2316
|
-
$session: $session,
|
|
2317
|
-
$set: $set,
|
|
2318
|
-
$setAccessCodes: $setAccessCodes,
|
|
2319
|
-
$setDelivery: $setDelivery,
|
|
2320
|
-
$setLandingRef: $setLandingRef,
|
|
2321
|
-
$setOwner: $setOwner,
|
|
2322
|
-
$setQuantity: $setQuantity,
|
|
2323
|
-
$setRights: $setRights,
|
|
2324
|
-
$setSiteRef: $setSiteRef,
|
|
2325
|
-
$setowner: $setowner,
|
|
2326
|
-
$settings: $settings,
|
|
2327
|
-
$share: $share,
|
|
2328
|
-
$sharetouser: $sharetouser,
|
|
2329
|
-
$shipment: $shipment,
|
|
2330
|
-
$shipmentItem: $shipmentItem,
|
|
2331
|
-
$shipmentProperty: $shipmentProperty,
|
|
2332
|
-
$shipmentPropertyValue: $shipmentPropertyValue,
|
|
2333
|
-
$show: $show,
|
|
2334
|
-
$showBlock: $showBlock,
|
|
2335
|
-
$sign: $sign,
|
|
2336
|
-
$silent: $silent,
|
|
2337
|
-
$sip: $sip,
|
|
2338
|
-
$site: $site,
|
|
2339
|
-
$skip: $skip,
|
|
2340
|
-
$sku: $sku,
|
|
2341
|
-
$slots: $slots,
|
|
2342
|
-
$socialnetwork: $socialnetwork,
|
|
2343
|
-
$sonet_group: $sonet_group,
|
|
2344
|
-
$source: $source,
|
|
2345
|
-
$spam: $spam,
|
|
2346
|
-
$stagehistory: $stagehistory,
|
|
2347
|
-
$stages: $stages,
|
|
2348
|
-
$start: $start,
|
|
2349
|
-
$startwatch: $startwatch,
|
|
2350
|
-
$startwithsound: $startwithsound,
|
|
2351
|
-
$startwithtext: $startwithtext,
|
|
2352
|
-
$statistic: $statistic,
|
|
2353
|
-
$status: $status,
|
|
2354
|
-
$statusLang: $statusLang,
|
|
2355
|
-
$statuslist: $statuslist,
|
|
2356
|
-
$stop: $stop,
|
|
2357
|
-
$stopwatch: $stopwatch,
|
|
2358
|
-
$storage: $storage,
|
|
2359
|
-
$store: $store,
|
|
2360
|
-
$storeProduct: $storeProduct,
|
|
2361
|
-
$subscribe: $subscribe,
|
|
2362
|
-
$syspage: $syspage,
|
|
2363
|
-
$system: $system,
|
|
2364
|
-
$tail: $tail,
|
|
2365
|
-
$task: $task,
|
|
2366
|
-
$tasks: $tasks,
|
|
2367
|
-
$telephony: $telephony,
|
|
2368
|
-
$template: $template,
|
|
2369
|
-
$terminate: $terminate,
|
|
2370
|
-
$text: $text,
|
|
2371
|
-
$textField: $textField,
|
|
2372
|
-
$thread: $thread,
|
|
2373
|
-
$time: $time,
|
|
2374
|
-
$timeMan: $timeMan,
|
|
2375
|
-
$timecontrol: $timecontrol,
|
|
2376
|
-
$timeline: $timeline,
|
|
2377
|
-
$todo: $todo,
|
|
2378
|
-
$trace: $trace,
|
|
2379
|
-
$tracking: $tracking,
|
|
2380
|
-
$tradeBinding: $tradeBinding,
|
|
2381
|
-
$tradePlatform: $tradePlatform,
|
|
2382
|
-
$transfer: $transfer,
|
|
2383
|
-
$tree: $tree,
|
|
2384
|
-
$trigger: $trigger,
|
|
2385
|
-
$tts: $tts,
|
|
2386
|
-
$type: $type,
|
|
2387
|
-
$types: $types,
|
|
2388
|
-
$unbind: $unbind,
|
|
2389
|
-
$unbindingFromGroup: $unbindingFromGroup,
|
|
2390
|
-
$unbindingFromMenu: $unbindingFromMenu,
|
|
2391
|
-
$unfavoriteBlock: $unfavoriteBlock,
|
|
2392
|
-
$unmute: $unmute,
|
|
2393
|
-
$unpay: $unpay,
|
|
2394
|
-
$unpin: $unpin,
|
|
2395
|
-
$unpinAll: $unpinAll,
|
|
2396
|
-
$unpublic: $unpublic,
|
|
2397
|
-
$unpublicFolder: $unpublicFolder,
|
|
2398
|
-
$unread: $unread,
|
|
2399
|
-
$unregister: $unregister,
|
|
2400
|
-
$unset: $unset,
|
|
2401
|
-
$unsubscribe: $unsubscribe,
|
|
2402
|
-
$upBlock: $upBlock,
|
|
2403
|
-
$update: $update,
|
|
2404
|
-
$updateAttrs: $updateAttrs,
|
|
2405
|
-
$updateAvatar: $updateAvatar,
|
|
2406
|
-
$updateCards: $updateCards,
|
|
2407
|
-
$updateCatalogProduct: $updateCatalogProduct,
|
|
2408
|
-
$updateColor: $updateColor,
|
|
2409
|
-
$updateContent: $updateContent,
|
|
2410
|
-
$updateDeadline: $updateDeadline,
|
|
2411
|
-
$updateDescription: $updateDescription,
|
|
2412
|
-
$updateFolder: $updateFolder,
|
|
2413
|
-
$updateNodes: $updateNodes,
|
|
2414
|
-
$updateResponsibleUser: $updateResponsibleUser,
|
|
2415
|
-
$updateStyles: $updateStyles,
|
|
2416
|
-
$updateTitle: $updateTitle,
|
|
2417
|
-
$upload: $upload,
|
|
2418
|
-
$uploadFile: $uploadFile,
|
|
2419
|
-
$uploadfile: $uploadfile,
|
|
2420
|
-
$uploadversion: $uploadversion,
|
|
2421
|
-
$url: $url,
|
|
2422
|
-
$user: $user,
|
|
2423
|
-
$userconsent: $userconsent,
|
|
2424
|
-
$userfield: $userfield,
|
|
2425
|
-
$userfieldtype: $userfieldtype,
|
|
2426
|
-
$users: $users,
|
|
2427
|
-
$v1: $v1,
|
|
2428
|
-
$v2: $v2,
|
|
2429
|
-
$vat: $vat,
|
|
2430
|
-
$version: $version,
|
|
2431
|
-
$voices: $voices,
|
|
2432
|
-
$volatileType: $volatileType,
|
|
2433
|
-
$vote: $vote,
|
|
2434
|
-
$voximplant: $voximplant,
|
|
2435
|
-
$waitlist: $waitlist,
|
|
2436
|
-
$workflow: $workflow,
|
|
2437
|
-
$workgroup: $workgroup,
|
|
2438
|
-
$writing: $writing
|
|
2439
|
-
});
|
|
2440
|
-
|
|
2441
|
-
class BXRestUserUserfield {
|
|
2442
|
-
constructor() {
|
|
2443
|
-
this.url = {
|
|
2444
|
-
list: [$user, $userfield, $list],
|
|
2445
|
-
};
|
|
2446
|
-
this.http = new HttpBXServices();
|
|
2447
|
-
}
|
|
2448
|
-
list() {
|
|
2449
|
-
return this.http.post(this.url.list);
|
|
2450
|
-
}
|
|
2451
|
-
}
|
|
2452
|
-
|
|
2453
|
-
class BXRestUser {
|
|
2454
|
-
constructor() {
|
|
2455
|
-
this.http = new HttpBXServices();
|
|
2456
|
-
this.userfield = new BXRestUserUserfield();
|
|
2457
|
-
this.url = {
|
|
2458
|
-
admin: [$user, 'admin'],
|
|
2459
|
-
get: [$user, $get],
|
|
2460
|
-
current: [$user, 'current'],
|
|
2461
|
-
update: [$user, $update],
|
|
2462
|
-
search: [$user, $search],
|
|
2463
|
-
access: [$user, 'access'],
|
|
2464
|
-
fields: [$user, 'fields'],
|
|
2465
|
-
};
|
|
2466
|
-
}
|
|
2467
|
-
admin() {
|
|
2468
|
-
return this.http.post(this.url.admin);
|
|
2469
|
-
}
|
|
2470
|
-
get(params = {}) {
|
|
2471
|
-
return this.http.post(this.url.get, params);
|
|
2472
|
-
}
|
|
2473
|
-
current() {
|
|
2474
|
-
return this.http.post(this.url.current, {});
|
|
2475
|
-
}
|
|
2476
|
-
update(user) {
|
|
2477
|
-
return this.http.post(this.url.update, user);
|
|
2478
|
-
}
|
|
2479
|
-
search(params) {
|
|
2480
|
-
return this.http.post(this.url.search, params);
|
|
2481
|
-
}
|
|
2482
|
-
access(access) {
|
|
2483
|
-
return this.http.post(this.url.access, { ACCESS: access });
|
|
2484
|
-
}
|
|
2485
|
-
fields() {
|
|
2486
|
-
return this.http.post(this.url.fields);
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2490
|
-
class BXRestListsElement {
|
|
2491
|
-
constructor() {
|
|
2492
|
-
this.url = {
|
|
2493
|
-
add: [$lists, $element, $add],
|
|
2494
|
-
get: [$lists, $element, $get],
|
|
2495
|
-
};
|
|
2496
|
-
this.http = new HttpBXServices();
|
|
2497
|
-
}
|
|
2498
|
-
get(pram) {
|
|
2499
|
-
return this.http.post(this.url.get, pram);
|
|
2500
|
-
}
|
|
2501
|
-
add(param) {
|
|
2502
|
-
return this.http.post(this.url.add, param);
|
|
2503
|
-
}
|
|
2504
|
-
}
|
|
2505
|
-
|
|
2506
|
-
class BXRestListsField {
|
|
2507
|
-
constructor() {
|
|
2508
|
-
this.url = {
|
|
2509
|
-
// /**
|
|
2510
|
-
// * Метод создает поле списка
|
|
2511
|
-
// */
|
|
2512
|
-
// add: [$lists, $field, $add],
|
|
2513
|
-
// /**
|
|
2514
|
-
// * Метод удаляет поле списка
|
|
2515
|
-
// */
|
|
2516
|
-
// delete: [$lists, $field, $delete],
|
|
2517
|
-
/**
|
|
2518
|
-
* Метод возвращает данные поля
|
|
2519
|
-
*/
|
|
2520
|
-
get: [$lists, $field, $get],
|
|
2521
|
-
// type: {
|
|
2522
|
-
// /**
|
|
2523
|
-
// * Метод возвращает доступные типа полей для указанного списка
|
|
2524
|
-
// */
|
|
2525
|
-
// get: [$lists, $field, $type, $get],
|
|
2526
|
-
// },
|
|
2527
|
-
// /**
|
|
2528
|
-
// * Метод обновляет поле списка
|
|
2529
|
-
// */
|
|
2530
|
-
// update: [$lists, $field, $update],
|
|
2531
|
-
};
|
|
2532
|
-
this.http = new HttpBXServices();
|
|
2533
|
-
}
|
|
2534
|
-
get(param) {
|
|
2535
|
-
return this.http.post(this.url.get, param);
|
|
2536
|
-
}
|
|
2537
|
-
}
|
|
2538
|
-
|
|
2539
|
-
class BXRestLists {
|
|
2540
|
-
constructor() {
|
|
2541
|
-
this.url = {
|
|
2542
|
-
// /**
|
|
2543
|
-
// * Метод создаёт список
|
|
2544
|
-
// */
|
|
2545
|
-
// add: [$lists, $add],
|
|
2546
|
-
// /**
|
|
2547
|
-
// * Метод удаляет список
|
|
2548
|
-
// */
|
|
2549
|
-
// delete: [$lists, $delete],
|
|
2550
|
-
/**
|
|
2551
|
-
* Метод возвращает данные по спискам
|
|
2552
|
-
*/
|
|
2553
|
-
get: [$lists, $get],
|
|
2554
|
-
// /**
|
|
2555
|
-
// * Метод обновляет существующий список
|
|
2556
|
-
// */
|
|
2557
|
-
// update: [$lists, $update],
|
|
2558
|
-
// /**
|
|
2559
|
-
// * Метод возвращает id типа инфоблока
|
|
2560
|
-
// */
|
|
2561
|
-
// getIBlockTypeId: [$lists, $get, $iblock, $type, $id],
|
|
2562
|
-
element: {
|
|
2563
|
-
/**
|
|
2564
|
-
* Метод создаёт элемент списка
|
|
2565
|
-
*/
|
|
2566
|
-
add: [$lists, $element, $add],
|
|
2567
|
-
// /**
|
|
2568
|
-
// * Метод удаляет элемент списка TODO: Реализовать
|
|
2569
|
-
// */
|
|
2570
|
-
// delete: [$lists, $element, $delete],
|
|
2571
|
-
/**
|
|
2572
|
-
* Метод возвращает список элементов или элемент
|
|
2573
|
-
*/
|
|
2574
|
-
get: [$lists, $element, $get],
|
|
2575
|
-
// /**
|
|
2576
|
-
// * Метод обновляет элемент списка TODO: Реализовать
|
|
2577
|
-
// */
|
|
2578
|
-
// update: [$lists, $element, $update],
|
|
2579
|
-
// /**
|
|
2580
|
-
// * Метод возвращает путь к файлу TODO: Реализовать
|
|
2581
|
-
// */
|
|
2582
|
-
// getFileUrl: [$lists, $element, $get, $file, $url]
|
|
2583
|
-
},
|
|
2584
|
-
field: {
|
|
2585
|
-
// /**
|
|
2586
|
-
// * Метод создает поле списка
|
|
2587
|
-
// */
|
|
2588
|
-
// add: [$lists, $field, $add],
|
|
2589
|
-
// /**
|
|
2590
|
-
// * Метод удаляет поле списка
|
|
2591
|
-
// */
|
|
2592
|
-
// delete: [$lists, $field, $delete],
|
|
2593
|
-
/**
|
|
2594
|
-
* Метод возвращает данные поля
|
|
2595
|
-
*/
|
|
2596
|
-
get: [$lists, $field, $get],
|
|
2597
|
-
// type: {
|
|
2598
|
-
// /**
|
|
2599
|
-
// * Метод возвращает доступные типа полей для указанного списка
|
|
2600
|
-
// */
|
|
2601
|
-
// get: [$lists, $field, $type, $get],
|
|
2602
|
-
// },
|
|
2603
|
-
// /**
|
|
2604
|
-
// * Метод обновляет поле списка
|
|
2605
|
-
// */
|
|
2606
|
-
// update: [$lists, $field, $update],
|
|
2607
|
-
}
|
|
2608
|
-
};
|
|
2609
|
-
this.element = new BXRestListsElement();
|
|
2610
|
-
this.field = new BXRestListsField();
|
|
2611
|
-
this.http = new HttpBXServices();
|
|
2612
|
-
}
|
|
2613
|
-
// getField(pram: getListFieldParam): Observable<iHttpAnswerBX<FieldItemLists[]> | undefined> {
|
|
2614
|
-
// return this.http.post<iHttpAnswerBX<{ [key: string]: FieldItemLists }>>(this.url.field.get, pram)
|
|
2615
|
-
// }
|
|
2616
|
-
get(param) {
|
|
2617
|
-
return this.http.post(this.url.get, param);
|
|
2618
|
-
}
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
class BXRestTaskElapsedItem {
|
|
2622
|
-
constructor() {
|
|
2623
|
-
this.url = {
|
|
2624
|
-
getList: [$task, $elapseditem, $getlist],
|
|
2625
|
-
add: [$task, $elapseditem, $add],
|
|
2626
|
-
delete: [$task, $elapseditem, $delete],
|
|
2627
|
-
isActionAllowed: [$task, $elapseditem, $isactionallowed],
|
|
2628
|
-
update: [$task, $elapseditem, $update],
|
|
2629
|
-
};
|
|
2630
|
-
this.http = new HttpBXServices();
|
|
2631
|
-
}
|
|
2632
|
-
getList(param = {}) {
|
|
2633
|
-
return this.http.post(this.url.getList, param);
|
|
2634
|
-
}
|
|
2635
|
-
add(param) {
|
|
2636
|
-
return this.http.post(this.url.add, param);
|
|
2637
|
-
}
|
|
2638
|
-
update(param) {
|
|
2639
|
-
return this.http.post(this.url.update, param);
|
|
2640
|
-
}
|
|
2641
|
-
del(param) {
|
|
2642
|
-
return this.http.post(this.url.delete, param);
|
|
2643
|
-
}
|
|
2644
|
-
/**
|
|
2645
|
-
* idAction:
|
|
2646
|
-
* 1 - ACTION_ELAPSED_TIME_ADD
|
|
2647
|
-
* 2 - ACTION_ELAPSED_TIME_MODIFY
|
|
2648
|
-
* 3 - ACTION_ELAPSED_TIME_REMOVE
|
|
2649
|
-
* ITEMID - обязателен в конечной отправке но не обязателен для ACTION_ELAPSED_TIME_ADD,
|
|
2650
|
-
* поэтому этом методе можно ставить "1" например, так же метод может выдавать ошибки о не доступности задачи
|
|
2651
|
-
* поэтому рекомендую воспользоваться аналогичным методом в пространстве имен navvy
|
|
2652
|
-
* @param param
|
|
2653
|
-
*/
|
|
2654
|
-
isActionAllowed(param) {
|
|
2655
|
-
return this.http.post(this.url.isActionAllowed, param);
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
|
|
2659
|
-
class BXRestTaskCommentItem {
|
|
2660
|
-
constructor() {
|
|
2661
|
-
this.url = {
|
|
2662
|
-
getManifest: [$task, $commentitem, $getmanifest], // Возвращает список методов и их описание
|
|
2663
|
-
getList: [$task, $commentitem, $getlist], // Возвращает список комментариев к задаче
|
|
2664
|
-
get: [$task, $commentitem, $get], // Возвращает комментарий к задаче
|
|
2665
|
-
add: [$task, $commentitem, $add], // Создает новый комментарий к задаче
|
|
2666
|
-
update: [$task, $commentitem, $update], // Обновляет данные комментария
|
|
2667
|
-
delete: [$task, $commentitem, $delete], // Удаляет комментарий
|
|
2668
|
-
isActionAllowed: [$task, $commentitem, $isactionallowed], // Проверяет, разрешено ли действие
|
|
2669
|
-
};
|
|
2670
|
-
this.http = new HttpBXServices();
|
|
2671
|
-
}
|
|
2672
|
-
add(param) {
|
|
2673
|
-
return this.http.post(this.url.add, param);
|
|
2674
|
-
}
|
|
2675
|
-
update(param) {
|
|
2676
|
-
return this.http.post(this.url.update, param);
|
|
2677
|
-
}
|
|
2678
|
-
get(param) {
|
|
2679
|
-
return this.http.post(this.url.get, param);
|
|
2680
|
-
}
|
|
2681
|
-
getlist(param) {
|
|
2682
|
-
return this.http.post(this.url.getList, param);
|
|
2683
|
-
}
|
|
2684
|
-
del(param) {
|
|
2685
|
-
return this.http.post(this.url.delete, param);
|
|
2686
|
-
}
|
|
2687
|
-
}
|
|
2688
|
-
|
|
2689
|
-
class BXRestTaskPlanner {
|
|
2690
|
-
constructor() {
|
|
2691
|
-
this.http = new HttpBXServices();
|
|
2692
|
-
}
|
|
2693
|
-
getList() {
|
|
2694
|
-
return this.http.post([$task, $planner, $getlist]);
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
|
|
2698
|
-
class BXRestTaskItemUserField {
|
|
2699
|
-
constructor() {
|
|
2700
|
-
this.url = {
|
|
2701
|
-
getList: [$task, $item, $userfield, 'getlist'],
|
|
2702
|
-
};
|
|
2703
|
-
this.http = new HttpBXServices();
|
|
2704
|
-
}
|
|
2705
|
-
getList(param) {
|
|
2706
|
-
return this.http.post(this.url.getList, param);
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
|
|
2710
|
-
class BXRestTaskItem {
|
|
2711
|
-
constructor() {
|
|
2712
|
-
this.userField = new BXRestTaskItemUserField();
|
|
2713
|
-
}
|
|
2714
|
-
}
|
|
2715
|
-
|
|
2716
|
-
class BXRestTask {
|
|
2717
|
-
constructor() {
|
|
2718
|
-
this.elapsedItem = new BXRestTaskElapsedItem();
|
|
2719
|
-
this.commentItem = new BXRestTaskCommentItem();
|
|
2720
|
-
this.planner = new BXRestTaskPlanner();
|
|
2721
|
-
this.item = new BXRestTaskItem();
|
|
2722
|
-
}
|
|
2723
|
-
}
|
|
2724
|
-
|
|
2725
|
-
class BXRestTasksTaskResult {
|
|
2726
|
-
constructor() {
|
|
2727
|
-
this.url = {
|
|
2728
|
-
list: [$tasks, $task, $result, $list],
|
|
2729
|
-
addFromComment: [$tasks, $task, $result, 'addFromComment'],
|
|
2730
|
-
deleteFromComment: [$tasks, $task, $result, 'deleteFromComment'],
|
|
2731
|
-
};
|
|
2732
|
-
this.http = new HttpBXServices();
|
|
2733
|
-
}
|
|
2734
|
-
deleteFromComment(commentID) {
|
|
2735
|
-
return this.http.post(this.url.deleteFromComment, { commentId: commentID });
|
|
2736
|
-
}
|
|
2737
|
-
addFromComment(param) {
|
|
2738
|
-
return this.http.post(this.url.addFromComment, param);
|
|
2739
|
-
}
|
|
2740
|
-
list(param) {
|
|
2741
|
-
return this.http.post(this.url.list, param);
|
|
2742
|
-
}
|
|
2743
|
-
}
|
|
2744
|
-
|
|
2745
|
-
class BXRestTasksTask {
|
|
2746
|
-
constructor() {
|
|
2747
|
-
this.url = {
|
|
2748
|
-
add: [$tasks, $task, $add],
|
|
2749
|
-
approve: [$tasks, $task, $approve],
|
|
2750
|
-
complete: [$tasks, $task, $complete],
|
|
2751
|
-
defer: [$tasks, $task, $defer],
|
|
2752
|
-
get: [$tasks, $task, $get],
|
|
2753
|
-
getFields: [$tasks, $task, $getFields],
|
|
2754
|
-
getAccess: [$tasks, $task, $getaccess],
|
|
2755
|
-
list: [$tasks, $task, $list],
|
|
2756
|
-
update: [$tasks, $task, $update],
|
|
2757
|
-
};
|
|
2758
|
-
this.result = new BXRestTasksTaskResult();
|
|
2759
|
-
this.http = new HttpBXServices();
|
|
2760
|
-
}
|
|
2761
|
-
add(param) {
|
|
2762
|
-
return this.http.post(this.url.add, param);
|
|
2763
|
-
}
|
|
2764
|
-
approve(param) {
|
|
2765
|
-
return this.http.post(this.url.approve, param);
|
|
2766
|
-
}
|
|
2767
|
-
complete(param) {
|
|
2768
|
-
return this.http.post(this.url.complete, param);
|
|
2769
|
-
}
|
|
2770
|
-
defer(param) {
|
|
2771
|
-
return this.http.post(this.url.defer, param);
|
|
2772
|
-
}
|
|
2773
|
-
update(param) {
|
|
2774
|
-
return this.http.post(this.url.update, param);
|
|
2775
|
-
}
|
|
2776
|
-
get(param) {
|
|
2777
|
-
return this.http.post(this.url.get, param);
|
|
2778
|
-
}
|
|
2779
|
-
list(param) {
|
|
2780
|
-
return this.http.post(this.url.list, param);
|
|
2781
|
-
}
|
|
2782
|
-
/*
|
|
2783
|
-
listArray(requestArray: RequestApiTaskListBX = {}) {
|
|
2784
|
-
return this.list(requestArray).pipe(
|
|
2785
|
-
map(v => this.http.mapResult(v)),
|
|
2786
|
-
map(v => (v && v.tasks) ? v.tasks : [])
|
|
2787
|
-
)
|
|
2788
|
-
}
|
|
2789
|
-
|
|
2790
|
-
listAll(requestArray: RequestApiTaskListBX = {}, cache = false): Observable<TaskBX[]> {
|
|
2791
|
-
if (!requestArray.select) {
|
|
2792
|
-
requestArray.select = this.def.select
|
|
2793
|
-
if (cache) {
|
|
2794
|
-
return this.storeTask$.pipe(
|
|
2795
|
-
take(1),
|
|
2796
|
-
mergeMap(tasks => {
|
|
2797
|
-
if (tasks && tasks.data.http.list && requestArray.filter && requestArray.filter.ID) {
|
|
2798
|
-
const ids = (typeof requestArray.filter.ID === 'number') ? [requestArray.filter.ID] : requestArray.filter.ID
|
|
2799
|
-
let filter = tasks.data.http.list.filter(i => (i.id) ? ids.includes(i.id) : false)
|
|
2800
|
-
if (filter.length === ids.length) {
|
|
2801
|
-
return of(filter)
|
|
2802
|
-
}
|
|
2803
|
-
}
|
|
2804
|
-
return this.getEndListArray(requestArray)
|
|
2805
|
-
})
|
|
2806
|
-
)
|
|
2807
|
-
}
|
|
2808
|
-
return this.getEndListArray(requestArray)
|
|
2809
|
-
}
|
|
2810
|
-
return this.getEndListArray(requestArray)
|
|
2811
|
-
}
|
|
2812
|
-
|
|
2813
|
-
getEndListArray(requestArray: RequestApiTaskListBX): Observable<TaskBX[]> {
|
|
2814
|
-
return this.list(requestArray).pipe(
|
|
2815
|
-
mergeMap((items: AnswerApiTaskBX | undefined): ObservableInput<any> | Observable<AnswerApiTaskBX[]> => {
|
|
2816
|
-
if (items && items.result && typeof items.result.tasks === 'object') {
|
|
2817
|
-
const items$ = of(items.result.tasks)
|
|
2818
|
-
if (items.next) {
|
|
2819
|
-
this.nowLoad$.next({
|
|
2820
|
-
total: (items.total) ? items.total : 0,
|
|
2821
|
-
next: items.next
|
|
2822
|
-
})
|
|
2823
|
-
requestArray.start = items.next
|
|
2824
|
-
return this.getEndListArray(requestArray).pipe(
|
|
2825
|
-
map(vEnd => {
|
|
2826
|
-
if (vEnd && items.result.tasks) {
|
|
2827
|
-
return [...items.result.tasks, ...vEnd]
|
|
2828
|
-
}
|
|
2829
|
-
return (items.result.tasks) ? items.result.tasks : []
|
|
2830
|
-
}))
|
|
2831
|
-
}
|
|
2832
|
-
this.nowLoad$.next({
|
|
2833
|
-
total: 0,
|
|
2834
|
-
next: 0
|
|
2835
|
-
})
|
|
2836
|
-
return items$
|
|
2837
|
-
} else {
|
|
2838
|
-
return of([])
|
|
2839
|
-
}
|
|
2840
|
-
})
|
|
2841
|
-
)
|
|
2842
|
-
}
|
|
2843
|
-
*/
|
|
2844
|
-
getFields() {
|
|
2845
|
-
return this.http.post(this.url.getFields);
|
|
2846
|
-
}
|
|
2847
|
-
getAccess(param) {
|
|
2848
|
-
return this.http.post(this.url.getAccess, param);
|
|
2849
|
-
}
|
|
2850
|
-
}
|
|
2851
|
-
|
|
2852
|
-
class BXRestTasks {
|
|
2853
|
-
constructor() {
|
|
2854
|
-
this.task = new BXRestTasksTask();
|
|
2855
|
-
}
|
|
2856
|
-
}
|
|
2857
|
-
|
|
2858
|
-
class BXRestDiskFile {
|
|
2859
|
-
constructor() {
|
|
2860
|
-
this.url = {
|
|
2861
|
-
get: [$disk, $file, $get],
|
|
2862
|
-
markDeleted: [$disk, $file, $markdeleted],
|
|
2863
|
-
};
|
|
2864
|
-
this.http = new HttpBXServices();
|
|
2865
|
-
}
|
|
2866
|
-
get(param) {
|
|
2867
|
-
return this.http.post(this.url.get, param);
|
|
2868
|
-
}
|
|
2869
|
-
markDeleted(param) {
|
|
2870
|
-
return this.http.post(this.url.markDeleted, param);
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
|
|
2874
|
-
class BXRestDiskFolder {
|
|
2875
|
-
constructor() {
|
|
2876
|
-
this.url = {
|
|
2877
|
-
getFields: [$disk, $folder, $getFields],
|
|
2878
|
-
get: [$disk, $folder, $get],
|
|
2879
|
-
getChildren: [$disk, $folder, $getchildren],
|
|
2880
|
-
addSubFolder: [$disk, $folder, 'addsubfolder'],
|
|
2881
|
-
copyTo: [$disk, $folder, $copyto],
|
|
2882
|
-
moveTo: [$disk, $folder, $moveto],
|
|
2883
|
-
rename: [$disk, $folder, $rename],
|
|
2884
|
-
deleteTree: [$disk, $folder, 'deletetree'],
|
|
2885
|
-
markDeleted: [$disk, $folder, $markdeleted],
|
|
2886
|
-
restore: [$disk, $folder, $restore],
|
|
2887
|
-
uploadFile: [$disk, $folder, $uploadfile],
|
|
2888
|
-
getExternalLink: [$disk, $folder, 'getExternalLink'],
|
|
2889
|
-
};
|
|
2890
|
-
this.http = new HttpBXServices();
|
|
2891
|
-
}
|
|
2892
|
-
/**
|
|
2893
|
-
* Возвращает папку по идентификатору
|
|
2894
|
-
*
|
|
2895
|
-
* @param param
|
|
2896
|
-
*/
|
|
2897
|
-
get(param) {
|
|
2898
|
-
return this.http.post(this.url.get, param);
|
|
2899
|
-
}
|
|
2900
|
-
/**
|
|
2901
|
-
* Создает дочернюю папку
|
|
2902
|
-
*
|
|
2903
|
-
* @param param
|
|
2904
|
-
*/
|
|
2905
|
-
addSubFolder(param) {
|
|
2906
|
-
return this.http.post(this.url.addSubFolder, param);
|
|
2907
|
-
}
|
|
2908
|
-
/**
|
|
2909
|
-
* Копирует папку в указанную папку
|
|
2910
|
-
*
|
|
2911
|
-
* @param param
|
|
2912
|
-
*/
|
|
2913
|
-
copyTo(param) {
|
|
2914
|
-
return this.http.post(this.url.copyTo, param);
|
|
2915
|
-
}
|
|
2916
|
-
/**
|
|
2917
|
-
* Перемещает папку в указанную папку
|
|
2918
|
-
*
|
|
2919
|
-
* @param param
|
|
2920
|
-
*/
|
|
2921
|
-
moveTo(param) {
|
|
2922
|
-
return this.http.post(this.url.moveTo, param);
|
|
2923
|
-
}
|
|
2924
|
-
/**
|
|
2925
|
-
* Переименовывает папку
|
|
2926
|
-
*
|
|
2927
|
-
* @param param
|
|
2928
|
-
*/
|
|
2929
|
-
rename(param) {
|
|
2930
|
-
return this.http.post(this.url.rename, param);
|
|
2931
|
-
}
|
|
2932
|
-
/**
|
|
2933
|
-
* Уничтожает папку и всё её дочерние элементы навсегда
|
|
2934
|
-
* В ответе 'result': true - успешное уничтожение папки
|
|
2935
|
-
*
|
|
2936
|
-
* @param param
|
|
2937
|
-
*/
|
|
2938
|
-
deleteTree(param) {
|
|
2939
|
-
return this.http.post(this.url.deleteTree, param);
|
|
2940
|
-
}
|
|
2941
|
-
/**
|
|
2942
|
-
* Перемещает папку в корзину
|
|
2943
|
-
*
|
|
2944
|
-
* @param param
|
|
2945
|
-
*/
|
|
2946
|
-
markDeleted(param) {
|
|
2947
|
-
return this.http.post(this.url.markDeleted, param);
|
|
2948
|
-
}
|
|
2949
|
-
/**
|
|
2950
|
-
* Восстанавливает папку из корзины
|
|
2951
|
-
*
|
|
2952
|
-
* @param param
|
|
2953
|
-
*/
|
|
2954
|
-
restore(param) {
|
|
2955
|
-
return this.http.post(this.url.restore, param);
|
|
2956
|
-
}
|
|
2957
|
-
/**
|
|
2958
|
-
* Метод возвращает публичную ссылку
|
|
2959
|
-
*
|
|
2960
|
-
* @param param
|
|
2961
|
-
*/
|
|
2962
|
-
getExternalLink(param) {
|
|
2963
|
-
return this.http.post(this.url.restore, param);
|
|
2964
|
-
}
|
|
2965
|
-
/**
|
|
2966
|
-
* Возвращает описание полей папки
|
|
2967
|
-
*/
|
|
2968
|
-
getFields() {
|
|
2969
|
-
return this.http.post(this.url.getFields);
|
|
2970
|
-
}
|
|
2971
|
-
/**
|
|
2972
|
-
* Загружает новый файл в указанную папку
|
|
2973
|
-
*
|
|
2974
|
-
* @param param
|
|
2975
|
-
*/
|
|
2976
|
-
uploadFile(param) {
|
|
2977
|
-
return this.http.post(this.url.uploadFile, param);
|
|
2978
|
-
}
|
|
2979
|
-
/**
|
|
2980
|
-
* Возвращает список файлов и папок, которые находятся непосредственно в папке
|
|
2981
|
-
*
|
|
2982
|
-
* @param param
|
|
2983
|
-
*/
|
|
2984
|
-
getChildren(param) {
|
|
2985
|
-
return this.http.post(this.url.getChildren, param);
|
|
2986
|
-
}
|
|
2987
|
-
}
|
|
2988
|
-
|
|
2989
|
-
class BXRestDiskAttachedObject {
|
|
2990
|
-
constructor() {
|
|
2991
|
-
this.url = {
|
|
2992
|
-
get: [$disk, 'attachedObject', $get],
|
|
2993
|
-
};
|
|
2994
|
-
this.http = new HttpBXServices();
|
|
2995
|
-
}
|
|
2996
|
-
get(param) {
|
|
2997
|
-
return this.http.post(this.url.get, param);
|
|
2998
|
-
}
|
|
2999
|
-
}
|
|
3000
|
-
|
|
3001
|
-
class BXRestDisk {
|
|
3002
|
-
constructor() {
|
|
3003
|
-
this.file = new BXRestDiskFile();
|
|
3004
|
-
this.folder = new BXRestDiskFolder();
|
|
3005
|
-
this.attachedObject = new BXRestDiskAttachedObject();
|
|
3006
|
-
}
|
|
3007
|
-
}
|
|
3008
|
-
|
|
3009
|
-
class BXRestBizProcWorkflowInstance {
|
|
3010
|
-
}
|
|
3011
|
-
|
|
3012
|
-
class BXRestBizProcWorkflowTemplate {
|
|
3013
|
-
}
|
|
3014
|
-
|
|
3015
|
-
class HttpNavvyServices {
|
|
3016
|
-
constructor() {
|
|
3017
|
-
this.httpServices = new HttpBXServices();
|
|
3018
|
-
}
|
|
3019
|
-
// Реализация метода
|
|
3020
|
-
post(url, params) {
|
|
3021
|
-
if (params === undefined) {
|
|
3022
|
-
params = {};
|
|
3023
|
-
}
|
|
3024
|
-
return this.httpServices.post(url, params);
|
|
3025
|
-
}
|
|
3026
|
-
}
|
|
3027
|
-
|
|
3028
|
-
class BXRestBizProcWorkflow {
|
|
3029
|
-
constructor() {
|
|
3030
|
-
this.instances = new BXRestBizProcWorkflowInstance();
|
|
3031
|
-
this.template = new BXRestBizProcWorkflowTemplate();
|
|
3032
|
-
this.http = new HttpNavvyServices();
|
|
3033
|
-
}
|
|
3034
|
-
/**
|
|
3035
|
-
* Запускает Бизнес-процесс
|
|
3036
|
-
*/
|
|
3037
|
-
start(param) {
|
|
3038
|
-
return this.http.post([$bizproc, $workflow, $start], param);
|
|
3039
|
-
}
|
|
3040
|
-
}
|
|
3041
|
-
|
|
3042
|
-
class BXRestBizProcActivity {
|
|
3043
|
-
}
|
|
3044
|
-
|
|
3045
|
-
class BXRestBizProcTask {
|
|
3046
|
-
}
|
|
3047
|
-
|
|
3048
|
-
class BXRestBizProcRobot {
|
|
3049
|
-
}
|
|
3050
|
-
|
|
3051
|
-
class BXRestBizProcEvent {
|
|
3052
|
-
}
|
|
3053
|
-
|
|
3054
|
-
class BXRestBizProc {
|
|
3055
|
-
constructor() {
|
|
3056
|
-
this.workflow = new BXRestBizProcWorkflow();
|
|
3057
|
-
this.activity = new BXRestBizProcActivity();
|
|
3058
|
-
this.task = new BXRestBizProcTask();
|
|
3059
|
-
this.robot = new BXRestBizProcRobot();
|
|
3060
|
-
this.event = new BXRestBizProcEvent();
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
3063
|
-
|
|
3064
|
-
class BXRestLogBlogPost {
|
|
3065
|
-
constructor() {
|
|
3066
|
-
this.url = {
|
|
3067
|
-
add: [$log, $blogpost, $add],
|
|
3068
|
-
get: [$log, $blogpost, $get],
|
|
3069
|
-
};
|
|
3070
|
-
this.http = new HttpBXServices();
|
|
3071
|
-
}
|
|
3072
|
-
add(param) {
|
|
3073
|
-
return this.http.post(this.url.add, param);
|
|
3074
|
-
}
|
|
3075
|
-
get(param = {}) {
|
|
3076
|
-
return this.http.post(this.url.get, param);
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
|
|
3080
|
-
class BXRestLogBlogComment {
|
|
3081
|
-
}
|
|
3082
|
-
|
|
3083
|
-
class BXRestLog {
|
|
3084
|
-
constructor() {
|
|
3085
|
-
this.blogPost = new BXRestLogBlogPost();
|
|
3086
|
-
this.blogComment = new BXRestLogBlogComment();
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
|
|
3090
|
-
class BXRestSonetGroup {
|
|
3091
|
-
constructor() {
|
|
3092
|
-
this.url = {
|
|
3093
|
-
get: [$sonet_group, $get],
|
|
3094
|
-
};
|
|
3095
|
-
this.http = new HttpBXServices();
|
|
3096
|
-
}
|
|
3097
|
-
// // TODO: filter и select позже нормально описать
|
|
3098
|
-
// getList(filter: any = {}, select: iWorkgroupFields[] = ['ID', 'NAME']){
|
|
3099
|
-
// return this.httpPost<iHttpAnswerBX<{workgroups: iListWorkgroup[]}>>(
|
|
3100
|
-
// this.url.get,
|
|
3101
|
-
// {
|
|
3102
|
-
// order: select,
|
|
3103
|
-
// filter: filter
|
|
3104
|
-
// }
|
|
3105
|
-
// )
|
|
3106
|
-
// }
|
|
3107
|
-
get(param = {}) {
|
|
3108
|
-
return this.http.post(this.url.get, param);
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
|
|
3112
|
-
class BXRestServer {
|
|
3113
|
-
constructor() {
|
|
3114
|
-
this.http = new HttpBXServices();
|
|
3115
|
-
this.url = {
|
|
3116
|
-
time: [$server, $time],
|
|
3117
|
-
};
|
|
3118
|
-
}
|
|
3119
|
-
time() {
|
|
3120
|
-
return this.http.post(this.url.time);
|
|
3121
|
-
}
|
|
3122
|
-
}
|
|
3123
|
-
|
|
3124
|
-
class BXRestDepartment {
|
|
3125
|
-
constructor() {
|
|
3126
|
-
this.url = {
|
|
3127
|
-
get: [$department, $get],
|
|
3128
|
-
del: [$department, $delete],
|
|
3129
|
-
add: [$department, $add],
|
|
3130
|
-
update: [$department, $update],
|
|
3131
|
-
};
|
|
3132
|
-
this.http = new HttpBXServices();
|
|
3133
|
-
}
|
|
3134
|
-
get(param = {}) {
|
|
3135
|
-
return this.http.post(this.url.get, param);
|
|
3136
|
-
}
|
|
3137
|
-
add(param) {
|
|
3138
|
-
return this.http.post(this.url.add, param);
|
|
3139
|
-
}
|
|
3140
|
-
del(param) {
|
|
3141
|
-
return this.http.post(this.url.del, param);
|
|
3142
|
-
}
|
|
3143
|
-
update(param) {
|
|
3144
|
-
return this.http.post(this.url.update, param);
|
|
3145
|
-
}
|
|
3146
|
-
}
|
|
3147
|
-
|
|
3148
|
-
class BXRestApp {
|
|
3149
|
-
constructor() {
|
|
3150
|
-
this.http = new HttpBXServices();
|
|
3151
|
-
}
|
|
3152
|
-
/**
|
|
3153
|
-
* Показ информации о приложении. Метод поддерживает безопасный вызов
|
|
3154
|
-
*/
|
|
3155
|
-
info() {
|
|
3156
|
-
return this.http.post(['app', 'info']);
|
|
3157
|
-
}
|
|
3158
|
-
}
|
|
3159
|
-
|
|
3160
|
-
class BXRestSocialNetWorkApiContentView {
|
|
3161
|
-
constructor() {
|
|
3162
|
-
this.url = {
|
|
3163
|
-
set: [$socialnetwork, $api, 'contentView', $set],
|
|
3164
|
-
};
|
|
3165
|
-
this.http = new HttpBXServices();
|
|
3166
|
-
}
|
|
3167
|
-
set(param) {
|
|
3168
|
-
return this.http.post(this.url.set, param);
|
|
3169
|
-
}
|
|
3170
|
-
}
|
|
3171
|
-
|
|
3172
|
-
class BXRestSocialNetWorkApiLiveFeedBlogPostImportant {
|
|
3173
|
-
constructor() {
|
|
3174
|
-
this.url = {
|
|
3175
|
-
vote: [$socialnetwork, $api, 'liveFeed', 'blogPost', 'important', 'vote'],
|
|
3176
|
-
};
|
|
3177
|
-
this.http = new HttpBXServices();
|
|
3178
|
-
}
|
|
3179
|
-
vote(param) {
|
|
3180
|
-
return this.http.post(this.url.vote, param);
|
|
3181
|
-
}
|
|
3182
|
-
}
|
|
3183
|
-
|
|
3184
|
-
class BXRestSocialNetWorkApiLiveFeedBlogPost {
|
|
3185
|
-
constructor() {
|
|
3186
|
-
this.important = new BXRestSocialNetWorkApiLiveFeedBlogPostImportant();
|
|
3187
|
-
}
|
|
3188
|
-
}
|
|
3189
|
-
|
|
3190
|
-
class BXRestSocialNetWorkApiLiveFeed {
|
|
3191
|
-
constructor() {
|
|
3192
|
-
this.blogPost = new BXRestSocialNetWorkApiLiveFeedBlogPost();
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3195
|
-
|
|
3196
|
-
class BXRestSocialNetWorkApi {
|
|
3197
|
-
constructor() {
|
|
3198
|
-
this.contentView = new BXRestSocialNetWorkApiContentView();
|
|
3199
|
-
this.liveFeed = new BXRestSocialNetWorkApiLiveFeed();
|
|
3200
|
-
}
|
|
3201
|
-
}
|
|
3202
|
-
|
|
3203
|
-
class BXRestSocialNetWork {
|
|
3204
|
-
constructor() {
|
|
3205
|
-
// private http = new HttpBXServices)
|
|
3206
|
-
this.api = new BXRestSocialNetWorkApi();
|
|
3207
|
-
}
|
|
3208
|
-
}
|
|
3209
|
-
|
|
3210
|
-
class BXRestPullApplicationConfig {
|
|
3211
|
-
constructor() {
|
|
3212
|
-
this.http = new HttpBXServices();
|
|
3213
|
-
}
|
|
3214
|
-
get() {
|
|
3215
|
-
return this.http.post([$pull, $application, $config, $get]);
|
|
3216
|
-
}
|
|
3217
|
-
}
|
|
3218
|
-
|
|
3219
|
-
class BXRestPullConfig {
|
|
3220
|
-
constructor() {
|
|
3221
|
-
this.http = new HttpBXServices();
|
|
3222
|
-
this.config = new BXRestPullApplicationConfig();
|
|
3223
|
-
}
|
|
3224
|
-
get() {
|
|
3225
|
-
return this.http.post([$pull, $config, $get]);
|
|
3226
|
-
}
|
|
3227
|
-
}
|
|
3228
|
-
|
|
3229
|
-
class BXRestPullChannelPublic {
|
|
3230
|
-
constructor() {
|
|
3231
|
-
this.http = new HttpBXServices();
|
|
3232
|
-
/**
|
|
3233
|
-
* Пес его знает что за метод такой, судя по коду нужно всю инфу json объектом о пользователе передать,
|
|
3234
|
-
* но это не точно
|
|
3235
|
-
*/
|
|
3236
|
-
// list() {
|
|
3237
|
-
// return this.http.post<iBXRestPullChannelPublicGetHttp>([$pull, $channel, $public, $list])
|
|
3238
|
-
// }
|
|
3239
|
-
}
|
|
3240
|
-
get() {
|
|
3241
|
-
return this.http.post([$pull, $channel, $public, $get]);
|
|
3242
|
-
}
|
|
3243
|
-
}
|
|
3244
|
-
|
|
3245
|
-
class BXRestPull {
|
|
3246
|
-
constructor() {
|
|
3247
|
-
this.config = new BXRestPullConfig();
|
|
3248
|
-
this.channel = {
|
|
3249
|
-
public: new BXRestPullChannelPublic()
|
|
3250
|
-
};
|
|
3251
|
-
}
|
|
3252
|
-
}
|
|
3253
|
-
|
|
3254
|
-
class BXRest {
|
|
3255
|
-
constructor() {
|
|
3256
|
-
this.http = new HttpBXServices();
|
|
3257
|
-
this.user = new BXRestUser();
|
|
3258
|
-
this.lists = new BXRestLists();
|
|
3259
|
-
this.task = new BXRestTask();
|
|
3260
|
-
this.tasks = new BXRestTasks();
|
|
3261
|
-
this.disk = new BXRestDisk();
|
|
3262
|
-
this.bizProc = new BXRestBizProc();
|
|
3263
|
-
this.log = new BXRestLog();
|
|
3264
|
-
this.sonet_group = new BXRestSonetGroup();
|
|
3265
|
-
this.server = new BXRestServer();
|
|
3266
|
-
this.department = new BXRestDepartment();
|
|
3267
|
-
this.app = new BXRestApp();
|
|
3268
|
-
this.socialNetWork = new BXRestSocialNetWork();
|
|
3269
|
-
this.pull = new BXRestPull();
|
|
3270
|
-
}
|
|
3271
|
-
profile() {
|
|
3272
|
-
return this.http.post(['profile']);
|
|
3273
|
-
}
|
|
3274
|
-
batch(param, headers) {
|
|
3275
|
-
return this.http.post(['batch'], param, false, headers);
|
|
3276
|
-
}
|
|
3277
|
-
}
|
|
3278
|
-
|
|
3279
|
-
/**
|
|
3280
|
-
* Класс-прослойка-обработчик для методов работающих на альтернативной постраничной навигации тика как методы по
|
|
3281
|
-
* затраченному времени на задачи https://dev.1c-bitrix.ru/rest_help/tasks/task/elapseditem/index.php
|
|
3282
|
-
*
|
|
3283
|
-
* не завершенный класс, работаем от частного к общему
|
|
3284
|
-
*/
|
|
3285
|
-
class NavvyAlterPagNav extends NavvyPagBase {
|
|
3286
|
-
resAll() {
|
|
3287
|
-
let save = [];
|
|
3288
|
-
return this.resultAllEnd()
|
|
3289
|
-
.pipe(map(v => {
|
|
3290
|
-
if (v) {
|
|
3291
|
-
save.push(...v);
|
|
3292
|
-
}
|
|
3293
|
-
return save;
|
|
3294
|
-
}), last(), shareReplay(1));
|
|
3295
|
-
}
|
|
3296
|
-
resultAllEnd() {
|
|
3297
|
-
let BXRestClass = new BXRest();
|
|
3298
|
-
// return this.mapForVanillaEnd(this.func, this.param)
|
|
3299
|
-
return this.resFirstPage().pipe(mergeMap(items => {
|
|
3300
|
-
if (items && instanceOfiBXRestAnswerSuccess(items)) {
|
|
3301
|
-
if (items.total && items.next) {
|
|
3302
|
-
const count = [...Array(Math.floor(items.total / this.pageSize)).keys()];
|
|
3303
|
-
// Разделяем массив на блоки
|
|
3304
|
-
const chunks = [];
|
|
3305
|
-
for (let i = 0; i < count.length; i += this.pageSize) {
|
|
3306
|
-
chunks.push(count.slice(i, i + this.pageSize));
|
|
3307
|
-
}
|
|
3308
|
-
const batchRequests = chunks.map(chunk => {
|
|
3309
|
-
return BXRestClass.batch({
|
|
3310
|
-
halt: 1,
|
|
3311
|
-
cmd: chunk.map(i => {
|
|
3312
|
-
const param = clone(this.param);
|
|
3313
|
-
if (!param.PARAMS) {
|
|
3314
|
-
param.PARAMS = {
|
|
3315
|
-
NAV_PARAMS: {
|
|
3316
|
-
iNumPage: 0,
|
|
3317
|
-
nPageSize: 50
|
|
3318
|
-
}
|
|
3319
|
-
};
|
|
3320
|
-
}
|
|
3321
|
-
// Устанавливаем start в зависимости от индекса
|
|
3322
|
-
param.PARAMS.NAV_PARAMS.iNumPage = i + 2; // первая страница уже есть, старт со второй
|
|
3323
|
-
// Формируем строку запроса
|
|
3324
|
-
return this.http.getNameMethod(this.url)
|
|
3325
|
-
+ '?' + serializeBitrixParams(param);
|
|
3326
|
-
})
|
|
3327
|
-
}, this.requestHeaders);
|
|
3328
|
-
});
|
|
3329
|
-
return from(batchRequests).pipe(concatMap(request => request), // Выполняет запросы по очереди
|
|
3330
|
-
toArray(), // Собирает все результаты в массив
|
|
3331
|
-
map(results => {
|
|
3332
|
-
const res = items.result;
|
|
3333
|
-
for (let result of results) {
|
|
3334
|
-
if (result && instanceOfiBXRestAnswerSuccess(result) && result.result && result.result.result) {
|
|
3335
|
-
res.push(...result.result.result.map(i => i).flat());
|
|
3336
|
-
}
|
|
3337
|
-
}
|
|
3338
|
-
return (this.map) ?
|
|
3339
|
-
this.map(res)
|
|
3340
|
-
: res;
|
|
3341
|
-
}));
|
|
3342
|
-
}
|
|
3343
|
-
}
|
|
3344
|
-
return this.mapResultForGetAll(items);
|
|
3345
|
-
}), catchError(err => {
|
|
3346
|
-
// this.snackBar.error("Проблемы с поточным получение затреканого времени")
|
|
3347
|
-
console.error(err);
|
|
3348
|
-
return throwError(() => err);
|
|
3349
|
-
}));
|
|
3350
|
-
}
|
|
3351
|
-
mapResultForGetAll(items) {
|
|
3352
|
-
return (instanceOfiBXRestAnswerSuccess(items)) ? from([items.result]).pipe(map(v => (v && this.map) ? this.map(v) : v)) : from([]);
|
|
3353
|
-
}
|
|
3354
|
-
}
|
|
3355
|
-
|
|
3356
|
-
class NavvyPagNavWithUselessKey extends NavvyPagBase {
|
|
3357
|
-
constructor() {
|
|
3358
|
-
super(...arguments);
|
|
3359
|
-
this.save = [];
|
|
3360
|
-
}
|
|
3361
|
-
resAll() {
|
|
3362
|
-
let BXRestClass = new BXRest();
|
|
3363
|
-
return this.resFirstPage().pipe(mergeMap(items => {
|
|
3364
|
-
if (items && instanceOfiBXRestAnswerSuccess(items)) {
|
|
3365
|
-
if (items.total && items.next) {
|
|
3366
|
-
const count = [...Array(Math.floor(items.total / this.pageSize)).keys()];
|
|
3367
|
-
// Разделяем массив на блоки
|
|
3368
|
-
const chunks = [];
|
|
3369
|
-
for (let i = 0; i < count.length; i += this.pageSize) {
|
|
3370
|
-
chunks.push(count.slice(i, i + this.pageSize));
|
|
3371
|
-
}
|
|
3372
|
-
const batchRequests = chunks.map(chunk => {
|
|
3373
|
-
return BXRestClass.batch({
|
|
3374
|
-
halt: 1,
|
|
3375
|
-
cmd: chunk.map(i => {
|
|
3376
|
-
const param = clone(this.param);
|
|
3377
|
-
// Устанавливаем start в зависимости от индекса
|
|
3378
|
-
param.start = (i + 1) * this.pageSize;
|
|
3379
|
-
// Формируем строку запроса
|
|
3380
|
-
return this.http.getNameMethod(this.url)
|
|
3381
|
-
+ '?' + serializeBitrixParams(param);
|
|
3382
|
-
})
|
|
3383
|
-
}, this.requestHeaders).pipe(map(v => {
|
|
3384
|
-
if (v && instanceOfiBXRestAnswerSuccess(v) && v.result && v.result.result && items.result) {
|
|
3385
|
-
return Object.assign({}, items.result, v.result.result);
|
|
3386
|
-
}
|
|
3387
|
-
throw new Error('wrong batch');
|
|
3388
|
-
}));
|
|
3389
|
-
});
|
|
3390
|
-
return from(batchRequests).pipe(concatMap(request => request), // Выполняет запросы по очереди
|
|
3391
|
-
toArray()); // Собирает все результаты в массив
|
|
3392
|
-
/*
|
|
3393
|
-
return this.getAllTaskElapsedItem(func, param).pipe(
|
|
3394
|
-
map(vEnd => {
|
|
3395
|
-
if (vEnd && vEnd.result && items.result) {
|
|
3396
|
-
return merge(clone(vEnd), {result: [...items.result, ...vEnd.result]})
|
|
3397
|
-
}
|
|
3398
|
-
return items
|
|
3399
|
-
})
|
|
3400
|
-
)
|
|
3401
|
-
*/
|
|
3402
|
-
}
|
|
3403
|
-
else {
|
|
3404
|
-
return of([items.result]);
|
|
3405
|
-
}
|
|
3406
|
-
}
|
|
3407
|
-
return of(undefined);
|
|
3408
|
-
// return from([BXRestMapResult(items)])
|
|
3409
|
-
// as ReturnType<Observable<T | undefined>, Observable<R | undefined>>
|
|
3410
|
-
}), map(v => {
|
|
3411
|
-
if (v) {
|
|
3412
|
-
const mergedObject = v.reduce((acc, obj) => {
|
|
3413
|
-
return { ...acc, ...obj };
|
|
3414
|
-
}, {});
|
|
3415
|
-
if (this.map) {
|
|
3416
|
-
return this.map(mergedObject);
|
|
3417
|
-
}
|
|
3418
|
-
this.save.push(...v);
|
|
3419
|
-
return this.save;
|
|
3420
|
-
}
|
|
3421
|
-
return v;
|
|
3422
|
-
}), catchError(err => {
|
|
3423
|
-
// this.snackBar.error("Проблемы с поточным получение затреканого времени")
|
|
3424
|
-
console.error(err);
|
|
3425
|
-
return throwError(() => err);
|
|
3426
|
-
}));
|
|
3427
|
-
}
|
|
3428
|
-
}
|
|
3429
|
-
|
|
3430
|
-
class NavvyPagNavTasks extends NavvyPagBase {
|
|
3431
|
-
constructor(url, param, map, restApi) {
|
|
3432
|
-
// Без своего map результат — массив задач, как и обещают типы `.res()` и `.resAll()`.
|
|
3433
|
-
super(url, param, map ?? (result => (result?.tasks ?? [])), restApi);
|
|
3434
|
-
this.save = [];
|
|
3435
|
-
}
|
|
3436
|
-
resAll() {
|
|
3437
|
-
let save = [];
|
|
3438
|
-
return this.resultAllEnd()
|
|
3439
|
-
.pipe(map(v => {
|
|
3440
|
-
if (v) {
|
|
3441
|
-
save.push(...v);
|
|
3442
|
-
}
|
|
3443
|
-
return save;
|
|
3444
|
-
}), last(), shareReplay(1));
|
|
3445
|
-
}
|
|
3446
|
-
resultAllEnd() {
|
|
3447
|
-
let BXRestClass = new BXRest();
|
|
3448
|
-
return this.resFirstPage().pipe(mergeMap(items => {
|
|
3449
|
-
if (items && instanceOfiBXRestAnswerSuccess(items)) {
|
|
3450
|
-
this.save = [];
|
|
3451
|
-
// TODO: проверить будет ли быстрее работать метод в случаях когда total < 100 (то есть можно обойтись двумя прямыми запросами)
|
|
3452
|
-
if (items.total && items.total > 50) {
|
|
3453
|
-
const count = [...Array(Math.floor(items.total / this.pageSize)).keys()];
|
|
3454
|
-
// Разделяем массив на блоки
|
|
3455
|
-
const chunks = [];
|
|
3456
|
-
for (let i = 0; i < count.length; i += this.pageSize) {
|
|
3457
|
-
chunks.push(count.slice(i, i + this.pageSize));
|
|
3458
|
-
}
|
|
3459
|
-
const batchRequests = chunks.map(chunk => {
|
|
3460
|
-
return BXRestClass.batch({
|
|
3461
|
-
halt: 1,
|
|
3462
|
-
cmd: chunk.map(i => {
|
|
3463
|
-
const param = clone(this.param);
|
|
3464
|
-
// Устанавливаем start в зависимости от индекса
|
|
3465
|
-
param.start = (i + 1) * this.pageSize;
|
|
3466
|
-
// Формируем строку запроса
|
|
3467
|
-
return this.http.getNameMethod(this.url)
|
|
3468
|
-
+ '?' + serializeBitrixParams(param);
|
|
3469
|
-
})
|
|
3470
|
-
}, this.requestHeaders);
|
|
3471
|
-
});
|
|
3472
|
-
return from(batchRequests).pipe(concatMap(request => request), // Выполняет запросы по очереди
|
|
3473
|
-
toArray(), // Собирает все результаты в массив
|
|
3474
|
-
map(results => {
|
|
3475
|
-
if (items.result && items.result.tasks) {
|
|
3476
|
-
const res = items.result.tasks;
|
|
3477
|
-
for (let result of results) {
|
|
3478
|
-
if (result && instanceOfiBXRestAnswerSuccess(result) && result.result && result.result.result) {
|
|
3479
|
-
res.push(...result.result.result.filter(i => i).map(i => i.tasks).flat());
|
|
3480
|
-
}
|
|
3481
|
-
}
|
|
3482
|
-
return (this.map) ?
|
|
3483
|
-
this.map({ tasks: res })
|
|
3484
|
-
: res;
|
|
3485
|
-
}
|
|
3486
|
-
throw new Error('wrong batch');
|
|
3487
|
-
}));
|
|
3488
|
-
}
|
|
3489
|
-
return this.mapResForGetAll(items);
|
|
3490
|
-
}
|
|
3491
|
-
return this.mapResForGetAll(items);
|
|
3492
|
-
}), catchError(err => {
|
|
3493
|
-
console.error(err);
|
|
3494
|
-
return throwError(() => err);
|
|
3495
|
-
}));
|
|
3496
|
-
}
|
|
3497
|
-
mapResForGetAll(items) {
|
|
3498
|
-
return (instanceOfiBXRestAnswerSuccess(items)) ? from([items.result]).pipe(map(v => (v && this.map) ? this.map(v) : v)) : from([]);
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3501
|
-
|
|
3502
|
-
class NavvyPag extends NavvyPagBase {
|
|
3503
|
-
constructor() {
|
|
3504
|
-
super(...arguments);
|
|
3505
|
-
this.save = [];
|
|
3506
|
-
}
|
|
3507
|
-
resAll() {
|
|
3508
|
-
let BXRestClass = new BXRest();
|
|
3509
|
-
return this.resFirstPage().pipe(mergeMap(items => {
|
|
3510
|
-
if (items && instanceOfiBXRestAnswerSuccess(items)) {
|
|
3511
|
-
this.save = [];
|
|
3512
|
-
// TODO: проверить будет ли быстрее работать метод в случаях когда total < 100 (то есть можно обойтись двумя прямыми запросами)
|
|
3513
|
-
if (items.total && items.total > this.pageSize) {
|
|
3514
|
-
const mathFloor = Math.floor(items.total / this.pageSize);
|
|
3515
|
-
const count = (mathFloor === items.total / this.pageSize) // если mathFloor равен обычному делению, значит один запрос будет лишним, так как результат первой страницы уже есть, а последняя в данном случаи будет пустая (или с мусорными аднными)
|
|
3516
|
-
? [...Array(mathFloor - 1).keys()]
|
|
3517
|
-
: [...Array(mathFloor).keys()];
|
|
3518
|
-
// Разделяем массив на блоки
|
|
3519
|
-
const chunks = [];
|
|
3520
|
-
for (let i = 0; i < count.length; i += this.pageSize) {
|
|
3521
|
-
chunks.push(count.slice(i, i + this.pageSize));
|
|
3522
|
-
}
|
|
3523
|
-
const batchRequests = chunks.map(chunk => {
|
|
3524
|
-
return BXRestClass.batch({
|
|
3525
|
-
halt: 1,
|
|
3526
|
-
cmd: chunk.map(i => {
|
|
3527
|
-
const param = clone(this.param);
|
|
3528
|
-
// Устанавливаем start в зависимости от индекса
|
|
3529
|
-
param.start = (i + 1) * this.pageSize;
|
|
3530
|
-
// Формируем строку запроса
|
|
3531
|
-
return this.http.getNameMethod(this.url)
|
|
3532
|
-
+ '?' + serializeBitrixParams(param);
|
|
3533
|
-
})
|
|
3534
|
-
}, this.requestHeaders).pipe();
|
|
3535
|
-
});
|
|
3536
|
-
return from(batchRequests).pipe(concatMap(request => request), // Выполняет запросы по очереди
|
|
3537
|
-
toArray(), // Собирает все результаты в массив
|
|
3538
|
-
map(results => {
|
|
3539
|
-
const res = items.result;
|
|
3540
|
-
for (let result of results) {
|
|
3541
|
-
if (result && instanceOfiBXRestAnswerSuccess(result) && result.result && result.result.result) {
|
|
3542
|
-
res.push(...result.result.result.map(i => i).flat());
|
|
3543
|
-
}
|
|
3544
|
-
}
|
|
3545
|
-
return (this.map) ?
|
|
3546
|
-
this.map(res)
|
|
3547
|
-
: res;
|
|
3548
|
-
}));
|
|
3549
|
-
}
|
|
3550
|
-
return this.mapResForGetAll(items);
|
|
3551
|
-
}
|
|
3552
|
-
return this.mapResForGetAll(items);
|
|
3553
|
-
}), map(v => {
|
|
3554
|
-
if (v) {
|
|
3555
|
-
this.save.push(...v);
|
|
3556
|
-
}
|
|
3557
|
-
return this.save;
|
|
3558
|
-
}));
|
|
3559
|
-
}
|
|
3560
|
-
mapResForGetAll(items) {
|
|
3561
|
-
return (instanceOfiBXRestAnswerSuccess(items)) ? from([items.result]).pipe(map(v => (v && this.map) ? this.map(v) : v)) : from([]);
|
|
3562
|
-
}
|
|
3563
|
-
}
|
|
3564
|
-
|
|
3565
|
-
class NavvyPagNavResultKey extends NavvyPagBase {
|
|
3566
|
-
constructor(url, param, key, map) {
|
|
3567
|
-
// Без своего map результат — массив по ключу, как и обещают типы `.res()` и `.resAll()`.
|
|
3568
|
-
// Иначе `.res()` отдал бы весь объект `{ items: [...] }`, а `.resAll()` упал бы на нём
|
|
3569
|
-
// при 50 записях и меньше: первая страница разворачивается через `save.push(...v)`.
|
|
3570
|
-
super(url, param, map ?? (result => (result?.[key] ?? [])));
|
|
3571
|
-
this.key = key;
|
|
3572
|
-
this.save = [];
|
|
3573
|
-
}
|
|
3574
|
-
resAll() {
|
|
3575
|
-
let save = [];
|
|
3576
|
-
return this.resultAllEnd()
|
|
3577
|
-
.pipe(map(v => {
|
|
3578
|
-
if (v) {
|
|
3579
|
-
save.push(...v);
|
|
3580
|
-
}
|
|
3581
|
-
return save;
|
|
3582
|
-
}), last(), shareReplay(1));
|
|
3583
|
-
}
|
|
3584
|
-
resultAllEnd() {
|
|
3585
|
-
let BXRestClass = new BXRest();
|
|
3586
|
-
return this.resFirstPage().pipe(mergeMap(items => {
|
|
3587
|
-
if (items && instanceOfiBXRestAnswerSuccess(items)) {
|
|
3588
|
-
this.save = [];
|
|
3589
|
-
if (items.total && items.total > 50) {
|
|
3590
|
-
const mathFloor = Math.floor(items.total / this.pageSize);
|
|
3591
|
-
const count = (mathFloor === items.total / this.pageSize)
|
|
3592
|
-
? [...Array(mathFloor - 1).keys()]
|
|
3593
|
-
: [...Array(mathFloor).keys()];
|
|
3594
|
-
const chunks = [];
|
|
3595
|
-
for (let i = 0; i < count.length; i += this.pageSize) {
|
|
3596
|
-
chunks.push(count.slice(i, i + this.pageSize));
|
|
3597
|
-
}
|
|
3598
|
-
const batchRequests = chunks.map(chunk => {
|
|
3599
|
-
return BXRestClass.batch({
|
|
3600
|
-
halt: 1,
|
|
3601
|
-
cmd: chunk.map(i => {
|
|
3602
|
-
const param = clone(this.param);
|
|
3603
|
-
param.start = (i + 1) * this.pageSize;
|
|
3604
|
-
return this.http.getNameMethod(this.url)
|
|
3605
|
-
+ '?' + serializeBitrixParams(param);
|
|
3606
|
-
})
|
|
3607
|
-
}, this.requestHeaders);
|
|
3608
|
-
});
|
|
3609
|
-
return from(batchRequests).pipe(concatMap(request => request), toArray(), map(results => {
|
|
3610
|
-
const firstPage = items.result?.[this.key];
|
|
3611
|
-
if (firstPage) {
|
|
3612
|
-
const res = firstPage;
|
|
3613
|
-
for (let result of results) {
|
|
3614
|
-
if (result && instanceOfiBXRestAnswerSuccess(result) && result.result && result.result.result) {
|
|
3615
|
-
res.push(...result.result.result.filter(i => i).map(i => i[this.key]).flat());
|
|
3616
|
-
}
|
|
3617
|
-
}
|
|
3618
|
-
return (this.map) ?
|
|
3619
|
-
this.map({ [this.key]: res })
|
|
3620
|
-
: res;
|
|
3621
|
-
}
|
|
3622
|
-
throw new Error('wrong batch');
|
|
3623
|
-
}));
|
|
3624
|
-
}
|
|
3625
|
-
return this.mapResForGetAll(items);
|
|
3626
|
-
}
|
|
3627
|
-
return this.mapResForGetAll(items);
|
|
3628
|
-
}), catchError(err => {
|
|
3629
|
-
console.error(err);
|
|
3630
|
-
return throwError(() => err);
|
|
3631
|
-
}));
|
|
3632
|
-
}
|
|
3633
|
-
mapResForGetAll(items) {
|
|
3634
|
-
return (instanceOfiBXRestAnswerSuccess(items)) ? from([items.result]).pipe(map(v => (v && this.map) ? this.map(v) : v)) : from([]);
|
|
3635
|
-
}
|
|
3636
|
-
}
|
|
3637
|
-
|
|
3638
|
-
/** Пагинация для методов, возвращающих коллекцию как объект с идентификаторами в ключах. */
|
|
3639
|
-
class NavvyPagNavResultKeyObject extends NavvyPagBase {
|
|
3640
|
-
constructor(url, param, key, mapResult) {
|
|
3641
|
-
// Без своего map результат — значения объекта по ключу, как и обещают типы `.res()` и `.resAll()`.
|
|
3642
|
-
super(url, param, mapResult ?? (result => Object.values(result?.[key] ?? {})));
|
|
3643
|
-
this.key = key;
|
|
3644
|
-
}
|
|
3645
|
-
resAll() {
|
|
3646
|
-
return this.resultAllEnd().pipe(last(), shareReplay(1));
|
|
3647
|
-
}
|
|
3648
|
-
resultAllEnd() {
|
|
3649
|
-
const bxRest = new BXRest();
|
|
3650
|
-
return this.resFirstPage().pipe(mergeMap(items => {
|
|
3651
|
-
if (!items || !instanceOfiBXRestAnswerSuccess(items)) {
|
|
3652
|
-
return from([]);
|
|
3653
|
-
}
|
|
3654
|
-
if (!items.total || items.total <= this.pageSize) {
|
|
3655
|
-
return this.mapResult(items);
|
|
3656
|
-
}
|
|
3657
|
-
const pageCount = Math.ceil(items.total / this.pageSize);
|
|
3658
|
-
const commands = Array.from({ length: pageCount - 1 }, (_, index) => {
|
|
3659
|
-
const param = clone(this.param);
|
|
3660
|
-
param.start = (index + 1) * this.pageSize;
|
|
3661
|
-
return bxRest.batch({
|
|
3662
|
-
halt: 1,
|
|
3663
|
-
cmd: [this.http.getNameMethod(this.url) + '?' + serializeBitrixParams(param)]
|
|
3664
|
-
}, this.requestHeaders);
|
|
3665
|
-
});
|
|
3666
|
-
return from(commands).pipe(concatMap(request => request), toArray(), mergeMap(results => {
|
|
3667
|
-
const merged = { ...(items.result?.[this.key] ?? {}) };
|
|
3668
|
-
for (const result of results) {
|
|
3669
|
-
if (result && instanceOfiBXRestAnswerSuccess(result)) {
|
|
3670
|
-
for (const page of result.result?.result ?? []) {
|
|
3671
|
-
Object.assign(merged, page?.[this.key] ?? {});
|
|
3672
|
-
}
|
|
3673
|
-
}
|
|
3674
|
-
}
|
|
3675
|
-
return this.mapResult({ result: { [this.key]: merged } });
|
|
3676
|
-
}));
|
|
3677
|
-
}), catchError(error => {
|
|
3678
|
-
console.error(error);
|
|
3679
|
-
return throwError(() => error);
|
|
3680
|
-
}));
|
|
3681
|
-
}
|
|
3682
|
-
mapResult(items) {
|
|
3683
|
-
if (!instanceOfiBXRestAnswerSuccess(items)) {
|
|
3684
|
-
return from([]);
|
|
3685
|
-
}
|
|
3686
|
-
return from([items.result]).pipe(map$1(value => this.map?.(value)));
|
|
3687
|
-
}
|
|
3688
|
-
}
|
|
3689
|
-
|
|
3690
|
-
class NavvySupport {
|
|
3691
|
-
constructor(requestClass) {
|
|
3692
|
-
this.requestClass = requestClass;
|
|
3693
|
-
this.pageSize = 50; // стандартный размер страницы
|
|
3694
|
-
}
|
|
3695
|
-
mapAndError(request) {
|
|
3696
|
-
return request.pipe(map(v => BXRestMapResult(v)), catchError((err) => {
|
|
3697
|
-
console.error(err);
|
|
3698
|
-
throw new Error((err.error) ? err.error : err);
|
|
3699
|
-
}));
|
|
3700
|
-
}
|
|
3701
|
-
}
|
|
3702
|
-
|
|
3703
|
-
class Navvy {
|
|
3704
|
-
simple(url, arg, map) {
|
|
3705
|
-
return new NavvySimple(url, arg !== undefined ? arg : undefined, map);
|
|
3706
|
-
}
|
|
3707
|
-
simpleV3(url, arg, map) {
|
|
3708
|
-
return new NavvySimple(url, arg !== undefined ? arg : undefined, map, true);
|
|
3709
|
-
}
|
|
3710
|
-
/**
|
|
3711
|
-
* Новый, пока тестируемый метод для api методов с пагинацией
|
|
3712
|
-
*
|
|
3713
|
-
* @param url
|
|
3714
|
-
* @param arg
|
|
3715
|
-
* @param map
|
|
3716
|
-
* @constructor
|
|
3717
|
-
*/
|
|
3718
|
-
pagNav(url, arg, map) {
|
|
3719
|
-
return new NavvyPag(url, arg, map);
|
|
3720
|
-
}
|
|
3721
|
-
// old PagNav
|
|
3722
|
-
// PagNav<T, R, A extends iBXRestPagination>(
|
|
3723
|
-
// func: (param: A) => Observable<iBXRestAnswer<T[]> | undefined>,
|
|
3724
|
-
// arg: A,
|
|
3725
|
-
// map: ((param: T[] | undefined) => R[] | undefined) | undefined) {
|
|
3726
|
-
// return new NavvyPagNav(this.requestClass, this.mapClass, func, arg, map)
|
|
3727
|
-
// }
|
|
3728
|
-
// Batch<T, R, A extends iBXRestPagination>(
|
|
3729
|
-
// func: (param: A) => Observable<iBXRestAnswer<T[]> | undefined>,
|
|
3730
|
-
// arg: A,
|
|
3731
|
-
// map: ((param: T[] | undefined) => R[] | undefined) | undefined) {
|
|
3732
|
-
// return new NavvyBatch(this.requestClass, this.mapClass, func, arg, map)
|
|
3733
|
-
// }
|
|
3734
|
-
pagNavTasks(url,
|
|
3735
|
-
// func: (param: A) => Observable<iBXRestAnswer<{tasks: T[] | undefined}> | undefined>,
|
|
3736
|
-
arg, map) {
|
|
3737
|
-
return new NavvyPagNavTasks(url, arg, map);
|
|
3738
|
-
}
|
|
3739
|
-
pagNavResultKey(url, arg, key, map) {
|
|
3740
|
-
return new NavvyPagNavResultKey(url, arg, key, map);
|
|
3741
|
-
}
|
|
3742
|
-
pagNavResultKeyObject(url, arg, key, map) {
|
|
3743
|
-
return new NavvyPagNavResultKeyObject(url, arg, key, map);
|
|
3744
|
-
}
|
|
3745
|
-
pagNavWithUselessKey(url,
|
|
3746
|
-
// func: (param: A) => Observable<iBXRestAnswer<{ [key: string]: T }> | undefined>,
|
|
3747
|
-
arg, map) {
|
|
3748
|
-
return new NavvyPagNavWithUselessKey(url, arg, map);
|
|
3749
|
-
}
|
|
3750
|
-
alterPagNav(url,
|
|
3751
|
-
// func: (param: A) => Observable<iBXRestAnswer<T[]> | undefined>,
|
|
3752
|
-
arg, map) {
|
|
3753
|
-
return new NavvyAlterPagNav(url, arg, map);
|
|
3754
|
-
}
|
|
3755
|
-
}
|
|
2590
|
+
$read: $read,
|
|
2591
|
+
$reading: $reading,
|
|
2592
|
+
$recall: $recall,
|
|
2593
|
+
$recent: $recent,
|
|
2594
|
+
$recipient: $recipient,
|
|
2595
|
+
$record: $record,
|
|
2596
|
+
$recurring: $recurring,
|
|
2597
|
+
$region: $region,
|
|
2598
|
+
$register: $register,
|
|
2599
|
+
$remove: $remove,
|
|
2600
|
+
$removeAttachments: $removeAttachments,
|
|
2601
|
+
$removeCard: $removeCard,
|
|
2602
|
+
$removeEntities: $removeEntities,
|
|
2603
|
+
$removecrmactivity: $removecrmactivity,
|
|
2604
|
+
$rename: $rename,
|
|
2605
|
+
$renew: $renew,
|
|
2606
|
+
$reply: $reply,
|
|
2607
|
+
$repo: $repo,
|
|
2608
|
+
$report: $report,
|
|
2609
|
+
$reports: $reports,
|
|
2610
|
+
$repowidget: $repowidget,
|
|
2611
|
+
$request: $request,
|
|
2612
|
+
$requisite: $requisite,
|
|
2613
|
+
$reset: $reset,
|
|
2614
|
+
$resolveIdByPublicUrl: $resolveIdByPublicUrl,
|
|
2615
|
+
$resource: $resource,
|
|
2616
|
+
$resourcetype: $resourcetype,
|
|
2617
|
+
$restore: $restore,
|
|
2618
|
+
$restoreFromVersion: $restoreFromVersion,
|
|
2619
|
+
$result: $result,
|
|
2620
|
+
$resume: $resume,
|
|
2621
|
+
$revision: $revision,
|
|
2622
|
+
$rights: $rights,
|
|
2623
|
+
$robot: $robot,
|
|
2624
|
+
$role: $role,
|
|
2625
|
+
$roundingRule: $roundingRule,
|
|
2626
|
+
$sale: $sale,
|
|
2627
|
+
$save: $save,
|
|
2628
|
+
$schedule: $schedule,
|
|
2629
|
+
$schema: $schema,
|
|
2630
|
+
$search: $search,
|
|
2631
|
+
$searchCrmEntities: $searchCrmEntities,
|
|
2632
|
+
$section: $section,
|
|
2633
|
+
$send: $send,
|
|
2634
|
+
$sendContext: $sendContext,
|
|
2635
|
+
$sendMessage: $sendMessage,
|
|
2636
|
+
$sender: $sender,
|
|
2637
|
+
$senders: $senders,
|
|
2638
|
+
$server: $server,
|
|
2639
|
+
$service: $service,
|
|
2640
|
+
$session: $session,
|
|
2641
|
+
$set: $set,
|
|
2642
|
+
$setAccessCodes: $setAccessCodes,
|
|
2643
|
+
$setDelivery: $setDelivery,
|
|
2644
|
+
$setLandingRef: $setLandingRef,
|
|
2645
|
+
$setOwner: $setOwner,
|
|
2646
|
+
$setQuantity: $setQuantity,
|
|
2647
|
+
$setRights: $setRights,
|
|
2648
|
+
$setSiteRef: $setSiteRef,
|
|
2649
|
+
$setowner: $setowner,
|
|
2650
|
+
$settings: $settings,
|
|
2651
|
+
$share: $share,
|
|
2652
|
+
$sharetouser: $sharetouser,
|
|
2653
|
+
$shipment: $shipment,
|
|
2654
|
+
$shipmentItem: $shipmentItem,
|
|
2655
|
+
$shipmentProperty: $shipmentProperty,
|
|
2656
|
+
$shipmentPropertyValue: $shipmentPropertyValue,
|
|
2657
|
+
$show: $show,
|
|
2658
|
+
$showBlock: $showBlock,
|
|
2659
|
+
$sign: $sign,
|
|
2660
|
+
$silent: $silent,
|
|
2661
|
+
$sip: $sip,
|
|
2662
|
+
$site: $site,
|
|
2663
|
+
$skip: $skip,
|
|
2664
|
+
$sku: $sku,
|
|
2665
|
+
$slots: $slots,
|
|
2666
|
+
$socialnetwork: $socialnetwork,
|
|
2667
|
+
$sonet_group: $sonet_group,
|
|
2668
|
+
$source: $source,
|
|
2669
|
+
$spam: $spam,
|
|
2670
|
+
$stagehistory: $stagehistory,
|
|
2671
|
+
$stages: $stages,
|
|
2672
|
+
$start: $start,
|
|
2673
|
+
$startwatch: $startwatch,
|
|
2674
|
+
$startwithsound: $startwithsound,
|
|
2675
|
+
$startwithtext: $startwithtext,
|
|
2676
|
+
$statistic: $statistic,
|
|
2677
|
+
$status: $status,
|
|
2678
|
+
$statusLang: $statusLang,
|
|
2679
|
+
$statuslist: $statuslist,
|
|
2680
|
+
$stop: $stop,
|
|
2681
|
+
$stopwatch: $stopwatch,
|
|
2682
|
+
$storage: $storage,
|
|
2683
|
+
$store: $store,
|
|
2684
|
+
$storeProduct: $storeProduct,
|
|
2685
|
+
$subscribe: $subscribe,
|
|
2686
|
+
$syspage: $syspage,
|
|
2687
|
+
$system: $system,
|
|
2688
|
+
$tail: $tail,
|
|
2689
|
+
$task: $task,
|
|
2690
|
+
$tasks: $tasks,
|
|
2691
|
+
$telephony: $telephony,
|
|
2692
|
+
$template: $template,
|
|
2693
|
+
$terminate: $terminate,
|
|
2694
|
+
$text: $text,
|
|
2695
|
+
$textField: $textField,
|
|
2696
|
+
$thread: $thread,
|
|
2697
|
+
$time: $time,
|
|
2698
|
+
$timeMan: $timeMan,
|
|
2699
|
+
$timecontrol: $timecontrol,
|
|
2700
|
+
$timeline: $timeline,
|
|
2701
|
+
$todo: $todo,
|
|
2702
|
+
$trace: $trace,
|
|
2703
|
+
$tracking: $tracking,
|
|
2704
|
+
$tradeBinding: $tradeBinding,
|
|
2705
|
+
$tradePlatform: $tradePlatform,
|
|
2706
|
+
$transfer: $transfer,
|
|
2707
|
+
$tree: $tree,
|
|
2708
|
+
$trigger: $trigger,
|
|
2709
|
+
$tts: $tts,
|
|
2710
|
+
$type: $type,
|
|
2711
|
+
$types: $types,
|
|
2712
|
+
$unbind: $unbind,
|
|
2713
|
+
$unbindingFromGroup: $unbindingFromGroup,
|
|
2714
|
+
$unbindingFromMenu: $unbindingFromMenu,
|
|
2715
|
+
$unfavoriteBlock: $unfavoriteBlock,
|
|
2716
|
+
$unmute: $unmute,
|
|
2717
|
+
$unpay: $unpay,
|
|
2718
|
+
$unpin: $unpin,
|
|
2719
|
+
$unpinAll: $unpinAll,
|
|
2720
|
+
$unpublic: $unpublic,
|
|
2721
|
+
$unpublicFolder: $unpublicFolder,
|
|
2722
|
+
$unread: $unread,
|
|
2723
|
+
$unregister: $unregister,
|
|
2724
|
+
$unset: $unset,
|
|
2725
|
+
$unsubscribe: $unsubscribe,
|
|
2726
|
+
$upBlock: $upBlock,
|
|
2727
|
+
$update: $update,
|
|
2728
|
+
$updateAttrs: $updateAttrs,
|
|
2729
|
+
$updateAvatar: $updateAvatar,
|
|
2730
|
+
$updateCards: $updateCards,
|
|
2731
|
+
$updateCatalogProduct: $updateCatalogProduct,
|
|
2732
|
+
$updateColor: $updateColor,
|
|
2733
|
+
$updateContent: $updateContent,
|
|
2734
|
+
$updateDeadline: $updateDeadline,
|
|
2735
|
+
$updateDescription: $updateDescription,
|
|
2736
|
+
$updateFolder: $updateFolder,
|
|
2737
|
+
$updateNodes: $updateNodes,
|
|
2738
|
+
$updateResponsibleUser: $updateResponsibleUser,
|
|
2739
|
+
$updateStyles: $updateStyles,
|
|
2740
|
+
$updateTitle: $updateTitle,
|
|
2741
|
+
$upload: $upload,
|
|
2742
|
+
$uploadFile: $uploadFile,
|
|
2743
|
+
$uploadfile: $uploadfile,
|
|
2744
|
+
$uploadversion: $uploadversion,
|
|
2745
|
+
$url: $url,
|
|
2746
|
+
$user: $user,
|
|
2747
|
+
$userconsent: $userconsent,
|
|
2748
|
+
$userfield: $userfield,
|
|
2749
|
+
$userfieldtype: $userfieldtype,
|
|
2750
|
+
$users: $users,
|
|
2751
|
+
$v1: $v1,
|
|
2752
|
+
$v2: $v2,
|
|
2753
|
+
$vat: $vat,
|
|
2754
|
+
$version: $version,
|
|
2755
|
+
$voices: $voices,
|
|
2756
|
+
$volatileType: $volatileType,
|
|
2757
|
+
$vote: $vote,
|
|
2758
|
+
$voximplant: $voximplant,
|
|
2759
|
+
$waitlist: $waitlist,
|
|
2760
|
+
$workflow: $workflow,
|
|
2761
|
+
$workgroup: $workgroup,
|
|
2762
|
+
$writing: $writing
|
|
2763
|
+
});
|
|
3756
2764
|
|
|
3757
2765
|
class BXRestNavvyUserUserfield {
|
|
3758
2766
|
constructor() {
|
|
@@ -3801,8 +2809,9 @@ class BXRestMapUser {
|
|
|
3801
2809
|
let res = Object.assign(clone(user), {
|
|
3802
2810
|
ID: toNum(user.ID),
|
|
3803
2811
|
IS_ONLINE: toBool(user.IS_ONLINE),
|
|
3804
|
-
|
|
3805
|
-
|
|
2812
|
+
// Дня рождения может не быть вовсе (пустая строка), а при урезанном scope нет и самих полей
|
|
2813
|
+
DATE_REGISTER: user.DATE_REGISTER ? toDate(user.DATE_REGISTER) : undefined,
|
|
2814
|
+
PERSONAL_BIRTHDAY: user.PERSONAL_BIRTHDAY ? toDate(user.PERSONAL_BIRTHDAY) : undefined,
|
|
3806
2815
|
});
|
|
3807
2816
|
if (user.LAST_LOGIN) {
|
|
3808
2817
|
res.LAST_LOGIN = toDate(user.LAST_LOGIN);
|
|
@@ -3813,7 +2822,7 @@ class BXRestMapUser {
|
|
|
3813
2822
|
return Object.assign(clone(user), {
|
|
3814
2823
|
ID: toStr(user.ID),
|
|
3815
2824
|
IS_ONLINE: toBXYorN(user.IS_ONLINE),
|
|
3816
|
-
DATE_REGISTER: toISOStringWithTimezone(user.DATE_REGISTER),
|
|
2825
|
+
DATE_REGISTER: user.DATE_REGISTER ? toISOStringWithTimezone(user.DATE_REGISTER) : '',
|
|
3817
2826
|
PERSONAL_BIRTHDAY: toStr(user.PERSONAL_BIRTHDAY),
|
|
3818
2827
|
LAST_LOGIN: toStr(user.LAST_LOGIN)
|
|
3819
2828
|
});
|
|
@@ -4306,8 +3315,8 @@ class BXRestMapTasksTaskResult {
|
|
|
4306
3315
|
}
|
|
4307
3316
|
|
|
4308
3317
|
class BXRestMapTasksTask {
|
|
4309
|
-
|
|
4310
|
-
|
|
3318
|
+
static get result() {
|
|
3319
|
+
return BXRestMapTasksTaskResult;
|
|
4311
3320
|
}
|
|
4312
3321
|
static getAccess(v) {
|
|
4313
3322
|
return (v && v.allowedActions) ? v.allowedActions : undefined;
|
|
@@ -4696,12 +3705,6 @@ class BXRestNavvyTasksTask {
|
|
|
4696
3705
|
* Переводит задачу в статус «завершена»
|
|
4697
3706
|
*/
|
|
4698
3707
|
complete: [$tasks, $task, $complete],
|
|
4699
|
-
// counters: {
|
|
4700
|
-
// /**
|
|
4701
|
-
// * Получает счетчики пользователя
|
|
4702
|
-
// */
|
|
4703
|
-
// get: [$tasks, $task, $counters, $get],
|
|
4704
|
-
// },
|
|
4705
3708
|
/**
|
|
4706
3709
|
* Переводит задачу в статус «отложена»
|
|
4707
3710
|
*/
|
|
@@ -4714,30 +3717,6 @@ class BXRestNavvyTasksTask {
|
|
|
4714
3717
|
* Возвращает информацию о конкретной задаче
|
|
4715
3718
|
*/
|
|
4716
3719
|
get: [$tasks, $task, $get],
|
|
4717
|
-
// /**
|
|
4718
|
-
// * Удаляет задачу
|
|
4719
|
-
// */
|
|
4720
|
-
// delete: [$tasks, $task, $delete],
|
|
4721
|
-
// /**
|
|
4722
|
-
// * Позволяет отклонить задачу
|
|
4723
|
-
// */
|
|
4724
|
-
// disapprove: [$tasks, $task, $disapprove],
|
|
4725
|
-
// favorite: {
|
|
4726
|
-
// /**
|
|
4727
|
-
// * Добавляет задачи в "Избранное"
|
|
4728
|
-
// */
|
|
4729
|
-
// add: [$tasks, $task, $favorite, $add],
|
|
4730
|
-
// /**
|
|
4731
|
-
// * Удаляет задачи из "Избранного"
|
|
4732
|
-
// */
|
|
4733
|
-
// delete: [$tasks, $task, $favorite, $delete],
|
|
4734
|
-
// },
|
|
4735
|
-
// files: {
|
|
4736
|
-
// /**
|
|
4737
|
-
// * Прикрепляет загруженный на диск файл к задаче
|
|
4738
|
-
// */
|
|
4739
|
-
// attach: [$tasks, $task, $files, $attach],
|
|
4740
|
-
// },
|
|
4741
3720
|
/**
|
|
4742
3721
|
* Возвращает все доступные поля
|
|
4743
3722
|
*/
|
|
@@ -4746,36 +3725,10 @@ class BXRestNavvyTasksTask {
|
|
|
4746
3725
|
* Метод для проверки доступа к задаче
|
|
4747
3726
|
*/
|
|
4748
3727
|
getAccess: [$tasks, $task, $getaccess],
|
|
4749
|
-
// history: {
|
|
4750
|
-
// /**
|
|
4751
|
-
// * Получает историю задачи
|
|
4752
|
-
// */
|
|
4753
|
-
// list: [$tasks, $task, $history, $list],
|
|
4754
|
-
// },
|
|
4755
3728
|
/**
|
|
4756
3729
|
* Возвращает массив задач, каждая из которых содержит массив полей
|
|
4757
3730
|
*/
|
|
4758
3731
|
list: [$tasks, $task, $list],
|
|
4759
|
-
// /**
|
|
4760
|
-
// * Останавливает выполнение задачи, переводя ее в статус "ждет выполнения"
|
|
4761
|
-
// */
|
|
4762
|
-
// pause: [$tasks, $task, $pause],
|
|
4763
|
-
// /**
|
|
4764
|
-
// * Возобновляет задачу после ее завершения
|
|
4765
|
-
// */
|
|
4766
|
-
// renew: [$tasks, $task, $renew],
|
|
4767
|
-
// /**
|
|
4768
|
-
// * Переводит задачу в статус «выполняется»
|
|
4769
|
-
// */
|
|
4770
|
-
// start: [$tasks, $task, $start],
|
|
4771
|
-
// /**
|
|
4772
|
-
// * Позволяет наблюдать за задачей
|
|
4773
|
-
// */
|
|
4774
|
-
// startWatch: [$tasks, $task, 'startwatch'],
|
|
4775
|
-
// /**
|
|
4776
|
-
// * Останавливает наблюдение за задачей
|
|
4777
|
-
// */
|
|
4778
|
-
// stopwatch: [$tasks, $task, 'stopwatch'],
|
|
4779
3732
|
/**
|
|
4780
3733
|
* Обновляет задачу
|
|
4781
3734
|
*/
|
|
@@ -4880,68 +3833,6 @@ class BXRestNavvyTasksTask {
|
|
|
4880
3833
|
list(param = {}) {
|
|
4881
3834
|
return this.Navvy.pagNavTasks(this.url.list, param, (BXRestMapTasksTask.list));
|
|
4882
3835
|
}
|
|
4883
|
-
/*
|
|
4884
|
-
listArray(requestArray: RequestApiTaskListBX = {}) {
|
|
4885
|
-
return this.list(requestArray).pipe(
|
|
4886
|
-
map(v => this.http.mapResult(v)),
|
|
4887
|
-
map(v => (v && v.tasks) ? v.tasks : [])
|
|
4888
|
-
)
|
|
4889
|
-
}
|
|
4890
|
-
|
|
4891
|
-
listAll(requestArray: RequestApiTaskListBX = {}, cache = false): Observable<TaskBX[]> {
|
|
4892
|
-
if (!requestArray.select) {
|
|
4893
|
-
requestArray.select = this.def.select
|
|
4894
|
-
if (cache) {
|
|
4895
|
-
return this.storeTask$.pipe(
|
|
4896
|
-
take(1),
|
|
4897
|
-
mergeMap(tasks => {
|
|
4898
|
-
if (tasks && tasks.data.http.list && requestArray.filter && requestArray.filter.ID) {
|
|
4899
|
-
const ids = (typeof requestArray.filter.ID === 'number') ? [requestArray.filter.ID] : requestArray.filter.ID
|
|
4900
|
-
let filter = tasks.data.http.list.filter(i => (i.id) ? ids.includes(i.id) : false)
|
|
4901
|
-
if (filter.length === ids.length) {
|
|
4902
|
-
return of(filter)
|
|
4903
|
-
}
|
|
4904
|
-
}
|
|
4905
|
-
return this.getEndListArray(requestArray)
|
|
4906
|
-
})
|
|
4907
|
-
)
|
|
4908
|
-
}
|
|
4909
|
-
return this.getEndListArray(requestArray)
|
|
4910
|
-
}
|
|
4911
|
-
return this.getEndListArray(requestArray)
|
|
4912
|
-
}
|
|
4913
|
-
|
|
4914
|
-
getEndListArray(requestArray: RequestApiTaskListBX): Observable<TaskBX[]> {
|
|
4915
|
-
return this.list(requestArray).pipe(
|
|
4916
|
-
mergeMap((items: AnswerApiTaskBX | undefined): ObservableInput<any> | Observable<AnswerApiTaskBX[]> => {
|
|
4917
|
-
if (items && items.result && typeof items.result.tasks === 'object') {
|
|
4918
|
-
const items$ = of(items.result.tasks)
|
|
4919
|
-
if (items.next) {
|
|
4920
|
-
this.nowLoad$.next({
|
|
4921
|
-
total: (items.total) ? items.total : 0,
|
|
4922
|
-
next: items.next
|
|
4923
|
-
})
|
|
4924
|
-
requestArray.start = items.next
|
|
4925
|
-
return this.getEndListArray(requestArray).pipe(
|
|
4926
|
-
map(vEnd => {
|
|
4927
|
-
if (vEnd && items.result.tasks) {
|
|
4928
|
-
return [...items.result.tasks, ...vEnd]
|
|
4929
|
-
}
|
|
4930
|
-
return (items.result.tasks) ? items.result.tasks : []
|
|
4931
|
-
}))
|
|
4932
|
-
}
|
|
4933
|
-
this.nowLoad$.next({
|
|
4934
|
-
total: 0,
|
|
4935
|
-
next: 0
|
|
4936
|
-
})
|
|
4937
|
-
return items$
|
|
4938
|
-
} else {
|
|
4939
|
-
return of([])
|
|
4940
|
-
}
|
|
4941
|
-
})
|
|
4942
|
-
)
|
|
4943
|
-
}
|
|
4944
|
-
*/
|
|
4945
3836
|
/**
|
|
4946
3837
|
* Возвращает список полей задачи.
|
|
4947
3838
|
*/
|
|
@@ -5272,6 +4163,10 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5272
4163
|
* Возвращает список записей о затраченном времени по задаче.
|
|
5273
4164
|
*/
|
|
5274
4165
|
getListByIDTask(ids) {
|
|
4166
|
+
// Пустой batch завершается без значения, и вызывающий код получил бы EmptyError
|
|
4167
|
+
if (!ids.length) {
|
|
4168
|
+
return of([]);
|
|
4169
|
+
}
|
|
5275
4170
|
// Работает только потому что "nPageSize: 99999"
|
|
5276
4171
|
return this.http.branch(ids.map(i => {
|
|
5277
4172
|
return {
|
|
@@ -5374,33 +4269,17 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5374
4269
|
* @param userCurrent
|
|
5375
4270
|
*/
|
|
5376
4271
|
checkPermissionAddElapsedTimeToTask(idTask, userCurrent = undefined) {
|
|
5377
|
-
// let permission = Permission.get()
|
|
5378
|
-
// if (permission?.tasks?.length) {
|
|
5379
|
-
// let findTask = permission.tasks.find(i => i.id === idTask)
|
|
5380
|
-
// if (findTask?.permission) {
|
|
5381
|
-
// return of(findTask.permission['ELAPSEDTIME.ADD'])
|
|
5382
|
-
// }
|
|
5383
4272
|
return ((userCurrent) ? of(userCurrent) : this.BXRestNavvyUser.current().res()).pipe(mergeMap(self => {
|
|
5384
4273
|
if (self) {
|
|
5385
4274
|
return this.BXRestNavvyTasks.task.getAccess({
|
|
5386
4275
|
id: idTask,
|
|
5387
4276
|
users: [self.ID]
|
|
5388
|
-
}).res().pipe(
|
|
5389
|
-
// tap(v => {
|
|
5390
|
-
// if (v && v[self.ID]) {
|
|
5391
|
-
// Permission.set({
|
|
5392
|
-
// tasks: [{id: idTask, permission: v[self.ID], elapsedItem: []}]
|
|
5393
|
-
// })
|
|
5394
|
-
// }
|
|
5395
|
-
// }),
|
|
5396
|
-
map(v => {
|
|
4277
|
+
}).res().pipe(map(v => {
|
|
5397
4278
|
return (v && v[self.ID]) ? v[self.ID]['ELAPSEDTIME.ADD'] : false;
|
|
5398
4279
|
}));
|
|
5399
4280
|
}
|
|
5400
4281
|
return of(undefined);
|
|
5401
4282
|
}));
|
|
5402
|
-
// }
|
|
5403
|
-
// return of(undefined)
|
|
5404
4283
|
}
|
|
5405
4284
|
/**
|
|
5406
4285
|
* Проверка на возможность прочтения такски
|
|
@@ -5409,35 +4288,17 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5409
4288
|
* @param userCurrent
|
|
5410
4289
|
*/
|
|
5411
4290
|
checkPermissionReadTask(idTask, userCurrent = undefined) {
|
|
5412
|
-
// let permission = Permission.get()
|
|
5413
|
-
// if (permission?.tasks?.length) {
|
|
5414
|
-
// let findTask = permission.tasks.find(i => i.id === idTask)
|
|
5415
|
-
// if (findTask?.permission) {
|
|
5416
|
-
// return of(findTask.permission.ACCEPT)
|
|
5417
|
-
// }
|
|
5418
|
-
// console.log('idTask', idTask)
|
|
5419
4291
|
return ((userCurrent) ? of(userCurrent) : this.BXRestNavvyUser.current().res()).pipe(mergeMap(self => {
|
|
5420
4292
|
if (self) {
|
|
5421
4293
|
return this.BXRestNavvyTasks.task.getAccess({
|
|
5422
4294
|
id: idTask,
|
|
5423
4295
|
users: [self.ID]
|
|
5424
|
-
}).res().pipe(
|
|
5425
|
-
// tap(v => {
|
|
5426
|
-
// if (v && v[self.ID]) {
|
|
5427
|
-
// Permission.set({
|
|
5428
|
-
// tasks: [{id: idTask, permission: v[self.ID], elapsedItem: []}]
|
|
5429
|
-
// })
|
|
5430
|
-
// }
|
|
5431
|
-
// }),
|
|
5432
|
-
map(v => {
|
|
4296
|
+
}).res().pipe(map(v => {
|
|
5433
4297
|
return (v && v[self.ID]) ? !!v[self.ID] : false; // отдельного флага на чтение нет, выходит что если права отдались то и права есть
|
|
5434
4298
|
}));
|
|
5435
4299
|
}
|
|
5436
4300
|
return of(undefined);
|
|
5437
4301
|
}));
|
|
5438
|
-
// }
|
|
5439
|
-
//
|
|
5440
|
-
// return of(undefined)
|
|
5441
4302
|
}
|
|
5442
4303
|
/**
|
|
5443
4304
|
* Законченный метод добавления записи с предварительной проверкой прав
|
|
@@ -5453,12 +4314,12 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5453
4314
|
return this.BXRestNavvyElapsedItem.add(param).res();
|
|
5454
4315
|
}
|
|
5455
4316
|
else {
|
|
5456
|
-
return throwError(() => new Error('
|
|
4317
|
+
return throwError(() => new Error('No permission to add an elapsed time record to the task'));
|
|
5457
4318
|
}
|
|
5458
4319
|
}));
|
|
5459
4320
|
}
|
|
5460
4321
|
else {
|
|
5461
|
-
return throwError(() => new Error('
|
|
4322
|
+
return throwError(() => new Error('No permission to read the task'));
|
|
5462
4323
|
}
|
|
5463
4324
|
}));
|
|
5464
4325
|
}
|
|
@@ -5475,48 +4336,21 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5475
4336
|
if (allowed) {
|
|
5476
4337
|
return this.BXRestNavvyElapsedItem.update(param).res();
|
|
5477
4338
|
}
|
|
5478
|
-
return throwError(() => new Error('
|
|
4339
|
+
return throwError(() => new Error('No permission to update the elapsed time record'));
|
|
5479
4340
|
}));
|
|
5480
4341
|
}
|
|
5481
|
-
return throwError(() => new Error('
|
|
4342
|
+
return throwError(() => new Error('No permission to read the task'));
|
|
5482
4343
|
}));
|
|
5483
4344
|
}
|
|
5484
|
-
// TODO: разобраться что это за ебатня в комментах и вписать нормальной комент если она нужна
|
|
5485
4345
|
/**
|
|
5486
4346
|
* Проверяет право на изменение записи о затраченном времени.
|
|
5487
4347
|
*/
|
|
5488
4348
|
isAllowedModify(idTask, idItem) {
|
|
5489
|
-
// let permission = Permission.get()
|
|
5490
|
-
// if (permission?.tasks?.length) {
|
|
5491
|
-
// let findTask = permission.tasks.find(i => i.id === idTask)
|
|
5492
|
-
// if (findTask) {
|
|
5493
|
-
// let find = findTask.elapsedItem.find(i => i.id === idItem)
|
|
5494
|
-
// if (find && find.verified.edit) {
|
|
5495
|
-
// return of(find.edit)
|
|
5496
|
-
// }
|
|
5497
|
-
// }
|
|
5498
|
-
// }
|
|
5499
4349
|
return this.BXRestNavvyElapsedItem.isActionAllowed({
|
|
5500
4350
|
TASKID: idTask,
|
|
5501
4351
|
ITEMID: idItem,
|
|
5502
4352
|
ACTIONID: 2
|
|
5503
4353
|
}).res();
|
|
5504
|
-
// .pipe(
|
|
5505
|
-
// tap(v => {
|
|
5506
|
-
// if (v !== undefined) {
|
|
5507
|
-
// Permission.setTaskElapsedItem(idTask,
|
|
5508
|
-
// {
|
|
5509
|
-
// id: idItem,
|
|
5510
|
-
// edit: v,
|
|
5511
|
-
// del: false,
|
|
5512
|
-
// verified: {
|
|
5513
|
-
// edit: true,
|
|
5514
|
-
// del: false,
|
|
5515
|
-
// }
|
|
5516
|
-
// })
|
|
5517
|
-
// }
|
|
5518
|
-
// })
|
|
5519
|
-
// )
|
|
5520
4354
|
}
|
|
5521
4355
|
/**
|
|
5522
4356
|
* isActionAllowed с фиксом на проверку возможности чтения задачи записи
|
|
@@ -5533,7 +4367,7 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5533
4367
|
if (canRead) {
|
|
5534
4368
|
return this.BXRestNavvyElapsedItem.isActionAllowed(param).res();
|
|
5535
4369
|
}
|
|
5536
|
-
return throwError(() => new Error('
|
|
4370
|
+
return throwError(() => new Error('No permission to read the task'));
|
|
5537
4371
|
}));
|
|
5538
4372
|
}
|
|
5539
4373
|
/**
|
|
@@ -5549,12 +4383,12 @@ class BXRestNavvyOperationElapsedItem {
|
|
|
5549
4383
|
return this.BXRestNavvyElapsedItem.delete(param).res();
|
|
5550
4384
|
}
|
|
5551
4385
|
else {
|
|
5552
|
-
return throwError(() => new Error('
|
|
4386
|
+
return throwError(() => new Error('No permission to delete the elapsed time record'));
|
|
5553
4387
|
}
|
|
5554
4388
|
}));
|
|
5555
4389
|
}
|
|
5556
4390
|
else {
|
|
5557
|
-
return throwError(() => new Error('
|
|
4391
|
+
return throwError(() => new Error('No permission to read the task'));
|
|
5558
4392
|
}
|
|
5559
4393
|
}));
|
|
5560
4394
|
}
|
|
@@ -6567,7 +5401,7 @@ class BXRestNavvyDiskOperation {
|
|
|
6567
5401
|
generateUniqueName: true
|
|
6568
5402
|
}).res();
|
|
6569
5403
|
}
|
|
6570
|
-
return throwError(() => new Error('
|
|
5404
|
+
return throwError(() => new Error('Could not get the app storage'));
|
|
6571
5405
|
}));
|
|
6572
5406
|
}
|
|
6573
5407
|
/**
|
|
@@ -6585,13 +5419,6 @@ class BXRestNavvyDiskOperation {
|
|
|
6585
5419
|
* Возвращает список папок и файлов в общем хранилище приложения.
|
|
6586
5420
|
*/
|
|
6587
5421
|
getRootFoldersApp() {
|
|
6588
|
-
// return this.BXDiskFolder$.pipe(
|
|
6589
|
-
// take(1),
|
|
6590
|
-
// mergeMap(
|
|
6591
|
-
// saveData => {
|
|
6592
|
-
// if (saveData.content.root.app) {
|
|
6593
|
-
// return of(saveData.content.root.app)
|
|
6594
|
-
// }
|
|
6595
5422
|
return this.storage.getForApp().res().pipe(mergeMap$1(v => {
|
|
6596
5423
|
if (v && v.ID) {
|
|
6597
5424
|
return this.storage.getChildren({ id: v.ID }).res();
|
|
@@ -6617,7 +5444,7 @@ class BXRestNavvyDiskOperation {
|
|
|
6617
5444
|
if (v && v.ID) {
|
|
6618
5445
|
return this.storage.addFolder({ id: v.ID, data: { NAME: folderName } }).res();
|
|
6619
5446
|
}
|
|
6620
|
-
return throwError(() => new Error('
|
|
5447
|
+
return throwError(() => new Error('Could not get the app storage'));
|
|
6621
5448
|
}));
|
|
6622
5449
|
}));
|
|
6623
5450
|
}
|
|
@@ -6988,6 +5815,32 @@ class BXRestNavvyBizProcRobot {
|
|
|
6988
5815
|
}
|
|
6989
5816
|
}
|
|
6990
5817
|
|
|
5818
|
+
/**
|
|
5819
|
+
* Символьный код нового элемента списка: `bx_rest_` и 128 случайных бит в hex.
|
|
5820
|
+
* Только латиница, цифры и `_`: допустимые символы документация Bitrix24 не
|
|
5821
|
+
* описывает.
|
|
5822
|
+
*
|
|
5823
|
+
* Случайные байты дают `crypto.getRandomValues` (в отличие от
|
|
5824
|
+
* `crypto.randomUUID`, он есть и на страницах по http). Глобального `crypto`
|
|
5825
|
+
* нет только в Node 18: там байты берутся из `Math.random`. Это не
|
|
5826
|
+
* криптостойко, но код нужен лишь уникальный, а совпадение с уже занятым кодом
|
|
5827
|
+
* ловит повтор в вызывающем методе.
|
|
5828
|
+
*/
|
|
5829
|
+
function uniqueElementCode() {
|
|
5830
|
+
const bytes = new Uint8Array(16);
|
|
5831
|
+
if (typeof globalThis.crypto?.getRandomValues === 'function') {
|
|
5832
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
5833
|
+
}
|
|
5834
|
+
else {
|
|
5835
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
5836
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
5837
|
+
}
|
|
5838
|
+
}
|
|
5839
|
+
return 'bx_rest_' + Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
|
|
5840
|
+
}
|
|
5841
|
+
|
|
5842
|
+
/** Сколько раз пробуем новый `ELEMENT_CODE`, если такой код в списке уже занят. */
|
|
5843
|
+
const ELEMENT_CODE_ATTEMPTS = 3;
|
|
6991
5844
|
/** Бизнес-процессы, задания, действия и роботы (`bizproc.*`). */
|
|
6992
5845
|
class BXRestNavvyBizProc {
|
|
6993
5846
|
constructor() {
|
|
@@ -7017,21 +5870,26 @@ class BXRestNavvyBizProc {
|
|
|
7017
5870
|
// Не понимаю почему DATE_CREATE указывается не на сервере
|
|
7018
5871
|
// но если пользователь не указал, надо указать
|
|
7019
5872
|
const value = parametersElement['DATE_CREATE'];
|
|
7020
|
-
if (value === null || value === undefined || (typeof value === 'string'
|
|
5873
|
+
if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
|
|
7021
5874
|
parametersElement['DATE_CREATE'] = new Date();
|
|
7022
5875
|
}
|
|
7023
|
-
|
|
5876
|
+
// ELEMENT_CODE обязателен и должен быть уникальным в списке. Занятые коды
|
|
5877
|
+
// знает только портал, поэтому на совпадение создаём новый код и повторяем.
|
|
5878
|
+
// throwOnApiError: иначе ошибка в ответе 2xx пришла бы как undefined.
|
|
5879
|
+
const addElement = (attempt) => this.BXRestNavvyLists.element.add({
|
|
7024
5880
|
IBLOCK_TYPE_ID: 'bitrix_processes',
|
|
7025
5881
|
IBLOCK_ID: id,
|
|
7026
|
-
ELEMENT_CODE:
|
|
7027
|
-
// тут должно быть уникально значение (генерация уникальных значений на фронте лол),
|
|
7028
|
-
// как ещё уникальнее сделать я просто не знаю
|
|
7029
|
-
// это поле обязательно без него не работает
|
|
5882
|
+
ELEMENT_CODE: uniqueElementCode(),
|
|
7030
5883
|
FIELDS: {
|
|
7031
5884
|
NAME: String(parametersElement['NAME']),
|
|
7032
5885
|
...parametersElement
|
|
7033
5886
|
}
|
|
7034
|
-
}).res().pipe(
|
|
5887
|
+
}).res({ throwOnApiError: true }).pipe(catchError$1((error) => (attempt < ELEMENT_CODE_ATTEMPTS
|
|
5888
|
+
&& error instanceof BXRestApiError
|
|
5889
|
+
&& error.error === 'ERROR_ELEMENT_ALREADY_EXISTS')
|
|
5890
|
+
? addElement(attempt + 1)
|
|
5891
|
+
: throwError(() => error)));
|
|
5892
|
+
return addElement(1).pipe(mergeMap(v => {
|
|
7035
5893
|
if (v) {
|
|
7036
5894
|
if (Object.keys(parametersBizProc).length && templateIDs.length) {
|
|
7037
5895
|
let request = [];
|
|
@@ -7048,7 +5906,7 @@ class BXRestNavvyBizProc {
|
|
|
7048
5906
|
return of(true);
|
|
7049
5907
|
}
|
|
7050
5908
|
}
|
|
7051
|
-
return throwError(() => new Error('
|
|
5909
|
+
return throwError(() => new Error('Could not start the business process: the list element was not created'));
|
|
7052
5910
|
}));
|
|
7053
5911
|
}
|
|
7054
5912
|
}
|
|
@@ -7318,14 +6176,6 @@ class BXRestNavvyRestCalendarEvent {
|
|
|
7318
6176
|
update: [$calendar, $event, $update],
|
|
7319
6177
|
};
|
|
7320
6178
|
this.Navvy = new Navvy();
|
|
7321
|
-
// /** Возвращает список событий календаря, всегда весь список, паганации в методе нет да и не нужна */
|
|
7322
|
-
// get(param: iBXRestCalendarEventGetParam) {
|
|
7323
|
-
// return this.Navvy.simple(
|
|
7324
|
-
// this.url.get,
|
|
7325
|
-
// param,
|
|
7326
|
-
// BXRestMapCalendarEvent.get
|
|
7327
|
-
// )
|
|
7328
|
-
// }
|
|
7329
6179
|
this.get = Object.assign(
|
|
7330
6180
|
/**
|
|
7331
6181
|
* Возвращает список событий календаря, всегда весь список, паганации в методе нет да и не нужна.
|
|
@@ -8414,40 +7264,6 @@ class BXRestNavvyImNotify {
|
|
|
8414
7264
|
}
|
|
8415
7265
|
}
|
|
8416
7266
|
|
|
8417
|
-
function CatchError(options) {
|
|
8418
|
-
return function (target, propertyKey, descriptor) {
|
|
8419
|
-
const original = descriptor.value;
|
|
8420
|
-
descriptor.value = function (...args) {
|
|
8421
|
-
try {
|
|
8422
|
-
return original.apply(this, args);
|
|
8423
|
-
}
|
|
8424
|
-
catch (err) {
|
|
8425
|
-
const errorInfo = {
|
|
8426
|
-
message: `❌ Error in ${target.constructor.name}.${propertyKey}`,
|
|
8427
|
-
args,
|
|
8428
|
-
error: err instanceof Error ? err.message : String(err),
|
|
8429
|
-
stack: err instanceof Error ? err.stack : new Error().stack,
|
|
8430
|
-
};
|
|
8431
|
-
console.error(formatError(errorInfo));
|
|
8432
|
-
if (options?.rethrow)
|
|
8433
|
-
throw err;
|
|
8434
|
-
return options?.defaultValue;
|
|
8435
|
-
}
|
|
8436
|
-
};
|
|
8437
|
-
return descriptor;
|
|
8438
|
-
};
|
|
8439
|
-
}
|
|
8440
|
-
// Общая функция форматирования
|
|
8441
|
-
function formatError(info) {
|
|
8442
|
-
const stackLines = info.stack?.split('\n').slice(2).join('\n');
|
|
8443
|
-
return [
|
|
8444
|
-
info.message,
|
|
8445
|
-
info.args ? ` • args: ${JSON.stringify(info.args)}` : '',
|
|
8446
|
-
info.error ? ` • error: ${info.error}` : '',
|
|
8447
|
-
` • stack trace:\n${stackLines}`,
|
|
8448
|
-
].join('\n');
|
|
8449
|
-
}
|
|
8450
|
-
|
|
8451
7267
|
class BXRestMapImRecent {
|
|
8452
7268
|
static get(value) {
|
|
8453
7269
|
return value
|
|
@@ -8518,12 +7334,6 @@ class BXRestMapImRecent {
|
|
|
8518
7334
|
return chat;
|
|
8519
7335
|
}
|
|
8520
7336
|
}
|
|
8521
|
-
__decorate([
|
|
8522
|
-
CatchError({ rethrow: true })
|
|
8523
|
-
], BXRestMapImRecent, "get", null);
|
|
8524
|
-
__decorate([
|
|
8525
|
-
CatchError({ rethrow: true })
|
|
8526
|
-
], BXRestMapImRecent, "list", null);
|
|
8527
7337
|
|
|
8528
7338
|
class BXRestNavvyImRecent {
|
|
8529
7339
|
constructor() {
|
|
@@ -9263,12 +8073,8 @@ class BXRestNavvySocialNetWorkApiLiveFeedBlogPost {
|
|
|
9263
8073
|
}
|
|
9264
8074
|
}
|
|
9265
8075
|
|
|
9266
|
-
// import { Navvy } from '../../../services/navvy'
|
|
9267
|
-
// import { BXRestSocialNetWorkApiLiveFeed } from '../../../request/socialnetwork/api/livefeed'
|
|
9268
8076
|
class BXRestNavvySocialNetWorkApiLiveFeed {
|
|
9269
8077
|
constructor() {
|
|
9270
|
-
// private readonly contentView = new BXRestSocialNetWorkApiLiveFeed)
|
|
9271
|
-
// private readonly Navvy = new Navvy(this.contentView, null)
|
|
9272
8078
|
/**
|
|
9273
8079
|
* Сообщения Ленты новостей в социальной сети (`socialnetwork.api.liveFeed.blogPost.*`).
|
|
9274
8080
|
*/
|
|
@@ -9362,17 +8168,6 @@ class BXRestMapPull {
|
|
|
9362
8168
|
}
|
|
9363
8169
|
}
|
|
9364
8170
|
|
|
9365
|
-
class BXRestMapPullChannelPublic {
|
|
9366
|
-
static get(value) {
|
|
9367
|
-
return value ? {
|
|
9368
|
-
...value,
|
|
9369
|
-
start: toDate(value.start),
|
|
9370
|
-
end: toDate(value.end)
|
|
9371
|
-
}
|
|
9372
|
-
: undefined;
|
|
9373
|
-
}
|
|
9374
|
-
}
|
|
9375
|
-
|
|
9376
8171
|
class BXRestNavvyPullConfig {
|
|
9377
8172
|
constructor() {
|
|
9378
8173
|
this.url = {
|
|
@@ -9383,7 +8178,6 @@ class BXRestNavvyPullConfig {
|
|
|
9383
8178
|
};
|
|
9384
8179
|
this.Navvy = new Navvy();
|
|
9385
8180
|
}
|
|
9386
|
-
static { this.public = new BXRestMapPullChannelPublic(); }
|
|
9387
8181
|
/**
|
|
9388
8182
|
* @experimental
|
|
9389
8183
|
* Этот метод находится в процессе тестирования и может измениться.
|
|
@@ -9393,6 +8187,17 @@ class BXRestNavvyPullConfig {
|
|
|
9393
8187
|
}
|
|
9394
8188
|
}
|
|
9395
8189
|
|
|
8190
|
+
class BXRestMapPullChannelPublic {
|
|
8191
|
+
static get(value) {
|
|
8192
|
+
return value ? {
|
|
8193
|
+
...value,
|
|
8194
|
+
start: toDate(value.start),
|
|
8195
|
+
end: toDate(value.end)
|
|
8196
|
+
}
|
|
8197
|
+
: undefined;
|
|
8198
|
+
}
|
|
8199
|
+
}
|
|
8200
|
+
|
|
9396
8201
|
class BXRestNavvyPullChannelPublic {
|
|
9397
8202
|
constructor() {
|
|
9398
8203
|
this.url = {
|
|
@@ -20203,69 +19008,70 @@ class BXRestNavvyUserFieldType {
|
|
|
20203
19008
|
}
|
|
20204
19009
|
|
|
20205
19010
|
class BXRestNavvy {
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
|
|
20217
|
-
|
|
20218
|
-
|
|
20219
|
-
|
|
20220
|
-
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
20224
|
-
|
|
20225
|
-
|
|
20226
|
-
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
|
|
20241
|
-
|
|
20242
|
-
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
|
|
20246
|
-
|
|
20247
|
-
|
|
20248
|
-
|
|
20249
|
-
|
|
20250
|
-
|
|
20251
|
-
|
|
20252
|
-
|
|
20253
|
-
|
|
20254
|
-
|
|
20255
|
-
|
|
20256
|
-
|
|
20257
|
-
|
|
20258
|
-
|
|
20259
|
-
|
|
20260
|
-
|
|
20261
|
-
|
|
20262
|
-
|
|
20263
|
-
|
|
20264
|
-
|
|
20265
|
-
|
|
20266
|
-
|
|
20267
|
-
|
|
20268
|
-
|
|
19011
|
+
/**
|
|
19012
|
+
* @param settings Свои настройки клиента: адрес портала, способ авторизации,
|
|
19013
|
+
* заголовки. Все запросы этого клиента идут с ними, даже если глобальные
|
|
19014
|
+
* `BXRestSettings` позже изменятся. Так в одном процессе можно работать
|
|
19015
|
+
* с несколькими порталами. Без аргумента клиент работает с глобальными
|
|
19016
|
+
* `BXRestSettings`, как раньше.
|
|
19017
|
+
*/
|
|
19018
|
+
constructor(settings) {
|
|
19019
|
+
// Каждый HTTP-объект запоминает контекст в момент создания, поэтому все
|
|
19020
|
+
// разделы создаются, пока включён контекст клиента. Создание идёт в теле
|
|
19021
|
+
// конструктора, а не в инициализаторах полей: только так finally вернёт
|
|
19022
|
+
// прежний контекст, даже если какой-то раздел бросит исключение. Иначе
|
|
19023
|
+
// объекты, созданные приложением позже, ушли бы на портал этого клиента.
|
|
19024
|
+
const previous = enterContext(settings ? new BXRestContext(settings) : globalContext);
|
|
19025
|
+
try {
|
|
19026
|
+
this.ai = new BXRestNavvyAi();
|
|
19027
|
+
this.mailService = new BXRestNavvyMailService();
|
|
19028
|
+
this.messageService = new BXRestNavvyMessageService();
|
|
19029
|
+
this.userConsent = new BXRestNavvyUserConsent();
|
|
19030
|
+
this.telephony = new BXRestNavvyTelephony();
|
|
19031
|
+
this.vote = new BXRestNavvyVote();
|
|
19032
|
+
this.imConnector = new BXRestNavvyImConnector();
|
|
19033
|
+
this.entity = new BXRestNavvyEntity();
|
|
19034
|
+
this.biConnector = new BXRestNavvyBiConnector();
|
|
19035
|
+
this.voxImplant = new BXRestNavvyVoxImplant();
|
|
19036
|
+
this.mail = new BXRestNavvyMail();
|
|
19037
|
+
this.note = new BXRestNavvyNote();
|
|
19038
|
+
this.documentGenerator = new BXRestNavvyDocumentGenerator();
|
|
19039
|
+
this.imBot = new BXRestNavvyImBot();
|
|
19040
|
+
this.booking = new BXRestNavvyBooking();
|
|
19041
|
+
this.imOpenLines = new BXRestNavvyImOpenLines();
|
|
19042
|
+
this.landing = new BXRestNavvyLanding();
|
|
19043
|
+
this.catalog = new BXRestNavvyCatalog();
|
|
19044
|
+
this.sale = new BXRestNavvySale();
|
|
19045
|
+
this.sign = new BXRestNavvySign();
|
|
19046
|
+
this.eventLog = new BXRestNavvyEventLog();
|
|
19047
|
+
this.placement = new BXRestNavvyPlacement();
|
|
19048
|
+
this.userFieldType = new BXRestNavvyUserFieldType();
|
|
19049
|
+
this.user = new BXRestNavvyUser();
|
|
19050
|
+
this.lists = new BXRestNavvyLists();
|
|
19051
|
+
this.task = new BXRestNavvyTask();
|
|
19052
|
+
this.tasks = new BXRestNavvyTasks();
|
|
19053
|
+
this.disk = new BXRestNavvyDisk();
|
|
19054
|
+
this.bizProc = new BXRestNavvyBizProc();
|
|
19055
|
+
this.log = new BXRestNavvyLog();
|
|
19056
|
+
this.calendar = new BXRestNavvyCalendar();
|
|
19057
|
+
this.sonet_group = new BXRestNavvySonetGroup();
|
|
19058
|
+
this.server = new BXRestNavvyServer();
|
|
19059
|
+
this.department = new BXRestNavvyDepartment();
|
|
19060
|
+
this.im = new BXRestNavvyIm();
|
|
19061
|
+
this.app = new BXRestNavvyApp();
|
|
19062
|
+
this.timeMan = new BXRestNavvyTimeMan();
|
|
19063
|
+
this.socialNetWork = new BXRestNavvySocialNetWork();
|
|
19064
|
+
this.pull = new BXRestNavvyPull();
|
|
19065
|
+
this.crm = new BXRestNavvyCrm();
|
|
19066
|
+
this.event = new BXRestNavvyEvent();
|
|
19067
|
+
this.method = new BXRestNavvyMethod();
|
|
19068
|
+
this.access = new BXRestNavvyAccess();
|
|
19069
|
+
this.feature = new BXRestNavvyFeature();
|
|
19070
|
+
this.Navvy = new Navvy();
|
|
19071
|
+
}
|
|
19072
|
+
finally {
|
|
19073
|
+
restoreContext(previous);
|
|
19074
|
+
}
|
|
20269
19075
|
}
|
|
20270
19076
|
/**
|
|
20271
19077
|
* Возвращает базовую информацию о текущем пользователе без scope `user`.
|
|
@@ -20291,6 +19097,15 @@ class BXRestNavvy {
|
|
|
20291
19097
|
}
|
|
20292
19098
|
}
|
|
20293
19099
|
|
|
19100
|
+
class BXRestMapDisk {
|
|
19101
|
+
constructor() {
|
|
19102
|
+
this.folder = new BXRestMapDiskFolder();
|
|
19103
|
+
this.attachedObject = new BXRestMapDiskAttachedObject();
|
|
19104
|
+
this.file = new BXRestMapDiskFile();
|
|
19105
|
+
this.storage = new BXRestMapDiskStorage();
|
|
19106
|
+
}
|
|
19107
|
+
}
|
|
19108
|
+
|
|
20294
19109
|
class BXRestMapCalendarUser {
|
|
20295
19110
|
constructor() {
|
|
20296
19111
|
this.settings = new BXRestMapCalendarUserSettings();
|
|
@@ -20322,16 +19137,23 @@ class BXRestMapTaskStage {
|
|
|
20322
19137
|
}
|
|
20323
19138
|
|
|
20324
19139
|
class BXRestMapTask {
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
19140
|
+
// Геттеры, а не статические поля: статический инициализатор выполняется при загрузке
|
|
19141
|
+
// модуля, поэтому бандлер не сможет выбросить класс, даже если он нигде не используется.
|
|
19142
|
+
static get commentItem() {
|
|
19143
|
+
return BXRestMapTaskCommentItem;
|
|
19144
|
+
}
|
|
19145
|
+
static get elapsedItem() {
|
|
19146
|
+
return BXRestMapTaskElapsedItem;
|
|
19147
|
+
}
|
|
19148
|
+
static get stages() {
|
|
19149
|
+
return BXRestMapTaskStage;
|
|
20329
19150
|
}
|
|
20330
19151
|
}
|
|
20331
19152
|
|
|
20332
19153
|
class BXRestMapTasks {
|
|
20333
|
-
|
|
20334
|
-
|
|
19154
|
+
// Геттер — по той же причине, что и в BXRestMapTask
|
|
19155
|
+
static get task() {
|
|
19156
|
+
return BXRestMapTasksTask;
|
|
20335
19157
|
}
|
|
20336
19158
|
}
|
|
20337
19159
|
|
|
@@ -20349,7 +19171,7 @@ class BXRestMap {
|
|
|
20349
19171
|
return BXRestMapLists;
|
|
20350
19172
|
}
|
|
20351
19173
|
get disk() {
|
|
20352
|
-
return
|
|
19174
|
+
return BXRestMapDisk;
|
|
20353
19175
|
}
|
|
20354
19176
|
get calendar() {
|
|
20355
19177
|
return BXRestMapCalendar;
|
|
@@ -20943,5 +19765,5 @@ function toRecord(value) {
|
|
|
20943
19765
|
* Generated bundle index. Do not edit.
|
|
20944
19766
|
*/
|
|
20945
19767
|
|
|
20946
|
-
export { base as BXBaseServices, BXRestApiError, BXRestFrame, BXRestFrameError, BXRestMap, BXRestMapResult, BXRestNavvy, HttpBXServices as BXRestRequest, BXRestSettings,
|
|
19768
|
+
export { base as BXBaseServices, BXRestApiError, BXRestFrame, BXRestFrameError, BXRestMap, BXRestMapResult, BXRestNavvy, HttpBXServices as BXRestRequest, BXRestSettings, BXRestTimeoutError, Navvy, SessionKeyError, SessionKeyServices, getAuthRefreshError, instanceOfiBXRestAnswerSuccess as isBXRestAnswerSuccess, isBXRestAuthError, partNameMethods$1 as partNameMethods };
|
|
20947
19769
|
//# sourceMappingURL=bx-rest.mjs.map
|