bx-rest 1.5.1 → 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.
Files changed (148) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.en.md +113 -2
  3. package/README.md +114 -2
  4. package/esm2022/functions/errors.mjs +17 -5
  5. package/esm2022/functions/uniqueElementCode.mjs +24 -0
  6. package/esm2022/public-api.mjs +2 -2
  7. package/esm2022/request-navvy/bizproc.mjs +18 -9
  8. package/esm2022/request-navvy/calendar/event.mjs +1 -9
  9. package/esm2022/request-navvy/disk/operation.mjs +3 -10
  10. package/esm2022/request-navvy/socialnetwork/api/livefeed.mjs +1 -5
  11. package/esm2022/request-navvy/task/operation/elapseditem.mjs +8 -8
  12. package/esm2022/request-navvy/tasks/task.mjs +1 -119
  13. package/esm2022/rest/navvy.mjs +66 -64
  14. package/esm2022/services/base.mjs +1 -4
  15. package/esm2022/services/context.mjs +59 -0
  16. package/esm2022/services/http/HttpBX.mjs +49 -19
  17. package/esm2022/services/http/authRefresh.mjs +25 -23
  18. package/esm2022/services/http/http.mjs +14 -69
  19. package/esm2022/services/http/middleware.mjs +149 -0
  20. package/esm2022/services/http/sessionKey.mjs +16 -5
  21. package/esm2022/services/http/transport.mjs +5 -0
  22. package/esm2022/services/navvy/navvy-support.mjs +2 -15
  23. package/esm2022/services/navvy.mjs +18 -31
  24. package/esm2022/typification/rest/calendar/event/get.mjs +1 -1
  25. package/esm2022/typification/rest/tasks/task/get.mjs +1 -1
  26. package/esm2022/typification/settings.mjs +1 -1
  27. package/fesm2022/bx-rest.mjs +450 -463
  28. package/fesm2022/bx-rest.mjs.map +1 -1
  29. package/functions/errors.d.ts +9 -0
  30. package/functions/uniqueElementCode.d.ts +12 -0
  31. package/package.json +1 -1
  32. package/public-api.d.ts +2 -1
  33. package/rest/navvy.d.ts +9 -0
  34. package/services/context.d.ts +43 -0
  35. package/services/http/HttpBX.d.ts +10 -0
  36. package/services/http/authRefresh.d.ts +5 -1
  37. package/services/http/http.d.ts +12 -9
  38. package/services/http/middleware.d.ts +31 -0
  39. package/services/http/sessionKey.d.ts +10 -0
  40. package/services/http/transport.d.ts +28 -0
  41. package/services/navvy/navvy-support.d.ts +0 -10
  42. package/services/navvy.d.ts +1 -0
  43. package/typification/rest/calendar/event/get.d.ts +1 -1
  44. package/typification/settings.d.ts +34 -0
  45. package/esm2022/functions/errorHandler.mjs +0 -34
  46. package/esm2022/request/app.mjs +0 -13
  47. package/esm2022/request/bizproc/activity.mjs +0 -3
  48. package/esm2022/request/bizproc/event.mjs +0 -3
  49. package/esm2022/request/bizproc/robot.mjs +0 -3
  50. package/esm2022/request/bizproc/task.mjs +0 -3
  51. package/esm2022/request/bizproc/workflow/instance.mjs +0 -3
  52. package/esm2022/request/bizproc/workflow/template.mjs +0 -3
  53. package/esm2022/request/bizproc/workflow.mjs +0 -18
  54. package/esm2022/request/bizproc.mjs +0 -15
  55. package/esm2022/request/department.mjs +0 -26
  56. package/esm2022/request/disk/attachedObject.mjs +0 -14
  57. package/esm2022/request/disk/file.mjs +0 -18
  58. package/esm2022/request/disk/folder.mjs +0 -117
  59. package/esm2022/request/disk.mjs +0 -11
  60. package/esm2022/request/lists/element.mjs +0 -18
  61. package/esm2022/request/lists/field.mjs +0 -35
  62. package/esm2022/request/lists.mjs +0 -86
  63. package/esm2022/request/log/blogcomment.mjs +0 -3
  64. package/esm2022/request/log/blogpost.mjs +0 -18
  65. package/esm2022/request/log.mjs +0 -9
  66. package/esm2022/request/pull/application/config.mjs +0 -11
  67. package/esm2022/request/pull/channel/public.mjs +0 -18
  68. package/esm2022/request/pull/config.mjs +0 -13
  69. package/esm2022/request/pull.mjs +0 -11
  70. package/esm2022/request/server.mjs +0 -14
  71. package/esm2022/request/socialnetwork/api/contentview.mjs +0 -14
  72. package/esm2022/request/socialnetwork/api/livefeed/blogpost/important.mjs +0 -14
  73. package/esm2022/request/socialnetwork/api/livefeed/blogpost.mjs +0 -7
  74. package/esm2022/request/socialnetwork/api/livefeed.mjs +0 -7
  75. package/esm2022/request/socialnetwork/api.mjs +0 -9
  76. package/esm2022/request/socialnetwork.mjs +0 -8
  77. package/esm2022/request/sonet_group.mjs +0 -24
  78. package/esm2022/request/task/commentitem.mjs +0 -32
  79. package/esm2022/request/task/elapseditem.mjs +0 -40
  80. package/esm2022/request/task/item/userfield.mjs +0 -14
  81. package/esm2022/request/task/item.mjs +0 -7
  82. package/esm2022/request/task/planner.mjs +0 -11
  83. package/esm2022/request/task.mjs +0 -13
  84. package/esm2022/request/tasks/task/result.mjs +0 -22
  85. package/esm2022/request/tasks/task.mjs +0 -110
  86. package/esm2022/request/tasks.mjs +0 -7
  87. package/esm2022/request/user/userfield.mjs +0 -14
  88. package/esm2022/request/user.mjs +0 -40
  89. package/esm2022/rest/base.mjs +0 -39
  90. package/esm2022/services/http/HttpData.mjs +0 -77
  91. package/esm2022/services/http/base/base.mjs +0 -4
  92. package/esm2022/services/http/httpNavvy.mjs +0 -14
  93. package/esm2022/typification/base/answers.mjs +0 -438
  94. package/esm2022/typification/base/params.mjs +0 -525
  95. package/esm2022/typification/base/workpiece/methods-list.mjs +0 -2
  96. package/esm2022/typification/base/workpiece/methods.mjs +0 -2
  97. package/functions/errorHandler.d.ts +0 -10
  98. package/request/app.d.ts +0 -8
  99. package/request/bizproc/activity.d.ts +0 -2
  100. package/request/bizproc/event.d.ts +0 -2
  101. package/request/bizproc/robot.d.ts +0 -2
  102. package/request/bizproc/task.d.ts +0 -2
  103. package/request/bizproc/workflow/instance.d.ts +0 -2
  104. package/request/bizproc/workflow/template.d.ts +0 -2
  105. package/request/bizproc/workflow.d.ts +0 -13
  106. package/request/bizproc.d.ts +0 -12
  107. package/request/department.d.ts +0 -18
  108. package/request/disk/attachedObject.d.ts +0 -8
  109. package/request/disk/file.d.ts +0 -10
  110. package/request/disk/folder.d.ts +0 -96
  111. package/request/disk.d.ts +0 -8
  112. package/request/lists/element.d.ts +0 -11
  113. package/request/lists/field.d.ts +0 -11
  114. package/request/lists.d.ts +0 -31
  115. package/request/log/blogcomment.d.ts +0 -2
  116. package/request/log/blogpost.d.ts +0 -11
  117. package/request/log.d.ts +0 -6
  118. package/request/pull/application/config.d.ts +0 -5
  119. package/request/pull/channel/public.d.ts +0 -5
  120. package/request/pull/config.d.ts +0 -7
  121. package/request/pull.d.ts +0 -8
  122. package/request/server.d.ts +0 -7
  123. package/request/socialnetwork/api/contentview.d.ts +0 -6
  124. package/request/socialnetwork/api/livefeed/blogpost/important.d.ts +0 -6
  125. package/request/socialnetwork/api/livefeed/blogpost.d.ts +0 -4
  126. package/request/socialnetwork/api/livefeed.d.ts +0 -4
  127. package/request/socialnetwork/api.d.ts +0 -6
  128. package/request/socialnetwork.d.ts +0 -4
  129. package/request/sonet_group.d.ts +0 -8
  130. package/request/task/commentitem.d.ts +0 -23
  131. package/request/task/elapseditem.d.ts +0 -26
  132. package/request/task/item/userfield.d.ts +0 -6
  133. package/request/task/item.d.ts +0 -4
  134. package/request/task/planner.d.ts +0 -4
  135. package/request/task.d.ts +0 -10
  136. package/request/tasks/task/result.d.ts +0 -13
  137. package/request/tasks/task.d.ts +0 -37
  138. package/request/tasks.d.ts +0 -4
  139. package/request/user/userfield.d.ts +0 -8
  140. package/request/user.d.ts +0 -24
  141. package/rest/base.d.ts +0 -33
  142. package/services/http/HttpData.d.ts +0 -7
  143. package/services/http/base/base.d.ts +0 -7
  144. package/services/http/httpNavvy.d.ts +0 -10
  145. package/typification/base/answers.d.ts +0 -12
  146. package/typification/base/params.d.ts +0 -16
  147. package/typification/base/workpiece/methods-list.d.ts +0 -247
  148. package/typification/base/workpiece/methods.d.ts +0 -20
package/CHANGELOG.md CHANGED
@@ -7,6 +7,100 @@
7
7
  История до версии 1.0.0 здесь не восстанавливалась — смотрите `git log` для
8
8
  более ранних изменений.
9
9
 
10
+ ## [1.6.0] - 2026-11-10
11
+
12
+ ### Added
13
+
14
+ - Клиент со своими настройками: `new BXRestNavvy(settings)`. Все запросы
15
+ такого клиента идут на его портал с его токеном, продление авторизации у
16
+ него своё, а `BXRestSettings` на него не влияют. Так в одном процессе можно
17
+ работать с несколькими порталами. `new BXRestNavvy()` без аргумента
18
+ работает с глобальными `BXRestSettings`, как раньше. Подробнее — в разделе
19
+ README «Несколько порталов».
20
+ - Настройки `retryOnQueryLimit`, `timeout` и `throttle` — в `BXRestSettings`
21
+ или у клиента `new BXRestNavvy(settings)`. `retryOnQueryLimit` повторяет
22
+ запрос при `QUERY_LIMIT_EXCEEDED` с растущей паузой, `timeout` отменяет
23
+ запрос, который идёт дольше заданного времени, с ошибкой
24
+ `BXRestTimeoutError`, `throttle` пропускает не больше N запросов в секунду.
25
+ `true` включает значения по умолчанию: 3 попытки с паузой от 1000 мс,
26
+ 60 000 мс и 2 запроса в секунду. Пока настройки не заданы, запросы идут как
27
+ раньше. Подробнее — в разделе README «Повтор, таймаут и очередь запросов».
28
+ - Настройка `middleware` — свои функции, через которые проходит каждый
29
+ запрос: логирование, подмена заголовков, свой транспорт вместо axios. Типы
30
+ `BXRestMiddleware`, `BXRestRequestConfig` и `BXRestSend` экспортируются из
31
+ `bx-rest`. Подробнее — в разделе README «Свои middleware».
32
+
33
+ ### Changed
34
+
35
+ - Отписка до ответа теперь отменяет HTTP-запрос, как у `HttpClient` в
36
+ Angular. Раньше запрос доходил до конца, а ответ отбрасывался. На
37
+ `firstValueFrom` и обычную подписку это не влияет: они отписываются после
38
+ ответа. Отменяются запросы, которые обрывают `switchMap`, `takeUntil`,
39
+ `timeout` из RxJS или явный `unsubscribe()`. Отмена не откатывает то, что
40
+ портал уже успел сделать.
41
+ - Один экземпляр axios на клиента: он создаётся только при первом запросе.
42
+ Создание объекта запроса стало примерно в 100 раз быстрее (10,7 → 0,15 мкс),
43
+ при `new BXRestNavvy()` — вдвое.
44
+ - Ошибки HTTP библиотека узнаёт по полю `response: { status, data }`, а не
45
+ через `axios.isAxiosError`. Для ошибок axios ничего не меняется, а
46
+ `isBXRestAuthError` и `BXRestApiError` теперь работают и с ошибками своего
47
+ транспорта такой же формы.
48
+ - `bizProc.startProcFormNewsFeed()`: если портал вернул ошибку Bitrix при
49
+ создании элемента списка в ответе 2xx, вызов завершается ошибкой
50
+ `BXRestApiError` с кодом и описанием ошибки. Раньше в этом случае приходила
51
+ общая ошибка `Не удалось запустить бизнес процесс`. Ошибки со статусом не 2xx
52
+ и раньше приходили как `BXRestApiError`.
53
+ - Ошибки, которые библиотека создаёт сама, теперь на английском, как и
54
+ остальные её сообщения (`SessionKeyError`, `BXRestTimeoutError`, ошибки
55
+ разбора значений). Это ошибки `bizProc.startProcFormNewsFeed()`,
56
+ `disk.operation.*` и `task.elapsedItem.operation.*`. Код, который
57
+ сравнивает `err.message` с русским текстом, нужно обновить. Ошибки Bitrix
58
+ (`BXRestApiError`) приходят с текстом портала, как и раньше.
59
+
60
+ ### Removed
61
+
62
+ - У `BXRestRequest` удалены публичные члены, которые библиотека не
63
+ использовала: `defSettings`, `getHttpParamsPost()`, `sliceArrayIntoChunks()`
64
+ и `removingMultipleSlashes()`. Они достались от внутреннего базового класса
65
+ и запросы не отправляли. `post()`, `get()`, `httpPost()` и `httpGet()` не
66
+ изменились. Код, который обращался к удалённым членам, перестанет
67
+ компилироваться.
68
+ - Из `bx-rest/services/navvy` удалён абстрактный класс `NavvySupport`:
69
+ библиотека его не использовала. Тип `ReturnTypeNavvy` остался.
70
+ - Из `bx-rest` удалён класс `HttpNavvyServices` вместе с его типами
71
+ `iBXRestParams` и `iBXRestAnswers`. Он отправлял запросы с типами для
72
+ небольшого набора методов, сама библиотека его не использовала, а в README
73
+ он не описан. Вместо него используйте `BXRestNavvy` или
74
+ `BXRestRequest.post()`.
75
+ - Из исходников удалены 63 модуля, недостижимых из точек входа пакета (старый
76
+ слой `request/*`, `rest/base`, `functions/errorHandler`, `isDate`, `isEqual`,
77
+ `isValidDate`, `serializeJavascript`, `services/permission` и другие), и
78
+ закомментированный код. Файлы 52 из них (`.d.ts` и `esm2022/*.mjs`) лежали в
79
+ пакете, но ни основной бандл, ни `exports` их не подключали, поэтому через
80
+ `import` из `bx-rest` и его подпутей они были недоступны. Из пакета удалено
81
+ 104 файла. Затронуть это может только код, который импортировал типы по
82
+ внутреннему пути вроде `bx-rest/request/...` при `moduleResolution: "node"`.
83
+
84
+ ### Fixed
85
+
86
+ - Проверка типов под `moduleResolution: "nodenext"` или `"node16"` с
87
+ `skipLibCheck: false` больше не падает с ошибкой TS1479 в
88
+ `typification/rest/calendar/event/get.d.ts`. Типы `countries-and-timezones`
89
+ теперь подключаются через `resolution-mode: 'import'`: ветка `require` этого
90
+ пакета указывает на несуществующий файл типов. Сами типы не изменились, код
91
+ пакета тоже. В режиме `bundler` (Angular, Vite, webpack) ошибки не было.
92
+ - `bizProc.startProcFormNewsFeed()` создаёт `ELEMENT_CODE` из префикса
93
+ `bx_rest_` и 128 случайных бит (`crypto.getRandomValues`). Раньше код
94
+ собирался из префикса другого приложения `trace_studio_`, времени и
95
+ `Math.random()`. Если портал отвечает, что такой код уже занят
96
+ (`ERROR_ELEMENT_ALREADY_EXISTS`), вызов создаёт новый код и повторяет
97
+ запрос, всего до трёх попыток.
98
+ - `disk.operation.getOfCreateRootFolderApp()` и
99
+ `getOfCreateRootContentFolderApp()`: если не удалось получить хранилище
100
+ приложения, ошибка теперь так и называется — `Could not get the app
101
+ storage`. Раньше в ней был чужой текст про учёт времени: `Отсутствуют права
102
+ добавление записи затраченного времени`.
103
+
10
104
  ## [1.5.1] - 2026-11-05
11
105
 
12
106
  ### Added
package/README.en.md CHANGED
@@ -24,6 +24,9 @@ Also known as: Bitrix24 REST client, BX24 REST SDK, Bitrix24 API client, Bitrix
24
24
  - [A token from the portal without BX24.js](#a-token-from-the-portal-without-bx24js)
25
25
  - [Recipe: straight to the portal](#recipe-straight-to-the-portal)
26
26
  - [Recipe: through a backend proxy](#recipe-through-a-backend-proxy)
27
+ - [Several portals](#several-portals)
28
+ - [Retry, timeout and request queue](#retry-timeout-and-request-queue)
29
+ - [Your own middleware](#your-own-middleware)
27
30
  - [Working in an iframe without BX24.js](#working-in-an-iframe-without-bx24js)
28
31
  - [Usage in Angular](#usage-in-angular)
29
32
  - [SessionKeyServices](#sessionkeyservices)
@@ -93,7 +96,7 @@ Do not hardcode or commit a production access token. Pass it from your applicati
93
96
 
94
97
  ### Result modes
95
98
 
96
- REST calls are lazy: the request starts when the returned `Observable` is subscribed to or passed to `firstValueFrom`.
99
+ REST calls are lazy: the request starts when the returned `Observable` is subscribed to or passed to `firstValueFrom`. Unsubscribing before the response aborts the HTTP request — this is what `switchMap`, `takeUntil` and the RxJS `timeout` operator rely on. Aborting does not undo what the portal has already done: if `crm.deal.add` reached the server, the deal may be created.
97
100
 
98
101
  | Method | Result |
99
102
  | --- | --- |
@@ -196,7 +199,9 @@ For cross-origin requests, the server — the portal or your proxy — must allo
196
199
  | --- | --- |
197
200
  | Bitrix API error with a non-2xx HTTP status — this is how Bitrix sends most errors: `expired_token` (401), `ERROR_METHOD_NOT_FOUND` (404), `QUERY_LIMIT_EXCEEDED` (503), `Not found` from `crm.*.get` (400) | The returned `Observable` errors with a `BXRestApiError`, with or without `throwOnApiError`. |
198
201
  | Bitrix API error in the body of a 2xx response | By default, `.res()` resolves normally with `undefined` — **it does not throw**. Pass `{ throwOnApiError: true }` to make it throw a `BXRestApiError` instead. |
199
- | Transport / configuration errors — network failure, missing auth, missing base URL, a response that is not from Bitrix (e.g. a proxy's HTML error page) | The returned `Observable` errors with a plain `Error`. The original error is in its `cause`: for a response that is not from Bitrix it is the axios error, with the HTTP status in `cause.response.status`. |
202
+ | Transport / configuration errors — network failure, [`timeout`](#retry-timeout-and-request-queue) exceeded, missing auth, an empty base address (see below), a response that is not from Bitrix (e.g. a proxy's HTML error page) | The returned `Observable` errors with a plain `Error`. The original error is in its `cause`: for a response that is not from Bitrix it is the axios error, with the HTTP status in `cause.response.status`; for `timeout` it is `BXRestTimeoutError`. |
203
+
204
+ **Base address.** The request address is built from two parts: the portal address and `urls.additional_part`. The portal address is `urls.key`, or, with `urls.source: 'localStorage'`, the value stored in `localStorage` under the `urls.key` key. The `Base URL was not resolved` error happens only when both parts are empty. If only the portal address is empty and `additional_part` is `'rest'` (as in the default settings), the request goes to `rest/<method>` relative to the current page. This is meant for pages opened on the portal's own domain. But a request also goes there when nothing was found in `localStorage` under the key, so check the value beforehand.
200
205
 
201
206
  `BXRestApiError` fields:
202
207
 
@@ -210,6 +215,8 @@ For cross-origin requests, the server — the portal or your proxy — must allo
210
215
 
211
216
  For REST v3 methods, `error` holds the error `code` and `error_description` its `message`.
212
217
 
218
+ **The token in errors.** An axios error keeps the whole request that was sent: `config.url` holds the address, and with it the webhook secret, and `config.data` holds the body with the token. The library passes this error on as is — in `err.cause` for `.res()` and as the error itself for `.resVanilla()`. So `console.error(err)` or sending the error to an error tracker passes the token along too. If errors go to logs, pick the fields you need, for example `err.status`, `err.error` and `err.cause?.response?.data`.
219
+
213
220
  **Recommended — `.res({ throwOnApiError: true })`.** Every Bitrix error then arrives as a `BXRestApiError` whatever the HTTP status, and can be handled alongside transport errors in a single `catchError`/`error` callback:
214
221
 
215
222
  ```typescript
@@ -404,6 +411,104 @@ BXRestSettings.update({
404
411
 
405
412
  Errors of the refresh function end up in `authRefreshError` of the original error, and your app may print that error to the console or send it to an error tracker — so keep tokens out of the error messages of the refresh function.
406
413
 
414
+ ## Several portals
415
+
416
+ `BXRestSettings` are shared by the whole app. To work with several portals in one process, for example on a server that serves different customers, pass the settings to the `BXRestNavvy` constructor. Such a client has its own settings: all its requests go to its portal with its token, and `BXRestSettings` do not affect it.
417
+
418
+ ```typescript
419
+ import { BXRestNavvy } from 'bx-rest'
420
+ import { firstValueFrom } from 'rxjs'
421
+
422
+ const portalA = new BXRestNavvy({
423
+ auth: { source: () => tokenA, key: 'auth' },
424
+ urls: { source: 'string', key: 'https://a.bitrix24.com', additional_part: 'rest' }
425
+ })
426
+ const portalB = new BXRestNavvy({
427
+ auth: { source: () => tokenB, key: 'auth' },
428
+ urls: { source: 'string', key: 'https://b.bitrix24.com', additional_part: 'rest' }
429
+ })
430
+
431
+ const deals = await firstValueFrom(
432
+ portalA.crm.deal.list({ select: ['ID'], filter: {}, start: 0 }).resAll()
433
+ )
434
+ ```
435
+
436
+ - **Without an argument** `new BXRestNavvy()` uses the global `BXRestSettings`, as before.
437
+ - **The format** is the same as for `BXRestSettings.update()`, but the settings are passed in full: `auth` and `urls` are required and are not merged with the global settings.
438
+ - **Changing the token of an existing client.** The library calls `auth.source` before every request, at subscribe time. To change the token, change the value the function returns. Requests created earlier but not started yet get the new token too:
439
+
440
+ ```typescript
441
+ let token = await getToken()
442
+ const portal = new BXRestNavvy({
443
+ auth: {
444
+ source: () => token,
445
+ key: 'auth',
446
+ refresh: async () => { token = await getNewToken() } // optional
447
+ },
448
+ urls: { source: 'string', key: 'https://a.bitrix24.com', additional_part: 'rest' }
449
+ })
450
+
451
+ token = newToken // the next request goes out with the new token
452
+ ```
453
+
454
+ - **Another portal or other headers** — create a new client, it takes a fraction of a millisecond.
455
+ - **Authorization refresh** is per client: a client's `auth.refresh` is called only for its own requests.
456
+ - **`auth.source: 'cookies'` and `'localStorage'`** read the shared browser storage, so two clients with the same key get the same token. For several portals, set `source` to a function.
457
+ - **Objects created directly** — `new Navvy()`, `new BXRestRequest()`, `new SessionKeyServices()` — use the global `BXRestSettings`. Only `BXRestNavvy` and everything created through it get the client's own settings.
458
+
459
+ ## Retry, timeout and request queue
460
+
461
+ Three optional settings protect against the Bitrix24 request rate limit and against hanging requests. Set them in `BXRestSettings.update()` for the whole app or in the settings of a `new BXRestNavvy(settings)` client. `true` turns on the defaults, a number or an object sets your own values. While a setting is not set, requests go as before.
462
+
463
+ ```typescript
464
+ BXRestSettings.update({
465
+ retryOnQueryLimit: true, // 3 attempts, pause from 1000 ms
466
+ timeout: 30_000, // ms
467
+ throttle: { perSecond: 2 },
468
+ })
469
+ ```
470
+
471
+ | Setting | `true` means | What it does |
472
+ | --- | --- | --- |
473
+ | `retryOnQueryLimit` | `{ attempts: 3, delay: 1000 }` | Retries the request when the portal answers `QUERY_LIMIT_EXCEEDED` (HTTP 503, request rate limit exceeded). `attempts` is the total number of attempts including the first one, `delay` is the pause before the second attempt in ms, then it doubles: 1000, 2000, 4000... Other errors are not retried. When the attempts run out, the error of the last one goes out; in `.res()` it is a `BXRestApiError` with `error: 'QUERY_LIMIT_EXCEEDED'`. |
474
+ | `timeout` | `60000` | Time limit for one HTTP request in ms. A request that takes longer is aborted with `BXRestTimeoutError` (its `timeout` field is the limit). In `.res()` it is in `cause`; `.resVanilla()`, `.mapForVanilla()` and `.resAll()` error with it directly. |
475
+ | `throttle` | `{ perSecond: 2 }` | At most `perSecond` requests per second, the rest wait in a queue. 2 requests per second is the Bitrix24 limit on regular plans. |
476
+
477
+ An object may set only some fields: `retryOnQueryLimit: { attempts: 5 }` keeps `delay: 1000`.
478
+
479
+ - **Order:** retry, queue, timeout, [your own middleware](#your-own-middleware), axios. Every retry attempt queues again and gets its own `timeout`. Waiting in the queue and pauses before a retry do not count towards `timeout`.
480
+ - **The queue** belongs to each `new BXRestNavvy(settings)` client and is shared by everything that uses the global `BXRestSettings`. Every request goes through it, including every batch request of `.resAll()`.
481
+ - **`throttle` is stricter than the portal.** Bitrix24 lets short bursts above the limit through, while `throttle` spreads all requests evenly. If short bursts of requests need to be fast, `retryOnQueryLimit` alone is enough.
482
+ - **Unsubscribing** stops both the wait in the queue and the pause before a retry: such a request is never sent.
483
+ - **Settings are read at subscribe time**, like the rest.
484
+ - **An invalid value** — for example `throttle: { perSecond: 0 }` or a negative `timeout` — fails the request with a `TypeError` that describes it; nothing is sent to the portal.
485
+
486
+ ### Your own middleware
487
+
488
+ A middleware is a function every request passes through before it is sent: logging, metrics, changing headers, your own transport instead of axios. Set it in `middleware`, globally or per client in the same way:
489
+
490
+ ```typescript
491
+ import { BXRestMiddleware, BXRestSettings } from 'bx-rest'
492
+
493
+ const logDuration: BXRestMiddleware = async (config, next) => {
494
+ const started = Date.now()
495
+ try {
496
+ return await next(config)
497
+ } finally {
498
+ console.debug(config.method, Date.now() - started, 'ms')
499
+ }
500
+ }
501
+
502
+ BXRestSettings.update({ middleware: [logDuration] })
503
+ ```
504
+
505
+ - **`config`** is the request: `method` (`'GET'` or `'POST'`), `url` (with the parameters for GET), `data` (the POST body), `headers`, `withCredentials`, `signal`. `next(config)` sends it on and returns the response body.
506
+ - **Order:** the first in the list is the outermost one: it sees the request first and the response last. All your middleware run after `retryOnQueryLimit`, `throttle` and `timeout`, so they see every retry attempt. The retry after `auth.refresh` wraps all the steps: on an authorization refresh the request passes through them again.
507
+ - **To change the request**, pass a new object on: `next({ ...config, headers: { ...config.headers, 'X-Trace': id } })`.
508
+ - **Your own transport** is a middleware that does not call `next`: it sends the request itself and returns the response body. For a non-2xx response it must reject with an error that has a `response: { status, data }` field, as axios does. The library uses that field to recognize Bitrix errors (`BXRestApiError`) and authorization errors (`auth.refresh`).
509
+ - **Pass `config.signal`** to your transport: it aborts the request on unsubscribe and on `timeout`.
510
+ - **`config.url` and `config.data`** contain the token and the webhook secret — do not log them as they are.
511
+
407
512
  ## Working in an iframe without BX24.js
408
513
 
409
514
  `BXRestFrame` is the commands an application in an iframe sends to the portal: the frame size, the selection dialogs, sliders, the messenger, placements, options, installation. The same commands and the same names as in BX24.js, but with promises instead of callbacks, and with no need to load BX24.js. bx-rest itself makes the REST requests, and `getAuth()`/`refreshAuth()` give the token for them (see [Authorization refresh](#authorization-refresh)).
@@ -665,6 +770,12 @@ npm run demo:bootstrap
665
770
  Then, in any of `projects/demo-angular|demo-vue|demo-react`: `npm run dev`
666
771
  (for Angular, `npm start`). See each demo's own README for details.
667
772
 
773
+ `projects/demo-node` is a Node.js demo without a UI. It shows two portals in
774
+ one process, `retryOnQueryLimit`, `throttle`, `timeout`, your own `middleware`
775
+ for logging and handling `BXRestApiError`. `npm run mock` runs it against a
776
+ built-in mock portal, `npm start` against a real portal using the incoming
777
+ webhook address from `BX_WEBHOOK_A`. On a portal the demo only reads data.
778
+
668
779
  ## Custom REST methods
669
780
 
670
781
  `Navvy` is exported from `bx-rest`. In Angular, register the `NavvyProvider` shown above and inject `Navvy` into your custom API service. A method URL is represented as an array and is joined with dots before the request is sent.
package/README.md CHANGED
@@ -24,6 +24,9 @@
24
24
  - [Токен от портала без BX24.js](#токен-от-портала-без-bx24js)
25
25
  - [Рецепт: напрямую в портал](#рецепт-напрямую-в-портал)
26
26
  - [Рецепт: через бэкенд-прокси](#рецепт-через-бэкенд-прокси)
27
+ - [Несколько порталов](#несколько-порталов)
28
+ - [Повтор, таймаут и очередь запросов](#повтор-таймаут-и-очередь-запросов)
29
+ - [Свои middleware](#свои-middleware)
27
30
  - [Работа в iframe без BX24.js](#работа-в-iframe-без-bx24js)
28
31
  - [Использование в Angular](#использование-в-angular)
29
32
  - [SessionKeyServices](#sessionkeyservices)
@@ -103,7 +106,7 @@ console.log(deals)
103
106
 
104
107
  ### Режимы результата
105
108
 
106
- REST-вызовы ленивые: запрос начинается, когда на возвращённый `Observable` подписываются или передают его в `firstValueFrom`.
109
+ REST-вызовы ленивые: запрос начинается, когда на возвращённый `Observable` подписываются или передают его в `firstValueFrom`. Отписка до ответа отменяет HTTP-запрос — так работают `switchMap`, `takeUntil` и оператор `timeout` из RxJS. Отмена не откатывает то, что портал уже успел сделать: если `crm.deal.add` дошёл до сервера, сделка может быть создана.
107
110
 
108
111
  | Метод | Результат |
109
112
  | --- | --- |
@@ -206,7 +209,9 @@ const deals = await firstValueFrom(
206
209
  | --- | --- |
207
210
  | Ошибка API Bitrix с HTTP-статусом не 2xx — так Bitrix отдаёт большинство ошибок: `expired_token` (401), `ERROR_METHOD_NOT_FOUND` (404), `QUERY_LIMIT_EXCEEDED` (503), `Not found` у `crm.*.get` (400) | Возвращённый `Observable` завершается ошибкой `BXRestApiError` — с `throwOnApiError` и без него. |
208
211
  | Ошибка API Bitrix в теле ответа со статусом 2xx | По умолчанию `.res()` резолвится обычным образом со значением `undefined` — **исключение не выбрасывается**. Передайте `{ throwOnApiError: true }`, чтобы вместо этого выбрасывалось `BXRestApiError`. |
209
- | Ошибки транспорта / конфигурации — сбой сети, отсутствие авторизации, отсутствие базового URL, ответ не от Bitrix (например, HTML-страница ошибки прокси) | Возвращённый `Observable` завершается обычной ошибкой `Error`. Исходная ошибка — в её `cause`: для ответа не от Bitrix это ошибка axios, HTTP-статус — в `cause.response.status`. |
212
+ | Ошибки транспорта / конфигурации — сбой сети, превышен [`timeout`](#повтор-таймаут-и-очередь-запросов), отсутствие авторизации, пустой базовый адрес (см. ниже), ответ не от Bitrix (например, HTML-страница ошибки прокси) | Возвращённый `Observable` завершается обычной ошибкой `Error`. Исходная ошибка — в её `cause`: для ответа не от Bitrix это ошибка axios, HTTP-статус — в `cause.response.status`; для `timeout` — `BXRestTimeoutError`. |
213
+
214
+ **Базовый адрес.** Адрес запроса собирается из двух частей: адреса портала и `urls.additional_part`. Адрес портала — это `urls.key`, а при `urls.source: 'localStorage'` — значение в `localStorage` под ключом `urls.key`. Ошибка `Base URL was not resolved` возникает, только если пусты обе части. Если пуст только адрес портала, а `additional_part` равен `'rest'` (так в настройках по умолчанию), запрос уходит на `rest/<метод>` относительно текущей страницы. Это нужно страницам, открытым на домене самого портала. Но так же уйдёт запрос, если в `localStorage` под ключом ничего не оказалось, — проверяйте значение заранее.
210
215
 
211
216
  Поля `BXRestApiError`:
212
217
 
@@ -220,6 +225,8 @@ const deals = await firstValueFrom(
220
225
 
221
226
  Для методов REST v3 в `error` попадает `code` ошибки, а в `error_description` — её `message`.
222
227
 
228
+ **Токен в ошибках.** Ошибка axios хранит весь отправленный запрос: в `config.url` — адрес, а с ним и секрет вебхука, в `config.data` — тело с токеном. Библиотека отдаёт эту ошибку как есть — в `err.cause` у `.res()` и саму ошибку у `.resVanilla()`. Поэтому `console.error(err)` или отправка ошибки в систему сбора ошибок передаёт и токен. Если ошибки уходят в логи, выбирайте из них нужные поля, например `err.status`, `err.error` и `err.cause?.response?.data`.
229
+
223
230
  **Рекомендуемый вариант — `.res({ throwOnApiError: true })`.** Тогда любая ошибка Bitrix приходит как `BXRestApiError` независимо от HTTP-статуса, и её можно обработать вместе с транспортными ошибками в одном колбэке `catchError`/`error`:
224
231
 
225
232
  ```typescript
@@ -414,6 +421,104 @@ BXRestSettings.update({
414
421
 
415
422
  Ошибки функции продления попадают в `authRefreshError` исходной ошибки, а приложение может вывести эту ошибку в консоль или отправить в систему сбора ошибок — поэтому не кладите токены в текст ошибок функции продления.
416
423
 
424
+ ## Несколько порталов
425
+
426
+ `BXRestSettings` — общие настройки на всё приложение. Если в одном процессе нужно работать с несколькими порталами, например на сервере, который обслуживает разных клиентов, передайте настройки в конструктор `BXRestNavvy`. У такого клиента настройки свои: все его запросы идут на его портал с его токеном, а `BXRestSettings` на него не влияют.
427
+
428
+ ```typescript
429
+ import { BXRestNavvy } from 'bx-rest'
430
+ import { firstValueFrom } from 'rxjs'
431
+
432
+ const portalA = new BXRestNavvy({
433
+ auth: { source: () => tokenA, key: 'auth' },
434
+ urls: { source: 'string', key: 'https://a.bitrix24.ru', additional_part: 'rest' }
435
+ })
436
+ const portalB = new BXRestNavvy({
437
+ auth: { source: () => tokenB, key: 'auth' },
438
+ urls: { source: 'string', key: 'https://b.bitrix24.ru', additional_part: 'rest' }
439
+ })
440
+
441
+ const deals = await firstValueFrom(
442
+ portalA.crm.deal.list({ select: ['ID'], filter: {}, start: 0 }).resAll()
443
+ )
444
+ ```
445
+
446
+ - **Без аргумента** `new BXRestNavvy()` работает с глобальными `BXRestSettings`, как и раньше.
447
+ - **Формат** тот же, что у `BXRestSettings.update()`, но настройки передаются целиком: `auth` и `urls` обязательны, с глобальными настройками они не смешиваются.
448
+ - **Смена токена у готового клиента.** Функцию `auth.source` библиотека вызывает перед каждым запросом, в момент подписки. Чтобы сменить токен, поменяйте значение, которое она возвращает. Новый токен получат и запросы, созданные раньше, но ещё не запущенные:
449
+
450
+ ```typescript
451
+ let token = await getToken()
452
+ const portal = new BXRestNavvy({
453
+ auth: {
454
+ source: () => token,
455
+ key: 'auth',
456
+ refresh: async () => { token = await getNewToken() } // необязательно
457
+ },
458
+ urls: { source: 'string', key: 'https://a.bitrix24.ru', additional_part: 'rest' }
459
+ })
460
+
461
+ token = newToken // следующий запрос уйдёт с новым токеном
462
+ ```
463
+
464
+ - **Другой портал или другие заголовки** — создайте новый клиент, это занимает доли миллисекунды.
465
+ - **Продление авторизации** у каждого клиента своё: `auth.refresh` клиента вызывается только для его запросов.
466
+ - **`auth.source: 'cookies'` и `'localStorage'`** читают общее хранилище браузера, поэтому два клиента с одним ключом получат один и тот же токен. Для нескольких порталов задавайте `source` функцией.
467
+ - **Объекты, созданные напрямую**, — `new Navvy()`, `new BXRestRequest()`, `new SessionKeyServices()` — работают с глобальными `BXRestSettings`. Свои настройки получает только `BXRestNavvy` и всё, что создаётся через него.
468
+
469
+ ## Повтор, таймаут и очередь запросов
470
+
471
+ Три необязательные настройки защищают от лимита частоты запросов Bitrix24 и от зависших запросов. Задайте их в `BXRestSettings.update()` для всего приложения или в настройках клиента `new BXRestNavvy(settings)`. `true` включает значения по умолчанию, число или объект задают свои. Пока настройка не задана, запросы идут как раньше.
472
+
473
+ ```typescript
474
+ BXRestSettings.update({
475
+ retryOnQueryLimit: true, // 3 попытки, пауза от 1000 мс
476
+ timeout: 30_000, // мс
477
+ throttle: { perSecond: 2 },
478
+ })
479
+ ```
480
+
481
+ | Настройка | `true` означает | Что делает |
482
+ | --- | --- | --- |
483
+ | `retryOnQueryLimit` | `{ attempts: 3, delay: 1000 }` | Повторяет запрос, если портал ответил `QUERY_LIMIT_EXCEEDED` (HTTP 503, превышен лимит частоты запросов). `attempts` — сколько всего попыток вместе с первой, `delay` — пауза перед второй попыткой в мс, дальше она растёт вдвое: 1000, 2000, 4000... Другие ошибки не повторяются. Попытки кончились — наружу уходит ошибка последней, в `.res()` это `BXRestApiError` с `error: 'QUERY_LIMIT_EXCEEDED'`. |
484
+ | `timeout` | `60000` | Предельное время одного HTTP-запроса в мс. Не уложился — запрос отменяется с ошибкой `BXRestTimeoutError` (поле `timeout` — заданное время). В `.res()` она лежит в `cause`, `.resVanilla()`, `.mapForVanilla()` и `.resAll()` завершаются ей самой. |
485
+ | `throttle` | `{ perSecond: 2 }` | Не больше `perSecond` запросов в секунду, остальные ждут своей очереди. 2 запроса в секунду — лимит Bitrix24 на обычных тарифах. |
486
+
487
+ В объекте можно задать только часть полей: `retryOnQueryLimit: { attempts: 5 }` оставит `delay: 1000`.
488
+
489
+ - **Порядок:** повтор, очередь, таймаут, [свои middleware](#свои-middleware), axios. Каждая попытка повтора заново встаёт в очередь и получает своё время `timeout`. Ожидание в очереди и паузы перед повтором в `timeout` не входят.
490
+ - **Очередь** своя у каждого клиента `new BXRestNavvy(settings)` и общая у всех, кто работает с глобальными `BXRestSettings`. Через неё проходит каждый запрос, в том числе каждый batch-запрос `.resAll()`.
491
+ - **`throttle` строже портала.** Bitrix24 пропускает короткие всплески сверх лимита, а `throttle` равномерно распределяет все запросы. Если важна скорость коротких пачек запросов, хватит одного `retryOnQueryLimit`.
492
+ - **Отписка** прерывает и ожидание в очереди, и паузу перед повтором: такой запрос уже не уйдёт.
493
+ - **Настройки читаются в момент подписки**, как и остальные.
494
+ - **Неверное значение** — например, `throttle: { perSecond: 0 }` или отрицательный `timeout` — завершает запрос ошибкой `TypeError` с описанием, на портал ничего не уходит.
495
+
496
+ ### Свои middleware
497
+
498
+ Middleware — функция, через которую проходит каждый запрос перед отправкой: логирование, метрики, подмена заголовков, свой транспорт вместо axios. Задаётся в `middleware` — так же глобально или у клиента:
499
+
500
+ ```typescript
501
+ import { BXRestMiddleware, BXRestSettings } from 'bx-rest'
502
+
503
+ const logDuration: BXRestMiddleware = async (config, next) => {
504
+ const started = Date.now()
505
+ try {
506
+ return await next(config)
507
+ } finally {
508
+ console.debug(config.method, Date.now() - started, 'ms')
509
+ }
510
+ }
511
+
512
+ BXRestSettings.update({ middleware: [logDuration] })
513
+ ```
514
+
515
+ - **`config`** — запрос: `method` (`'GET'` или `'POST'`), `url` (у GET вместе с параметрами), `data` (тело POST), `headers`, `withCredentials`, `signal`. `next(config)` отправляет его дальше и возвращает тело ответа.
516
+ - **Порядок:** первый в списке — внешний, он первым видит запрос и последним — ответ. Все свои middleware идут после `retryOnQueryLimit`, `throttle` и `timeout`, поэтому видят каждую попытку повтора. Повтор после `auth.refresh` идёт снаружи всех шагов: при продлении авторизации запрос пройдёт через них ещё раз.
517
+ - **Изменить запрос** — передать дальше новый объект: `next({ ...config, headers: { ...config.headers, 'X-Trace': id } })`.
518
+ - **Свой транспорт** — middleware, который не зовёт `next`: он сам отправляет запрос и возвращает тело ответа. На ответ не 2xx он должен отклонить промис ошибкой с полем `response: { status, data }`, как это делает axios. По этому полю библиотека узнаёт ошибки Bitrix (`BXRestApiError`) и ошибки авторизации (`auth.refresh`).
519
+ - **`config.signal`** передавайте в свой транспорт: по нему запрос отменяется при отписке и по `timeout`.
520
+ - **`config.url` и `config.data`** содержат токен и секрет вебхука — не логируйте их как есть.
521
+
417
522
  ## Работа в iframe без BX24.js
418
523
 
419
524
  `BXRestFrame` — команды, которые приложение из iframe отправляет порталу: размер фрейма, диалоги выбора, слайдеры, мессенджер, встраивания, настройки, установка. Те же команды и те же имена, что у BX24.js, но вместо колбэков — промисы, и подключать BX24.js не нужно. REST-запросы делает сама bx-rest, токен для них — `getAuth()`/`refreshAuth()` (см. [Продление авторизации](#продление-авторизации)).
@@ -675,6 +780,13 @@ npm run demo:bootstrap
675
780
  Дальше в любой из `projects/demo-angular|demo-vue|demo-react`: `npm run dev`
676
781
  (для Angular — `npm start`). Подробности — в README каждого демо.
677
782
 
783
+ `projects/demo-node` — демо для Node.js, без интерфейса. Показывает два
784
+ портала в одном процессе, `retryOnQueryLimit`, `throttle`, `timeout`, свой
785
+ `middleware` для логирования и обработку `BXRestApiError`. `npm run mock`
786
+ запускает его со встроенной заглушкой портала, `npm start` — с настоящим
787
+ порталом по адресу входящего вебхука из `BX_WEBHOOK_A`. На портале демо только
788
+ читает данные.
789
+
678
790
  ## Кастомные REST-методы
679
791
 
680
792
  `Navvy` экспортируется из `bx-rest`. В Angular зарегистрируйте показанный выше `NavvyProvider` и внедрите `Navvy` в ваш кастомный API-сервис. URL метода представлен массивом и перед отправкой запроса соединяется точками.
@@ -1,4 +1,3 @@
1
- import axios from 'axios';
2
1
  /**
3
2
  * Why `BXRestSettings.auth.refresh` failed. When a request fails with an
4
3
  * authorization error and the refresh fails too, the library rethrows the
@@ -73,18 +72,31 @@ export function parseBXRestErrorBody(body) {
73
72
  * Bitrix error body, so the caller can keep its own handling for them.
74
73
  */
75
74
  export function bxRestApiErrorFromHttp(err, method) {
76
- if (!axios.isAxiosError(err) || !err.response) {
75
+ const response = httpErrorResponse(err);
76
+ if (!response) {
77
77
  return undefined;
78
78
  }
79
- const parsed = parseBXRestErrorBody(err.response.data);
79
+ const parsed = parseBXRestErrorBody(response.data);
80
80
  if (!parsed) {
81
81
  return undefined;
82
82
  }
83
83
  return new BXRestApiError(parsed.error, parsed.error_description, {
84
- status: err.response.status,
84
+ status: response.status,
85
85
  method,
86
86
  cause: err,
87
87
  authRefreshError: getAuthRefreshError(err)
88
88
  });
89
89
  }
90
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYngtcmVzdC9zcmMvZnVuY3Rpb25zL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUE7QUFzQnpCOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEtBQWM7SUFDaEQsT0FBTyxDQUFDLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUM7UUFDekMsQ0FBQyxDQUFFLEtBQXdDLENBQUMsZ0JBQWdCO1FBQzVELENBQUMsQ0FBQyxTQUFTLENBQUE7QUFDZixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxPQUFPLGNBQWUsU0FBUSxLQUFLO0lBTXZDLFlBQ1MsS0FBeUIsRUFDekIsaUJBQXFDLEVBQzVDLE9BQStCO1FBRS9CLEtBQUssQ0FDSCxpQkFBaUIsSUFBSSxLQUFLLElBQUksa0JBQWtCLEVBQ2hELE9BQU8sRUFBRSxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FDcEUsQ0FBQTtRQVBNLFVBQUssR0FBTCxLQUFLLENBQW9CO1FBQ3pCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBb0I7UUFPNUMsSUFBSSxDQUFDLElBQUksR0FBRyxnQkFBZ0IsQ0FBQTtRQUM1QixJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLENBQUE7UUFDN0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxDQUFBO1FBQzdCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLEVBQUUsZ0JBQWdCLENBQUE7SUFDbkQsQ0FBQztDQUNGO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxJQUFhO0lBRWhELElBQUksQ0FBQyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM1RCxPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBQ0QsTUFBTSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxHQUFHLElBQXVELENBQUE7SUFFNUYsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM5QixPQUFPO1lBQ0wsS0FBSztZQUNMLGlCQUFpQixFQUFFLE9BQU8saUJBQWlCLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsU0FBUztTQUN6RixDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxNQUFNLElBQUksS0FBSyxFQUFFLENBQUM7UUFDMUQsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUE2QyxDQUFBO1FBQ3ZFLE9BQU87WUFDTCxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQztZQUNuQixpQkFBaUIsRUFBRSxPQUFPLE9BQU8sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUztTQUNyRSxDQUFBO0lBQ0gsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsR0FBWSxFQUFFLE1BQWM7SUFDakUsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDOUMsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDdEQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztJQUNELE9BQU8sSUFBSSxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsaUJBQWlCLEVBQUU7UUFDaEUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTTtRQUMzQixNQUFNO1FBQ04sS0FBSyxFQUFFLEdBQUc7UUFDVixnQkFBZ0IsRUFBRSxtQkFBbUIsQ0FBQyxHQUFHLENBQUM7S0FDM0MsQ0FBQyxDQUFBO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBheGlvcyBmcm9tICdheGlvcydcblxuZXhwb3J0IGludGVyZmFjZSBCWFJlc3RBcGlFcnJvckRldGFpbHMge1xuICAvKipcbiAgICogSFRUUCBzdGF0dXMgb2YgdGhlIHBvcnRhbCByZXNwb25zZS4gYHVuZGVmaW5lZGAgd2hlbiB0aGUgZXJyb3IgY2FtZSBpblxuICAgKiB0aGUgYm9keSBvZiBhIHN1Y2Nlc3NmdWwgKDJ4eCkgcmVzcG9uc2UuXG4gICAqL1xuICBzdGF0dXM/OiBudW1iZXJcbiAgLyoqIFJFU1QgbWV0aG9kIHRoYXQgZmFpbGVkLCBlLmcuIGBjcm0uZGVhbC5nZXRgLiAqL1xuICBtZXRob2Q/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFRoZSBvcmlnaW5hbCBlcnJvciwgZS5nLiB0aGUgYEF4aW9zRXJyb3JgIOKAlCBpdHMgYHJlc3BvbnNlLmRhdGFgIGhvbGRzXG4gICAqIHRoZSBmdWxsIHJlc3BvbnNlIGJvZHkgKGluY2x1ZGluZyBSRVNUIHYzIGB2YWxpZGF0aW9uYCkuXG4gICAqL1xuICBjYXVzZT86IHVua25vd25cbiAgLyoqXG4gICAqIFdoeSBgQlhSZXN0U2V0dGluZ3MuYXV0aC5yZWZyZXNoYCBmYWlsZWQsIHdoZW4gdGhlIHJlcXVlc3QgZmFpbGVkIHdpdGhcbiAgICogYW4gYXV0aG9yaXphdGlvbiBlcnJvciBhbmQgdGhlIHJlZnJlc2ggY291bGQgbm90IGZpeCBpdC5cbiAgICovXG4gIGF1dGhSZWZyZXNoRXJyb3I/OiB1bmtub3duXG59XG5cbi8qKlxuICogV2h5IGBCWFJlc3RTZXR0aW5ncy5hdXRoLnJlZnJlc2hgIGZhaWxlZC4gV2hlbiBhIHJlcXVlc3QgZmFpbHMgd2l0aCBhblxuICogYXV0aG9yaXphdGlvbiBlcnJvciBhbmQgdGhlIHJlZnJlc2ggZmFpbHMgdG9vLCB0aGUgbGlicmFyeSByZXRocm93cyB0aGVcbiAqIG9yaWdpbmFsIHJlcXVlc3QgZXJyb3IgYW5kIHB1dHMgdGhlIHJlZnJlc2ggZmFpbHVyZSBpbnRvIGl0c1xuICogYGF1dGhSZWZyZXNoRXJyb3JgIGZpZWxkIOKAlCBvbiB0aGUgYEF4aW9zRXJyb3JgIG9mIGAucmVzVmFuaWxsYSgpYCBhbmQgdGhlXG4gKiBsaWtlLCBhbmQgb24gdGhlIGBCWFJlc3RBcGlFcnJvcmAgLyBgRXJyb3JgIG9mIGAucmVzKClgLlxuICpcbiAqIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB0aGVyZSB3YXMgbm8gcmVmcmVzaCBvciBpdCBzdWNjZWVkZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBdXRoUmVmcmVzaEVycm9yKGVycm9yOiB1bmtub3duKTogdW5rbm93biB7XG4gIHJldHVybiAoZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JylcbiAgICA/IChlcnJvciBhcyB7IGF1dGhSZWZyZXNoRXJyb3I/OiB1bmtub3duIH0pLmF1dGhSZWZyZXNoRXJyb3JcbiAgICA6IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEEgQml0cml4LWxldmVsIEFQSSBlcnJvciwgZS5nLiBgSU5TVUZGSUNJRU5UX1NDT1BFYCBvciBgZXhwaXJlZF90b2tlbmAuXG4gKlxuICogYC5yZXMoKWAgZmFpbHMgd2l0aCBpdCB3aGVuZXZlciB0aGUgcG9ydGFsIGFuc3dlcnMgd2l0aCBhIEJpdHJpeCBlcnJvciBhbmRcbiAqIGEgbm9uLTJ4eCBIVFRQIHN0YXR1cyDigJQgd2hpY2ggaXMgaG93IEJpdHJpeCBzZW5kcyBtb3N0IG9mIGl0cyBlcnJvcnMuIFdoZW5cbiAqIHRoZSBlcnJvciBjb21lcyBpbiB0aGUgYm9keSBvZiBhIDJ4eCByZXNwb25zZSwgYC5yZXMoKWAgcmVzb2x2ZXMgYXNcbiAqIGB1bmRlZmluZWRgIGJ5IGRlZmF1bHQgYW5kIGZhaWxzIHdpdGggaXQgb25seSB3aXRoXG4gKiBgeyB0aHJvd09uQXBpRXJyb3I6IHRydWUgfWAg4oCUIHNlZSB0aGUgXCJFcnJvciBoYW5kbGluZ1wiIHNlY3Rpb24gb2YgdGhlIFJFQURNRS5cbiAqIGAucmVzQWxsKClgIGFsd2F5cyBmYWlscyB3aXRoIGl0IG9uIGFuIGVycm9yIGluIHRoZSBib2R5IG9mIGEgMnh4IHJlc3BvbnNlLlxuICovXG5leHBvcnQgY2xhc3MgQlhSZXN0QXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyIHwgdW5kZWZpbmVkXG4gIHJlYWRvbmx5IG1ldGhvZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4gIC8qKiBTZWUgYGdldEF1dGhSZWZyZXNoRXJyb3IoKWAuICovXG4gIHJlYWRvbmx5IGF1dGhSZWZyZXNoRXJyb3I6IHVua25vd25cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZXJyb3I6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBwdWJsaWMgZXJyb3JfZGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICBkZXRhaWxzPzogQlhSZXN0QXBpRXJyb3JEZXRhaWxzXG4gICkge1xuICAgIHN1cGVyKFxuICAgICAgZXJyb3JfZGVzY3JpcHRpb24gfHwgZXJyb3IgfHwgJ0JpdHJpeCBBUEkgZXJyb3InLFxuICAgICAgZGV0YWlscz8uY2F1c2UgIT09IHVuZGVmaW5lZCA/IHsgY2F1c2U6IGRldGFpbHMuY2F1c2UgfSA6IHVuZGVmaW5lZFxuICAgIClcbiAgICB0aGlzLm5hbWUgPSAnQlhSZXN0QXBpRXJyb3InXG4gICAgdGhpcy5zdGF0dXMgPSBkZXRhaWxzPy5zdGF0dXNcbiAgICB0aGlzLm1ldGhvZCA9IGRldGFpbHM/Lm1ldGhvZFxuICAgIHRoaXMuYXV0aFJlZnJlc2hFcnJvciA9IGRldGFpbHM/LmF1dGhSZWZyZXNoRXJyb3JcbiAgfVxufVxuXG4vKipcbiAqIFJlY29nbmlzZXMgYSBCaXRyaXggZXJyb3IgYm9keTogUkVTVCB2MiBgeyBlcnJvciwgZXJyb3JfZGVzY3JpcHRpb24gfWAgYW5kXG4gKiBSRVNUIHYzIGB7IGVycm9yOiB7IGNvZGUsIG1lc3NhZ2UgfSB9YC4gUmV0dXJucyBgdW5kZWZpbmVkYCBmb3IgYW55dGhpbmdcbiAqIGVsc2Ug4oCUIGEgc3VjY2VzcyBwYXlsb2FkLCBhbiBIVE1MIHBhZ2UgZnJvbSBhIHByb3h5LCBhbiBlbXB0eSBib2R5LlxuICpcbiAqIEFuIGVtcHR5IGBlcnJvcmAgc3RpbGwgY291bnRzOiBCaXRyaXggYW5zd2VycyBlLmcuIGBjcm0uZGVhbC5nZXRgIGZvciBhXG4gKiBtaXNzaW5nIElEIHdpdGggYHsgZXJyb3I6ICcnLCBlcnJvcl9kZXNjcmlwdGlvbjogJ05vdCBmb3VuZCcgfWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJYUmVzdEVycm9yQm9keShib2R5OiB1bmtub3duKVxuICA6IHsgZXJyb3I6IHN0cmluZywgZXJyb3JfZGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZCB9IHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFib2R5IHx8IHR5cGVvZiBib2R5ICE9PSAnb2JqZWN0JyB8fCAhKCdlcnJvcicgaW4gYm9keSkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgY29uc3QgeyBlcnJvciwgZXJyb3JfZGVzY3JpcHRpb24gfSA9IGJvZHkgYXMgeyBlcnJvcjogdW5rbm93biwgZXJyb3JfZGVzY3JpcHRpb24/OiB1bmtub3duIH1cblxuICBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB7XG4gICAgICBlcnJvcixcbiAgICAgIGVycm9yX2Rlc2NyaXB0aW9uOiB0eXBlb2YgZXJyb3JfZGVzY3JpcHRpb24gPT09ICdzdHJpbmcnID8gZXJyb3JfZGVzY3JpcHRpb24gOiB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICBpZiAoZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJiAnY29kZScgaW4gZXJyb3IpIHtcbiAgICBjb25zdCB7IGNvZGUsIG1lc3NhZ2UgfSA9IGVycm9yIGFzIHsgY29kZTogdW5rbm93biwgbWVzc2FnZT86IHVua25vd24gfVxuICAgIHJldHVybiB7XG4gICAgICBlcnJvcjogU3RyaW5nKGNvZGUpLFxuICAgICAgZXJyb3JfZGVzY3JpcHRpb246IHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyA/IG1lc3NhZ2UgOiB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogVHVybnMgYW4gSFRUUCBmYWlsdXJlIGludG8gYSBgQlhSZXN0QXBpRXJyb3JgIHdoZW4gdGhlIHBvcnRhbCBhbnN3ZXJlZCB3aXRoXG4gKiBhIEJpdHJpeCBlcnJvciBib2R5LiBCaXRyaXggc2VuZHMgbW9zdCBlcnJvcnMgd2l0aCBhIG5vbi0yeHggc3RhdHVzXG4gKiAoNDAxIGBleHBpcmVkX3Rva2VuYCwgNDA0IGBFUlJPUl9NRVRIT0RfTk9UX0ZPVU5EYCwgNTAzXG4gKiBgUVVFUllfTElNSVRfRVhDRUVERURgLCA0MDAgXCJOb3QgZm91bmRcIiBmcm9tIGBjcm0uKi5nZXRgLCAuLi4pLCBhbmQgYXhpb3NcbiAqIHJlamVjdHMgb24gdGhvc2UuXG4gKlxuICogUmV0dXJucyBgdW5kZWZpbmVkYCBmb3IgbmV0d29yayBlcnJvcnMgYW5kIGZvciByZXNwb25zZXMgdGhhdCBhcmUgbm90IGFcbiAqIEJpdHJpeCBlcnJvciBib2R5LCBzbyB0aGUgY2FsbGVyIGNhbiBrZWVwIGl0cyBvd24gaGFuZGxpbmcgZm9yIHRoZW0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBieFJlc3RBcGlFcnJvckZyb21IdHRwKGVycjogdW5rbm93biwgbWV0aG9kOiBzdHJpbmcpOiBCWFJlc3RBcGlFcnJvciB8IHVuZGVmaW5lZCB7XG4gIGlmICghYXhpb3MuaXNBeGlvc0Vycm9yKGVycikgfHwgIWVyci5yZXNwb25zZSkge1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuICBjb25zdCBwYXJzZWQgPSBwYXJzZUJYUmVzdEVycm9yQm9keShlcnIucmVzcG9uc2UuZGF0YSlcbiAgaWYgKCFwYXJzZWQpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgcmV0dXJuIG5ldyBCWFJlc3RBcGlFcnJvcihwYXJzZWQuZXJyb3IsIHBhcnNlZC5lcnJvcl9kZXNjcmlwdGlvbiwge1xuICAgIHN0YXR1czogZXJyLnJlc3BvbnNlLnN0YXR1cyxcbiAgICBtZXRob2QsXG4gICAgY2F1c2U6IGVycixcbiAgICBhdXRoUmVmcmVzaEVycm9yOiBnZXRBdXRoUmVmcmVzaEVycm9yKGVycilcbiAgfSlcbn1cbiJdfQ==
90
+ /**
91
+ * HTTP-ответ из ошибки транспорта: `response: { status, data }`. Так устроен
92
+ * `AxiosError`, и так же должны отклоняться свои транспорты (middleware).
93
+ * Для сетевых ошибок, отмены и прочих ошибок — `undefined`.
94
+ */
95
+ export function httpErrorResponse(error) {
96
+ const response = (error && typeof error === 'object') ? error.response : undefined;
97
+ if (!response || typeof response !== 'object' || typeof response.status !== 'number') {
98
+ return undefined;
99
+ }
100
+ return response;
101
+ }
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYngtcmVzdC9zcmMvZnVuY3Rpb25zL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFvQkE7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsS0FBYztJQUNoRCxPQUFPLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsQ0FBQztRQUN6QyxDQUFDLENBQUUsS0FBd0MsQ0FBQyxnQkFBZ0I7UUFDNUQsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtBQUNmLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8sY0FBZSxTQUFRLEtBQUs7SUFNdkMsWUFDUyxLQUF5QixFQUN6QixpQkFBcUMsRUFDNUMsT0FBK0I7UUFFL0IsS0FBSyxDQUNILGlCQUFpQixJQUFJLEtBQUssSUFBSSxrQkFBa0IsRUFDaEQsT0FBTyxFQUFFLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUNwRSxDQUFBO1FBUE0sVUFBSyxHQUFMLEtBQUssQ0FBb0I7UUFDekIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFvQjtRQU81QyxJQUFJLENBQUMsSUFBSSxHQUFHLGdCQUFnQixDQUFBO1FBQzVCLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxFQUFFLE1BQU0sQ0FBQTtRQUM3QixJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLENBQUE7UUFDN0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQTtJQUNuRCxDQUFDO0NBQ0Y7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLElBQWE7SUFFaEQsSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzVELE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFDRCxNQUFNLEVBQUUsS0FBSyxFQUFFLGlCQUFpQixFQUFFLEdBQUcsSUFBdUQsQ0FBQTtJQUU1RixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzlCLE9BQU87WUFDTCxLQUFLO1lBQ0wsaUJBQWlCLEVBQUUsT0FBTyxpQkFBaUIsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxTQUFTO1NBQ3pGLENBQUE7SUFDSCxDQUFDO0lBRUQsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUMxRCxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLEtBQTZDLENBQUE7UUFDdkUsT0FBTztZQUNMLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ25CLGlCQUFpQixFQUFFLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTO1NBQ3JFLENBQUE7SUFDSCxDQUFDO0lBRUQsT0FBTyxTQUFTLENBQUE7QUFDbEIsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FBQyxHQUFZLEVBQUUsTUFBYztJQUNqRSxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN2QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsb0JBQW9CLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2xELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFDRCxPQUFPLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLGlCQUFpQixFQUFFO1FBQ2hFLE1BQU0sRUFBRSxRQUFRLENBQUMsTUFBTTtRQUN2QixNQUFNO1FBQ04sS0FBSyxFQUFFLEdBQUc7UUFDVixnQkFBZ0IsRUFBRSxtQkFBbUIsQ0FBQyxHQUFHLENBQUM7S0FDM0MsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsS0FBYztJQUM5QyxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUUsS0FBZ0MsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtJQUM5RyxJQUFJLENBQUMsUUFBUSxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxPQUFRLFFBQWlDLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQy9HLE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7SUFDRCxPQUFPLFFBQTZDLENBQUE7QUFDdEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgQlhSZXN0QXBpRXJyb3JEZXRhaWxzIHtcclxuICAvKipcclxuICAgKiBIVFRQIHN0YXR1cyBvZiB0aGUgcG9ydGFsIHJlc3BvbnNlLiBgdW5kZWZpbmVkYCB3aGVuIHRoZSBlcnJvciBjYW1lIGluXHJcbiAgICogdGhlIGJvZHkgb2YgYSBzdWNjZXNzZnVsICgyeHgpIHJlc3BvbnNlLlxyXG4gICAqL1xyXG4gIHN0YXR1cz86IG51bWJlclxyXG4gIC8qKiBSRVNUIG1ldGhvZCB0aGF0IGZhaWxlZCwgZS5nLiBgY3JtLmRlYWwuZ2V0YC4gKi9cclxuICBtZXRob2Q/OiBzdHJpbmdcclxuICAvKipcclxuICAgKiBUaGUgb3JpZ2luYWwgZXJyb3IsIGUuZy4gdGhlIGBBeGlvc0Vycm9yYCDigJQgaXRzIGByZXNwb25zZS5kYXRhYCBob2xkc1xyXG4gICAqIHRoZSBmdWxsIHJlc3BvbnNlIGJvZHkgKGluY2x1ZGluZyBSRVNUIHYzIGB2YWxpZGF0aW9uYCkuXHJcbiAgICovXHJcbiAgY2F1c2U/OiB1bmtub3duXHJcbiAgLyoqXHJcbiAgICogV2h5IGBCWFJlc3RTZXR0aW5ncy5hdXRoLnJlZnJlc2hgIGZhaWxlZCwgd2hlbiB0aGUgcmVxdWVzdCBmYWlsZWQgd2l0aFxyXG4gICAqIGFuIGF1dGhvcml6YXRpb24gZXJyb3IgYW5kIHRoZSByZWZyZXNoIGNvdWxkIG5vdCBmaXggaXQuXHJcbiAgICovXHJcbiAgYXV0aFJlZnJlc2hFcnJvcj86IHVua25vd25cclxufVxyXG5cclxuLyoqXHJcbiAqIFdoeSBgQlhSZXN0U2V0dGluZ3MuYXV0aC5yZWZyZXNoYCBmYWlsZWQuIFdoZW4gYSByZXF1ZXN0IGZhaWxzIHdpdGggYW5cclxuICogYXV0aG9yaXphdGlvbiBlcnJvciBhbmQgdGhlIHJlZnJlc2ggZmFpbHMgdG9vLCB0aGUgbGlicmFyeSByZXRocm93cyB0aGVcclxuICogb3JpZ2luYWwgcmVxdWVzdCBlcnJvciBhbmQgcHV0cyB0aGUgcmVmcmVzaCBmYWlsdXJlIGludG8gaXRzXHJcbiAqIGBhdXRoUmVmcmVzaEVycm9yYCBmaWVsZCDigJQgb24gdGhlIGBBeGlvc0Vycm9yYCBvZiBgLnJlc1ZhbmlsbGEoKWAgYW5kIHRoZVxyXG4gKiBsaWtlLCBhbmQgb24gdGhlIGBCWFJlc3RBcGlFcnJvcmAgLyBgRXJyb3JgIG9mIGAucmVzKClgLlxyXG4gKlxyXG4gKiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgd2FzIG5vIHJlZnJlc2ggb3IgaXQgc3VjY2VlZGVkLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEF1dGhSZWZyZXNoRXJyb3IoZXJyb3I6IHVua25vd24pOiB1bmtub3duIHtcclxuICByZXR1cm4gKGVycm9yICYmIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcpXHJcbiAgICA/IChlcnJvciBhcyB7IGF1dGhSZWZyZXNoRXJyb3I/OiB1bmtub3duIH0pLmF1dGhSZWZyZXNoRXJyb3JcclxuICAgIDogdW5kZWZpbmVkXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIEJpdHJpeC1sZXZlbCBBUEkgZXJyb3IsIGUuZy4gYElOU1VGRklDSUVOVF9TQ09QRWAgb3IgYGV4cGlyZWRfdG9rZW5gLlxyXG4gKlxyXG4gKiBgLnJlcygpYCBmYWlscyB3aXRoIGl0IHdoZW5ldmVyIHRoZSBwb3J0YWwgYW5zd2VycyB3aXRoIGEgQml0cml4IGVycm9yIGFuZFxyXG4gKiBhIG5vbi0yeHggSFRUUCBzdGF0dXMg4oCUIHdoaWNoIGlzIGhvdyBCaXRyaXggc2VuZHMgbW9zdCBvZiBpdHMgZXJyb3JzLiBXaGVuXHJcbiAqIHRoZSBlcnJvciBjb21lcyBpbiB0aGUgYm9keSBvZiBhIDJ4eCByZXNwb25zZSwgYC5yZXMoKWAgcmVzb2x2ZXMgYXNcclxuICogYHVuZGVmaW5lZGAgYnkgZGVmYXVsdCBhbmQgZmFpbHMgd2l0aCBpdCBvbmx5IHdpdGhcclxuICogYHsgdGhyb3dPbkFwaUVycm9yOiB0cnVlIH1gIOKAlCBzZWUgdGhlIFwiRXJyb3IgaGFuZGxpbmdcIiBzZWN0aW9uIG9mIHRoZSBSRUFETUUuXHJcbiAqIGAucmVzQWxsKClgIGFsd2F5cyBmYWlscyB3aXRoIGl0IG9uIGFuIGVycm9yIGluIHRoZSBib2R5IG9mIGEgMnh4IHJlc3BvbnNlLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEJYUmVzdEFwaUVycm9yIGV4dGVuZHMgRXJyb3Ige1xyXG4gIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyIHwgdW5kZWZpbmVkXHJcbiAgcmVhZG9ubHkgbWV0aG9kOiBzdHJpbmcgfCB1bmRlZmluZWRcclxuICAvKiogU2VlIGBnZXRBdXRoUmVmcmVzaEVycm9yKClgLiAqL1xyXG4gIHJlYWRvbmx5IGF1dGhSZWZyZXNoRXJyb3I6IHVua25vd25cclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgZXJyb3I6IHN0cmluZyB8IHVuZGVmaW5lZCxcclxuICAgIHB1YmxpYyBlcnJvcl9kZXNjcmlwdGlvbjogc3RyaW5nIHwgdW5kZWZpbmVkLFxyXG4gICAgZGV0YWlscz86IEJYUmVzdEFwaUVycm9yRGV0YWlsc1xyXG4gICkge1xyXG4gICAgc3VwZXIoXHJcbiAgICAgIGVycm9yX2Rlc2NyaXB0aW9uIHx8IGVycm9yIHx8ICdCaXRyaXggQVBJIGVycm9yJyxcclxuICAgICAgZGV0YWlscz8uY2F1c2UgIT09IHVuZGVmaW5lZCA/IHsgY2F1c2U6IGRldGFpbHMuY2F1c2UgfSA6IHVuZGVmaW5lZFxyXG4gICAgKVxyXG4gICAgdGhpcy5uYW1lID0gJ0JYUmVzdEFwaUVycm9yJ1xyXG4gICAgdGhpcy5zdGF0dXMgPSBkZXRhaWxzPy5zdGF0dXNcclxuICAgIHRoaXMubWV0aG9kID0gZGV0YWlscz8ubWV0aG9kXHJcbiAgICB0aGlzLmF1dGhSZWZyZXNoRXJyb3IgPSBkZXRhaWxzPy5hdXRoUmVmcmVzaEVycm9yXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogUmVjb2duaXNlcyBhIEJpdHJpeCBlcnJvciBib2R5OiBSRVNUIHYyIGB7IGVycm9yLCBlcnJvcl9kZXNjcmlwdGlvbiB9YCBhbmRcclxuICogUkVTVCB2MyBgeyBlcnJvcjogeyBjb2RlLCBtZXNzYWdlIH0gfWAuIFJldHVybnMgYHVuZGVmaW5lZGAgZm9yIGFueXRoaW5nXHJcbiAqIGVsc2Ug4oCUIGEgc3VjY2VzcyBwYXlsb2FkLCBhbiBIVE1MIHBhZ2UgZnJvbSBhIHByb3h5LCBhbiBlbXB0eSBib2R5LlxyXG4gKlxyXG4gKiBBbiBlbXB0eSBgZXJyb3JgIHN0aWxsIGNvdW50czogQml0cml4IGFuc3dlcnMgZS5nLiBgY3JtLmRlYWwuZ2V0YCBmb3IgYVxyXG4gKiBtaXNzaW5nIElEIHdpdGggYHsgZXJyb3I6ICcnLCBlcnJvcl9kZXNjcmlwdGlvbjogJ05vdCBmb3VuZCcgfWAuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCWFJlc3RFcnJvckJvZHkoYm9keTogdW5rbm93bilcclxuICA6IHsgZXJyb3I6IHN0cmluZywgZXJyb3JfZGVzY3JpcHRpb246IHN0cmluZyB8IHVuZGVmaW5lZCB9IHwgdW5kZWZpbmVkIHtcclxuICBpZiAoIWJvZHkgfHwgdHlwZW9mIGJvZHkgIT09ICdvYmplY3QnIHx8ICEoJ2Vycm9yJyBpbiBib2R5KSkge1xyXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxyXG4gIH1cclxuICBjb25zdCB7IGVycm9yLCBlcnJvcl9kZXNjcmlwdGlvbiB9ID0gYm9keSBhcyB7IGVycm9yOiB1bmtub3duLCBlcnJvcl9kZXNjcmlwdGlvbj86IHVua25vd24gfVxyXG5cclxuICBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgZXJyb3IsXHJcbiAgICAgIGVycm9yX2Rlc2NyaXB0aW9uOiB0eXBlb2YgZXJyb3JfZGVzY3JpcHRpb24gPT09ICdzdHJpbmcnID8gZXJyb3JfZGVzY3JpcHRpb24gOiB1bmRlZmluZWRcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmICdjb2RlJyBpbiBlcnJvcikge1xyXG4gICAgY29uc3QgeyBjb2RlLCBtZXNzYWdlIH0gPSBlcnJvciBhcyB7IGNvZGU6IHVua25vd24sIG1lc3NhZ2U/OiB1bmtub3duIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgIGVycm9yOiBTdHJpbmcoY29kZSksXHJcbiAgICAgIGVycm9yX2Rlc2NyaXB0aW9uOiB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgPyBtZXNzYWdlIDogdW5kZWZpbmVkXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdW5kZWZpbmVkXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUdXJucyBhbiBIVFRQIGZhaWx1cmUgaW50byBhIGBCWFJlc3RBcGlFcnJvcmAgd2hlbiB0aGUgcG9ydGFsIGFuc3dlcmVkIHdpdGhcclxuICogYSBCaXRyaXggZXJyb3IgYm9keS4gQml0cml4IHNlbmRzIG1vc3QgZXJyb3JzIHdpdGggYSBub24tMnh4IHN0YXR1c1xyXG4gKiAoNDAxIGBleHBpcmVkX3Rva2VuYCwgNDA0IGBFUlJPUl9NRVRIT0RfTk9UX0ZPVU5EYCwgNTAzXHJcbiAqIGBRVUVSWV9MSU1JVF9FWENFRURFRGAsIDQwMCBcIk5vdCBmb3VuZFwiIGZyb20gYGNybS4qLmdldGAsIC4uLiksIGFuZCBheGlvc1xyXG4gKiByZWplY3RzIG9uIHRob3NlLlxyXG4gKlxyXG4gKiBSZXR1cm5zIGB1bmRlZmluZWRgIGZvciBuZXR3b3JrIGVycm9ycyBhbmQgZm9yIHJlc3BvbnNlcyB0aGF0IGFyZSBub3QgYVxyXG4gKiBCaXRyaXggZXJyb3IgYm9keSwgc28gdGhlIGNhbGxlciBjYW4ga2VlcCBpdHMgb3duIGhhbmRsaW5nIGZvciB0aGVtLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGJ4UmVzdEFwaUVycm9yRnJvbUh0dHAoZXJyOiB1bmtub3duLCBtZXRob2Q6IHN0cmluZyk6IEJYUmVzdEFwaUVycm9yIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcmVzcG9uc2UgPSBodHRwRXJyb3JSZXNwb25zZShlcnIpXG4gIGlmICghcmVzcG9uc2UpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgY29uc3QgcGFyc2VkID0gcGFyc2VCWFJlc3RFcnJvckJvZHkocmVzcG9uc2UuZGF0YSlcclxuICBpZiAoIXBhcnNlZCkge1xyXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxyXG4gIH1cclxuICByZXR1cm4gbmV3IEJYUmVzdEFwaUVycm9yKHBhcnNlZC5lcnJvciwgcGFyc2VkLmVycm9yX2Rlc2NyaXB0aW9uLCB7XHJcbiAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcclxuICAgIG1ldGhvZCxcclxuICAgIGNhdXNlOiBlcnIsXHJcbiAgICBhdXRoUmVmcmVzaEVycm9yOiBnZXRBdXRoUmVmcmVzaEVycm9yKGVycilcclxuICB9KVxyXG59XHJcblxuLyoqXG4gKiBIVFRQLdC+0YLQstC10YIg0LjQtyDQvtGI0LjQsdC60Lgg0YLRgNCw0L3RgdC/0L7RgNGC0LA6IGByZXNwb25zZTogeyBzdGF0dXMsIGRhdGEgfWAuINCi0LDQuiDRg9GB0YLRgNC+0LXQvVxuICogYEF4aW9zRXJyb3JgLCDQuCDRgtCw0Log0LbQtSDQtNC+0LvQttC90Ysg0L7RgtC60LvQvtC90Y/RgtGM0YHRjyDRgdCy0L7QuCDRgtGA0LDQvdGB0L/QvtGA0YLRiyAobWlkZGxld2FyZSkuXG4gKiDQlNC70Y8g0YHQtdGC0LXQstGL0YUg0L7RiNC40LHQvtC6LCDQvtGC0LzQtdC90Ysg0Lgg0L/RgNC+0YfQuNGFINC+0YjQuNCx0L7QuiDigJQgYHVuZGVmaW5lZGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBodHRwRXJyb3JSZXNwb25zZShlcnJvcjogdW5rbm93bik6IHsgc3RhdHVzOiBudW1iZXIsIGRhdGE6IHVua25vd24gfSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHJlc3BvbnNlID0gKGVycm9yICYmIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcpID8gKGVycm9yIGFzIHsgcmVzcG9uc2U/OiB1bmtub3duIH0pLnJlc3BvbnNlIDogdW5kZWZpbmVkXG4gIGlmICghcmVzcG9uc2UgfHwgdHlwZW9mIHJlc3BvbnNlICE9PSAnb2JqZWN0JyB8fCB0eXBlb2YgKHJlc3BvbnNlIGFzIHsgc3RhdHVzPzogdW5rbm93biB9KS5zdGF0dXMgIT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG4gIHJldHVybiByZXNwb25zZSBhcyB7IHN0YXR1czogbnVtYmVyLCBkYXRhOiB1bmtub3duIH1cbn1cbiJdfQ==
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Символьный код нового элемента списка: `bx_rest_` и 128 случайных бит в hex.
3
+ * Только латиница, цифры и `_`: допустимые символы документация Bitrix24 не
4
+ * описывает.
5
+ *
6
+ * Случайные байты дают `crypto.getRandomValues` (в отличие от
7
+ * `crypto.randomUUID`, он есть и на страницах по http). Глобального `crypto`
8
+ * нет только в Node 18: там байты берутся из `Math.random`. Это не
9
+ * криптостойко, но код нужен лишь уникальный, а совпадение с уже занятым кодом
10
+ * ловит повтор в вызывающем методе.
11
+ */
12
+ export function uniqueElementCode() {
13
+ const bytes = new Uint8Array(16);
14
+ if (typeof globalThis.crypto?.getRandomValues === 'function') {
15
+ globalThis.crypto.getRandomValues(bytes);
16
+ }
17
+ else {
18
+ for (let i = 0; i < bytes.length; i++) {
19
+ bytes[i] = Math.floor(Math.random() * 256);
20
+ }
21
+ }
22
+ return 'bx_rest_' + Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
23
+ }
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pcXVlRWxlbWVudENvZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9ieC1yZXN0L3NyYy9mdW5jdGlvbnMvdW5pcXVlRWxlbWVudENvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxpQkFBaUI7SUFDL0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDaEMsSUFBSSxPQUFPLFVBQVUsQ0FBQyxNQUFNLEVBQUUsZUFBZSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQzdELFVBQVUsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzFDLENBQUM7U0FBTSxDQUFDO1FBQ04sS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN0QyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUE7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLFVBQVUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUN0RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiDQodC40LzQstC+0LvRjNC90YvQuSDQutC+0LQg0L3QvtCy0L7Qs9C+INGN0LvQtdC80LXQvdGC0LAg0YHQv9C40YHQutCwOiBgYnhfcmVzdF9gINC4IDEyOCDRgdC70YPRh9Cw0LnQvdGL0YUg0LHQuNGCINCyIGhleC5cbiAqINCi0L7Qu9GM0LrQviDQu9Cw0YLQuNC90LjRhtCwLCDRhtC40YTRgNGLINC4IGBfYDog0LTQvtC/0YPRgdGC0LjQvNGL0LUg0YHQuNC80LLQvtC70Ysg0LTQvtC60YPQvNC10L3RgtCw0YbQuNGPIEJpdHJpeDI0INC90LVcbiAqINC+0L/QuNGB0YvQstCw0LXRgi5cbiAqXG4gKiDQodC70YPRh9Cw0LnQvdGL0LUg0LHQsNC50YLRiyDQtNCw0Y7RgiBgY3J5cHRvLmdldFJhbmRvbVZhbHVlc2AgKNCyINC+0YLQu9C40YfQuNC1INC+0YJcbiAqIGBjcnlwdG8ucmFuZG9tVVVJRGAsINC+0L0g0LXRgdGC0Ywg0Lgg0L3QsCDRgdGC0YDQsNC90LjRhtCw0YUg0L/QviBodHRwKS4g0JPQu9C+0LHQsNC70YzQvdC+0LPQviBgY3J5cHRvYFxuICog0L3QtdGCINGC0L7Qu9GM0LrQviDQsiBOb2RlIDE4OiDRgtCw0Lwg0LHQsNC50YLRiyDQsdC10YDRg9GC0YHRjyDQuNC3IGBNYXRoLnJhbmRvbWAuINCt0YLQviDQvdC1XG4gKiDQutGA0LjQv9GC0L7RgdGC0L7QudC60L4sINC90L4g0LrQvtC0INC90YPQttC10L0g0LvQuNGI0Ywg0YPQvdC40LrQsNC70YzQvdGL0LksINCwINGB0L7QstC/0LDQtNC10L3QuNC1INGBINGD0LbQtSDQt9Cw0L3Rj9GC0YvQvCDQutC+0LTQvtC8XG4gKiDQu9C+0LLQuNGCINC/0L7QstGC0L7RgCDQsiDQstGL0LfRi9Cy0LDRjtGJ0LXQvCDQvNC10YLQvtC00LUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmlxdWVFbGVtZW50Q29kZSgpOiBzdHJpbmcge1xuICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDE2KVxuICBpZiAodHlwZW9mIGdsb2JhbFRoaXMuY3J5cHRvPy5nZXRSYW5kb21WYWx1ZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBnbG9iYWxUaGlzLmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnl0ZXMpXG4gIH0gZWxzZSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgYnl0ZXNbaV0gPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTYpXG4gICAgfVxuICB9XG4gIHJldHVybiAnYnhfcmVzdF8nICsgQXJyYXkuZnJvbShieXRlcywgYiA9PiBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpKS5qb2luKCcnKVxufVxuIl19
@@ -14,7 +14,7 @@ export { isBXRestAuthError } from './services/http/authRefresh';
14
14
  export { BXRestFrame } from './services/frame/frame';
15
15
  export { BXRestFrameError } from './services/frame/transport';
16
16
  export * from './services/frame/types';
17
- export { HttpNavvyServices } from './services/http/httpNavvy';
18
17
  export * as partNameMethods from './consts/part-name-methods';
19
18
  export * as BXBaseServices from './services/base';
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2J4LXJlc3Qvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUN2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDdEMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ3hDLE9BQU8sRUFBRSxjQUFjLElBQUksYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDeEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBQ2hGLE9BQU8sRUFBRSw4QkFBOEIsSUFBSSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFBO0FBQy9GLE9BQU8sRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUV4RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUE7QUFFN0QsY0FBYyx3QkFBd0IsQ0FBQTtBQUd0QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQTtBQUM3RCxPQUFPLEtBQUssZUFBZSxNQUFNLDRCQUE0QixDQUFBO0FBQzdELE9BQU8sS0FBSyxjQUFjLE1BQU0saUJBQWlCLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIGJ4LXJlc3RcclxuICovXHJcbmV4cG9ydCB7IEJYUmVzdFNldHRpbmdzIH0gZnJvbSAnLi9zZXR0aW5ncydcclxuZXhwb3J0IHsgQlhSZXN0TWFwUmVzdWx0IH0gZnJvbSAnLi9mdW5jdGlvbnMvbWFwUmVzdWx0J1xyXG5leHBvcnQgeyBCWFJlc3ROYXZ2eSB9IGZyb20gJy4vcmVzdC9uYXZ2eSdcclxuZXhwb3J0IHsgQlhSZXN0TWFwIH0gZnJvbSAnLi9yZXN0L21hcCdcclxuZXhwb3J0IHsgTmF2dnkgfSBmcm9tICcuL3NlcnZpY2VzL25hdnZ5J1xyXG5leHBvcnQgeyBIdHRwQlhTZXJ2aWNlcyBhcyBCWFJlc3RSZXF1ZXN0IH0gZnJvbSAnLi9zZXJ2aWNlcy9odHRwL0h0dHBCWCdcclxuZXhwb3J0IHsgU2Vzc2lvbktleVNlcnZpY2VzLCBTZXNzaW9uS2V5RXJyb3IgfSBmcm9tICcuL3NlcnZpY2VzL2h0dHAvc2Vzc2lvbktleSdcclxuZXhwb3J0IHsgaW5zdGFuY2VPZmlCWFJlc3RBbnN3ZXJTdWNjZXNzIGFzIGlzQlhSZXN0QW5zd2VyU3VjY2VzcyB9IGZyb20gJy4vZnVuY3Rpb25zL21hcFJlc3VsdCdcclxuZXhwb3J0IHsgQlhSZXN0QXBpRXJyb3IsIGdldEF1dGhSZWZyZXNoRXJyb3IgfSBmcm9tICcuL2Z1bmN0aW9ucy9lcnJvcnMnXHJcbmV4cG9ydCB0eXBlIHsgQlhSZXN0QXBpRXJyb3JEZXRhaWxzIH0gZnJvbSAnLi9mdW5jdGlvbnMvZXJyb3JzJ1xyXG5leHBvcnQgeyBpc0JYUmVzdEF1dGhFcnJvciB9IGZyb20gJy4vc2VydmljZXMvaHR0cC9hdXRoUmVmcmVzaCdcclxuZXhwb3J0IHsgQlhSZXN0RnJhbWUgfSBmcm9tICcuL3NlcnZpY2VzL2ZyYW1lL2ZyYW1lJ1xyXG5leHBvcnQgeyBCWFJlc3RGcmFtZUVycm9yIH0gZnJvbSAnLi9zZXJ2aWNlcy9mcmFtZS90cmFuc3BvcnQnXHJcbmV4cG9ydCB0eXBlIHsgQlhSZXN0RnJhbWVFcnJvckNvZGUgfSBmcm9tICcuL3NlcnZpY2VzL2ZyYW1lL3RyYW5zcG9ydCdcclxuZXhwb3J0ICogZnJvbSAnLi9zZXJ2aWNlcy9mcmFtZS90eXBlcydcclxuZXhwb3J0IHR5cGUgeyBCWFJlc3RSZXNPcHRpb25zIH0gZnJvbSAnLi9zZXJ2aWNlcy9uYXZ2eS9leHRlbmRzL25hdnZ5LXBhZy1iYXNlJ1xyXG5leHBvcnQgdHlwZSB7IGlCWFJlc3RTZXR0aW5ncyB9IGZyb20gJy4vdHlwaWZpY2F0aW9uL3NldHRpbmdzJ1xyXG5leHBvcnQgeyBIdHRwTmF2dnlTZXJ2aWNlcyB9IGZyb20gJy4vc2VydmljZXMvaHR0cC9odHRwTmF2dnknXHJcbmV4cG9ydCAqIGFzIHBhcnROYW1lTWV0aG9kcyBmcm9tICcuL2NvbnN0cy9wYXJ0LW5hbWUtbWV0aG9kcydcclxuZXhwb3J0ICogYXMgQlhCYXNlU2VydmljZXMgZnJvbSAnLi9zZXJ2aWNlcy9iYXNlJ1xyXG4iXX0=
19
+ export { BXRestTimeoutError } from './services/http/middleware';
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2J4LXJlc3Qvc3JjL3B1YmxpYy1hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQTtBQUN2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDdEMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ3hDLE9BQU8sRUFBRSxjQUFjLElBQUksYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDeEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFBO0FBQ2hGLE9BQU8sRUFBRSw4QkFBOEIsSUFBSSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFBO0FBQy9GLE9BQU8sRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUV4RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUE7QUFFN0QsY0FBYyx3QkFBd0IsQ0FBQTtBQUd0QyxPQUFPLEtBQUssZUFBZSxNQUFNLDRCQUE0QixDQUFBO0FBQzdELE9BQU8sS0FBSyxjQUFjLE1BQU0saUJBQWlCLENBQUE7QUFFakQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIGJ4LXJlc3RcclxuICovXHJcbmV4cG9ydCB7IEJYUmVzdFNldHRpbmdzIH0gZnJvbSAnLi9zZXR0aW5ncydcclxuZXhwb3J0IHsgQlhSZXN0TWFwUmVzdWx0IH0gZnJvbSAnLi9mdW5jdGlvbnMvbWFwUmVzdWx0J1xyXG5leHBvcnQgeyBCWFJlc3ROYXZ2eSB9IGZyb20gJy4vcmVzdC9uYXZ2eSdcclxuZXhwb3J0IHsgQlhSZXN0TWFwIH0gZnJvbSAnLi9yZXN0L21hcCdcclxuZXhwb3J0IHsgTmF2dnkgfSBmcm9tICcuL3NlcnZpY2VzL25hdnZ5J1xyXG5leHBvcnQgeyBIdHRwQlhTZXJ2aWNlcyBhcyBCWFJlc3RSZXF1ZXN0IH0gZnJvbSAnLi9zZXJ2aWNlcy9odHRwL0h0dHBCWCdcclxuZXhwb3J0IHsgU2Vzc2lvbktleVNlcnZpY2VzLCBTZXNzaW9uS2V5RXJyb3IgfSBmcm9tICcuL3NlcnZpY2VzL2h0dHAvc2Vzc2lvbktleSdcclxuZXhwb3J0IHsgaW5zdGFuY2VPZmlCWFJlc3RBbnN3ZXJTdWNjZXNzIGFzIGlzQlhSZXN0QW5zd2VyU3VjY2VzcyB9IGZyb20gJy4vZnVuY3Rpb25zL21hcFJlc3VsdCdcclxuZXhwb3J0IHsgQlhSZXN0QXBpRXJyb3IsIGdldEF1dGhSZWZyZXNoRXJyb3IgfSBmcm9tICcuL2Z1bmN0aW9ucy9lcnJvcnMnXHJcbmV4cG9ydCB0eXBlIHsgQlhSZXN0QXBpRXJyb3JEZXRhaWxzIH0gZnJvbSAnLi9mdW5jdGlvbnMvZXJyb3JzJ1xyXG5leHBvcnQgeyBpc0JYUmVzdEF1dGhFcnJvciB9IGZyb20gJy4vc2VydmljZXMvaHR0cC9hdXRoUmVmcmVzaCdcclxuZXhwb3J0IHsgQlhSZXN0RnJhbWUgfSBmcm9tICcuL3NlcnZpY2VzL2ZyYW1lL2ZyYW1lJ1xyXG5leHBvcnQgeyBCWFJlc3RGcmFtZUVycm9yIH0gZnJvbSAnLi9zZXJ2aWNlcy9mcmFtZS90cmFuc3BvcnQnXHJcbmV4cG9ydCB0eXBlIHsgQlhSZXN0RnJhbWVFcnJvckNvZGUgfSBmcm9tICcuL3NlcnZpY2VzL2ZyYW1lL3RyYW5zcG9ydCdcclxuZXhwb3J0ICogZnJvbSAnLi9zZXJ2aWNlcy9mcmFtZS90eXBlcydcclxuZXhwb3J0IHR5cGUgeyBCWFJlc3RSZXNPcHRpb25zIH0gZnJvbSAnLi9zZXJ2aWNlcy9uYXZ2eS9leHRlbmRzL25hdnZ5LXBhZy1iYXNlJ1xyXG5leHBvcnQgdHlwZSB7IGlCWFJlc3RTZXR0aW5ncyB9IGZyb20gJy4vdHlwaWZpY2F0aW9uL3NldHRpbmdzJ1xyXG5leHBvcnQgKiBhcyBwYXJ0TmFtZU1ldGhvZHMgZnJvbSAnLi9jb25zdHMvcGFydC1uYW1lLW1ldGhvZHMnXHJcbmV4cG9ydCAqIGFzIEJYQmFzZVNlcnZpY2VzIGZyb20gJy4vc2VydmljZXMvYmFzZSdcclxuZXhwb3J0IHR5cGUgeyBCWFJlc3RSZXF1ZXN0Q29uZmlnLCBCWFJlc3RTZW5kLCBCWFJlc3RNaWRkbGV3YXJlIH0gZnJvbSAnLi9zZXJ2aWNlcy9odHRwL3RyYW5zcG9ydCdcclxuZXhwb3J0IHsgQlhSZXN0VGltZW91dEVycm9yIH0gZnJvbSAnLi9zZXJ2aWNlcy9odHRwL21pZGRsZXdhcmUnXHJcbiJdfQ==