bx-rest 1.5.1 → 1.7.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 (301) hide show
  1. package/CHANGELOG.md +163 -0
  2. package/README.en.md +206 -3
  3. package/README.md +207 -3
  4. package/consts/part-name-methods.d.ts +1 -0
  5. package/esm2022/consts/part-name-methods.mjs +2 -1
  6. package/esm2022/functions/errors.mjs +17 -5
  7. package/esm2022/functions/uniqueElementCode.mjs +24 -0
  8. package/esm2022/map/pull/application/config.mjs +25 -29
  9. package/esm2022/map/pull.mjs +8 -13
  10. package/esm2022/public-api.mjs +3 -2
  11. package/esm2022/request-navvy/bizproc.mjs +18 -9
  12. package/esm2022/request-navvy/booking/v1/resource.mjs +2 -2
  13. package/esm2022/request-navvy/booking/v1/resourcetype.mjs +2 -2
  14. package/esm2022/request-navvy/calendar/event.mjs +1 -9
  15. package/esm2022/request-navvy/catalog/catalog.mjs +2 -2
  16. package/esm2022/request-navvy/catalog/document/element.mjs +2 -2
  17. package/esm2022/request-navvy/catalog/document.mjs +2 -2
  18. package/esm2022/request-navvy/catalog/documentcontractor.mjs +2 -2
  19. package/esm2022/request-navvy/catalog/extra.mjs +2 -2
  20. package/esm2022/request-navvy/catalog/measure.mjs +2 -2
  21. package/esm2022/request-navvy/catalog/price.mjs +2 -2
  22. package/esm2022/request-navvy/catalog/pricetype.mjs +2 -2
  23. package/esm2022/request-navvy/catalog/pricetypegroup.mjs +2 -2
  24. package/esm2022/request-navvy/catalog/pricetypelang.mjs +2 -2
  25. package/esm2022/request-navvy/catalog/product/offer.mjs +2 -2
  26. package/esm2022/request-navvy/catalog/product/service.mjs +2 -2
  27. package/esm2022/request-navvy/catalog/product/sku.mjs +2 -2
  28. package/esm2022/request-navvy/catalog/product.mjs +2 -2
  29. package/esm2022/request-navvy/catalog/productproperty.mjs +2 -2
  30. package/esm2022/request-navvy/catalog/productpropertyenum.mjs +2 -2
  31. package/esm2022/request-navvy/catalog/productpropertyfeature.mjs +2 -2
  32. package/esm2022/request-navvy/catalog/productpropertysection.mjs +2 -2
  33. package/esm2022/request-navvy/catalog/ratio.mjs +2 -2
  34. package/esm2022/request-navvy/catalog/roundingrule.mjs +2 -2
  35. package/esm2022/request-navvy/catalog/section.mjs +2 -2
  36. package/esm2022/request-navvy/catalog/store.mjs +2 -2
  37. package/esm2022/request-navvy/catalog/storeproduct.mjs +2 -2
  38. package/esm2022/request-navvy/catalog/userfield/document.mjs +2 -2
  39. package/esm2022/request-navvy/catalog/vat.mjs +2 -2
  40. package/esm2022/request-navvy/crm/activity.mjs +2 -2
  41. package/esm2022/request-navvy/crm/deal/recurring.mjs +2 -2
  42. package/esm2022/request-navvy/crm/item/product/row.mjs +2 -2
  43. package/esm2022/request-navvy/crm/orderentity.mjs +2 -2
  44. package/esm2022/request-navvy/crm/requisite/link.mjs +2 -2
  45. package/esm2022/request-navvy/crm/stagehistory.mjs +2 -2
  46. package/esm2022/request-navvy/crm/timeline/bindings.mjs +2 -2
  47. package/esm2022/request-navvy/disk/operation.mjs +3 -10
  48. package/esm2022/request-navvy/documentgenerator/document.mjs +2 -2
  49. package/esm2022/request-navvy/documentgenerator/numerator.mjs +2 -2
  50. package/esm2022/request-navvy/documentgenerator/role.mjs +2 -2
  51. package/esm2022/request-navvy/documentgenerator/template.mjs +2 -2
  52. package/esm2022/request-navvy/pull/application/config.mjs +10 -4
  53. package/esm2022/request-navvy/pull/application/event.mjs +23 -0
  54. package/esm2022/request-navvy/pull/application/push.mjs +23 -0
  55. package/esm2022/request-navvy/pull/channel/public.mjs +4 -4
  56. package/esm2022/request-navvy/pull/config.mjs +8 -4
  57. package/esm2022/request-navvy/pull.mjs +12 -1
  58. package/esm2022/request-navvy/sale/basketitem.mjs +2 -2
  59. package/esm2022/request-navvy/sale/basketproperties.mjs +2 -2
  60. package/esm2022/request-navvy/sale/businessvaluepersondomain.mjs +2 -2
  61. package/esm2022/request-navvy/sale/order.mjs +2 -2
  62. package/esm2022/request-navvy/sale/payment.mjs +2 -2
  63. package/esm2022/request-navvy/sale/paymentitembasket.mjs +2 -2
  64. package/esm2022/request-navvy/sale/paymentitemshipment.mjs +2 -2
  65. package/esm2022/request-navvy/sale/persontype.mjs +2 -2
  66. package/esm2022/request-navvy/sale/property.mjs +2 -2
  67. package/esm2022/request-navvy/sale/propertyrelation.mjs +2 -2
  68. package/esm2022/request-navvy/sale/propertyvalue.mjs +2 -2
  69. package/esm2022/request-navvy/sale/propertyvariant.mjs +2 -2
  70. package/esm2022/request-navvy/sale/shipment.mjs +2 -2
  71. package/esm2022/request-navvy/sale/shipmentitem.mjs +2 -2
  72. package/esm2022/request-navvy/sale/shipmentproperty.mjs +2 -2
  73. package/esm2022/request-navvy/sale/shipmentpropertyvalue.mjs +2 -2
  74. package/esm2022/request-navvy/sale/status.mjs +2 -2
  75. package/esm2022/request-navvy/sale/statuslang.mjs +2 -2
  76. package/esm2022/request-navvy/sale/tradebinding.mjs +2 -2
  77. package/esm2022/request-navvy/sale/tradeplatform.mjs +2 -2
  78. package/esm2022/request-navvy/socialnetwork/api/livefeed.mjs +1 -5
  79. package/esm2022/request-navvy/task/operation/elapseditem.mjs +51 -28
  80. package/esm2022/request-navvy/tasks/task.mjs +1 -119
  81. package/esm2022/request-navvy/userfieldtype.mjs +2 -2
  82. package/esm2022/rest/navvy.mjs +66 -64
  83. package/esm2022/services/base.mjs +1 -4
  84. package/esm2022/services/context.mjs +59 -0
  85. package/esm2022/services/http/HttpBX.mjs +52 -19
  86. package/esm2022/services/http/authRefresh.mjs +25 -23
  87. package/esm2022/services/http/fetch.mjs +45 -0
  88. package/esm2022/services/http/http.mjs +25 -71
  89. package/esm2022/services/http/middleware.mjs +203 -0
  90. package/esm2022/services/http/sessionKey.mjs +16 -5
  91. package/esm2022/services/http/transport.mjs +5 -0
  92. package/esm2022/services/navvy/navvy-pag-nav-keyed.mjs +31 -0
  93. package/esm2022/services/navvy/navvy-support.mjs +2 -15
  94. package/esm2022/services/navvy.mjs +32 -31
  95. package/esm2022/typification/rest/calendar/event/get.mjs +1 -1
  96. package/esm2022/typification/rest/crm/requisite.mjs +1 -1
  97. package/esm2022/typification/rest/crm/timeline/bindings.mjs +1 -1
  98. package/esm2022/typification/rest/pull/application/config/get.mjs +1 -1
  99. package/esm2022/typification/rest/pull/application/event/add.mjs +2 -0
  100. package/esm2022/typification/rest/pull/application/push/add.mjs +2 -0
  101. package/esm2022/typification/rest/pull/config/get.mjs +1 -1
  102. package/esm2022/typification/rest/pull.mjs +3 -1
  103. package/esm2022/typification/rest/tasks/task/get.mjs +1 -1
  104. package/esm2022/typification/settings.mjs +1 -1
  105. package/fesm2022/bx-rest.mjs +800 -588
  106. package/fesm2022/bx-rest.mjs.map +1 -1
  107. package/functions/errors.d.ts +9 -0
  108. package/functions/uniqueElementCode.d.ts +12 -0
  109. package/map/pull/application/config.d.ts +3 -0
  110. package/package.json +1 -1
  111. package/public-api.d.ts +4 -2
  112. package/request-navvy/booking/v1/resource.d.ts +1 -1
  113. package/request-navvy/booking/v1/resourcetype.d.ts +1 -1
  114. package/request-navvy/catalog/catalog.d.ts +1 -1
  115. package/request-navvy/catalog/document/element.d.ts +1 -1
  116. package/request-navvy/catalog/document.d.ts +1 -1
  117. package/request-navvy/catalog/documentcontractor.d.ts +1 -1
  118. package/request-navvy/catalog/extra.d.ts +1 -1
  119. package/request-navvy/catalog/measure.d.ts +1 -1
  120. package/request-navvy/catalog/price.d.ts +1 -1
  121. package/request-navvy/catalog/pricetype.d.ts +1 -1
  122. package/request-navvy/catalog/pricetypegroup.d.ts +1 -1
  123. package/request-navvy/catalog/pricetypelang.d.ts +1 -1
  124. package/request-navvy/catalog/product/offer.d.ts +1 -1
  125. package/request-navvy/catalog/product/service.d.ts +1 -1
  126. package/request-navvy/catalog/product/sku.d.ts +1 -1
  127. package/request-navvy/catalog/product.d.ts +1 -1
  128. package/request-navvy/catalog/productproperty.d.ts +1 -1
  129. package/request-navvy/catalog/productpropertyenum.d.ts +1 -1
  130. package/request-navvy/catalog/productpropertyfeature.d.ts +1 -1
  131. package/request-navvy/catalog/productpropertysection.d.ts +1 -1
  132. package/request-navvy/catalog/ratio.d.ts +1 -1
  133. package/request-navvy/catalog/roundingrule.d.ts +1 -1
  134. package/request-navvy/catalog/section.d.ts +1 -1
  135. package/request-navvy/catalog/store.d.ts +1 -1
  136. package/request-navvy/catalog/storeproduct.d.ts +1 -1
  137. package/request-navvy/catalog/userfield/document.d.ts +1 -1
  138. package/request-navvy/catalog/vat.d.ts +1 -1
  139. package/request-navvy/crm/activity.d.ts +1 -1
  140. package/request-navvy/crm/deal/recurring.d.ts +1 -1
  141. package/request-navvy/crm/item/product/row.d.ts +5 -1
  142. package/request-navvy/crm/orderentity.d.ts +5 -1
  143. package/request-navvy/crm/requisite/link.d.ts +1 -1
  144. package/request-navvy/crm/stagehistory.d.ts +5 -1
  145. package/request-navvy/crm/timeline/bindings.d.ts +1 -1
  146. package/request-navvy/documentgenerator/document.d.ts +1 -1
  147. package/request-navvy/documentgenerator/numerator.d.ts +1 -1
  148. package/request-navvy/documentgenerator/role.d.ts +1 -1
  149. package/request-navvy/documentgenerator/template.d.ts +1 -1
  150. package/request-navvy/pull/application/config.d.ts +9 -3
  151. package/request-navvy/pull/application/event.d.ts +17 -0
  152. package/request-navvy/pull/application/push.d.ts +17 -0
  153. package/request-navvy/pull/config.d.ts +7 -3
  154. package/request-navvy/pull.d.ts +11 -0
  155. package/request-navvy/sale/basketitem.d.ts +1 -1
  156. package/request-navvy/sale/basketproperties.d.ts +1 -1
  157. package/request-navvy/sale/businessvaluepersondomain.d.ts +1 -1
  158. package/request-navvy/sale/order.d.ts +1 -1
  159. package/request-navvy/sale/payment.d.ts +1 -1
  160. package/request-navvy/sale/paymentitembasket.d.ts +1 -1
  161. package/request-navvy/sale/paymentitemshipment.d.ts +1 -1
  162. package/request-navvy/sale/persontype.d.ts +1 -1
  163. package/request-navvy/sale/property.d.ts +1 -1
  164. package/request-navvy/sale/propertyrelation.d.ts +1 -1
  165. package/request-navvy/sale/propertyvalue.d.ts +1 -1
  166. package/request-navvy/sale/propertyvariant.d.ts +1 -1
  167. package/request-navvy/sale/shipment.d.ts +1 -1
  168. package/request-navvy/sale/shipmentitem.d.ts +1 -1
  169. package/request-navvy/sale/shipmentproperty.d.ts +1 -1
  170. package/request-navvy/sale/shipmentpropertyvalue.d.ts +1 -1
  171. package/request-navvy/sale/status.d.ts +1 -1
  172. package/request-navvy/sale/statuslang.d.ts +1 -1
  173. package/request-navvy/sale/tradebinding.d.ts +1 -1
  174. package/request-navvy/sale/tradeplatform.d.ts +1 -1
  175. package/request-navvy/task/operation/elapseditem.d.ts +15 -10
  176. package/request-navvy/userfieldtype.d.ts +1 -1
  177. package/rest/navvy.d.ts +9 -0
  178. package/services/context.d.ts +43 -0
  179. package/services/http/HttpBX.d.ts +11 -0
  180. package/services/http/authRefresh.d.ts +5 -1
  181. package/services/http/fetch.d.ts +22 -0
  182. package/services/http/http.d.ts +20 -9
  183. package/services/http/middleware.d.ts +32 -0
  184. package/services/http/sessionKey.d.ts +10 -0
  185. package/services/http/transport.d.ts +28 -0
  186. package/services/navvy/navvy-pag-nav-keyed.d.ts +18 -0
  187. package/services/navvy/navvy-support.d.ts +0 -10
  188. package/services/navvy.d.ts +17 -0
  189. package/typification/rest/calendar/event/get.d.ts +1 -1
  190. package/typification/rest/crm/requisite.d.ts +1 -1
  191. package/typification/rest/crm/timeline/bindings.d.ts +2 -1
  192. package/typification/rest/pull/application/config/get.d.ts +1 -1
  193. package/typification/rest/pull/application/event/add.d.ts +24 -0
  194. package/typification/rest/pull/application/push/add.d.ts +16 -0
  195. package/typification/rest/pull/config/get.d.ts +28 -3
  196. package/typification/rest/pull.d.ts +2 -0
  197. package/typification/settings.d.ts +68 -0
  198. package/esm2022/functions/errorHandler.mjs +0 -34
  199. package/esm2022/request/app.mjs +0 -13
  200. package/esm2022/request/bizproc/activity.mjs +0 -3
  201. package/esm2022/request/bizproc/event.mjs +0 -3
  202. package/esm2022/request/bizproc/robot.mjs +0 -3
  203. package/esm2022/request/bizproc/task.mjs +0 -3
  204. package/esm2022/request/bizproc/workflow/instance.mjs +0 -3
  205. package/esm2022/request/bizproc/workflow/template.mjs +0 -3
  206. package/esm2022/request/bizproc/workflow.mjs +0 -18
  207. package/esm2022/request/bizproc.mjs +0 -15
  208. package/esm2022/request/department.mjs +0 -26
  209. package/esm2022/request/disk/attachedObject.mjs +0 -14
  210. package/esm2022/request/disk/file.mjs +0 -18
  211. package/esm2022/request/disk/folder.mjs +0 -117
  212. package/esm2022/request/disk.mjs +0 -11
  213. package/esm2022/request/lists/element.mjs +0 -18
  214. package/esm2022/request/lists/field.mjs +0 -35
  215. package/esm2022/request/lists.mjs +0 -86
  216. package/esm2022/request/log/blogcomment.mjs +0 -3
  217. package/esm2022/request/log/blogpost.mjs +0 -18
  218. package/esm2022/request/log.mjs +0 -9
  219. package/esm2022/request/pull/application/config.mjs +0 -11
  220. package/esm2022/request/pull/channel/public.mjs +0 -18
  221. package/esm2022/request/pull/config.mjs +0 -13
  222. package/esm2022/request/pull.mjs +0 -11
  223. package/esm2022/request/server.mjs +0 -14
  224. package/esm2022/request/socialnetwork/api/contentview.mjs +0 -14
  225. package/esm2022/request/socialnetwork/api/livefeed/blogpost/important.mjs +0 -14
  226. package/esm2022/request/socialnetwork/api/livefeed/blogpost.mjs +0 -7
  227. package/esm2022/request/socialnetwork/api/livefeed.mjs +0 -7
  228. package/esm2022/request/socialnetwork/api.mjs +0 -9
  229. package/esm2022/request/socialnetwork.mjs +0 -8
  230. package/esm2022/request/sonet_group.mjs +0 -24
  231. package/esm2022/request/task/commentitem.mjs +0 -32
  232. package/esm2022/request/task/elapseditem.mjs +0 -40
  233. package/esm2022/request/task/item/userfield.mjs +0 -14
  234. package/esm2022/request/task/item.mjs +0 -7
  235. package/esm2022/request/task/planner.mjs +0 -11
  236. package/esm2022/request/task.mjs +0 -13
  237. package/esm2022/request/tasks/task/result.mjs +0 -22
  238. package/esm2022/request/tasks/task.mjs +0 -110
  239. package/esm2022/request/tasks.mjs +0 -7
  240. package/esm2022/request/user/userfield.mjs +0 -14
  241. package/esm2022/request/user.mjs +0 -40
  242. package/esm2022/rest/base.mjs +0 -39
  243. package/esm2022/services/http/HttpData.mjs +0 -77
  244. package/esm2022/services/http/base/base.mjs +0 -4
  245. package/esm2022/services/http/httpNavvy.mjs +0 -14
  246. package/esm2022/typification/base/answers.mjs +0 -438
  247. package/esm2022/typification/base/params.mjs +0 -525
  248. package/esm2022/typification/base/workpiece/methods-list.mjs +0 -2
  249. package/esm2022/typification/base/workpiece/methods.mjs +0 -2
  250. package/functions/errorHandler.d.ts +0 -10
  251. package/request/app.d.ts +0 -8
  252. package/request/bizproc/activity.d.ts +0 -2
  253. package/request/bizproc/event.d.ts +0 -2
  254. package/request/bizproc/robot.d.ts +0 -2
  255. package/request/bizproc/task.d.ts +0 -2
  256. package/request/bizproc/workflow/instance.d.ts +0 -2
  257. package/request/bizproc/workflow/template.d.ts +0 -2
  258. package/request/bizproc/workflow.d.ts +0 -13
  259. package/request/bizproc.d.ts +0 -12
  260. package/request/department.d.ts +0 -18
  261. package/request/disk/attachedObject.d.ts +0 -8
  262. package/request/disk/file.d.ts +0 -10
  263. package/request/disk/folder.d.ts +0 -96
  264. package/request/disk.d.ts +0 -8
  265. package/request/lists/element.d.ts +0 -11
  266. package/request/lists/field.d.ts +0 -11
  267. package/request/lists.d.ts +0 -31
  268. package/request/log/blogcomment.d.ts +0 -2
  269. package/request/log/blogpost.d.ts +0 -11
  270. package/request/log.d.ts +0 -6
  271. package/request/pull/application/config.d.ts +0 -5
  272. package/request/pull/channel/public.d.ts +0 -5
  273. package/request/pull/config.d.ts +0 -7
  274. package/request/pull.d.ts +0 -8
  275. package/request/server.d.ts +0 -7
  276. package/request/socialnetwork/api/contentview.d.ts +0 -6
  277. package/request/socialnetwork/api/livefeed/blogpost/important.d.ts +0 -6
  278. package/request/socialnetwork/api/livefeed/blogpost.d.ts +0 -4
  279. package/request/socialnetwork/api/livefeed.d.ts +0 -4
  280. package/request/socialnetwork/api.d.ts +0 -6
  281. package/request/socialnetwork.d.ts +0 -4
  282. package/request/sonet_group.d.ts +0 -8
  283. package/request/task/commentitem.d.ts +0 -23
  284. package/request/task/elapseditem.d.ts +0 -26
  285. package/request/task/item/userfield.d.ts +0 -6
  286. package/request/task/item.d.ts +0 -4
  287. package/request/task/planner.d.ts +0 -4
  288. package/request/task.d.ts +0 -10
  289. package/request/tasks/task/result.d.ts +0 -13
  290. package/request/tasks/task.d.ts +0 -37
  291. package/request/tasks.d.ts +0 -4
  292. package/request/user/userfield.d.ts +0 -8
  293. package/request/user.d.ts +0 -24
  294. package/rest/base.d.ts +0 -33
  295. package/services/http/HttpData.d.ts +0 -7
  296. package/services/http/base/base.d.ts +0 -7
  297. package/services/http/httpNavvy.d.ts +0 -10
  298. package/typification/base/answers.d.ts +0 -12
  299. package/typification/base/params.d.ts +0 -16
  300. package/typification/base/workpiece/methods-list.d.ts +0 -247
  301. package/typification/base/workpiece/methods.d.ts +0 -20
@@ -1,5 +1,5 @@
1
- import { Subscription, of, throwError, from, defer, forkJoin, concatMap, toArray, mergeMap, shareReplay, tap } from 'rxjs';
2
- import { switchMap, catchError, map, take, mergeMap as mergeMap$1 } from 'rxjs/operators';
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';
@@ -414,9 +414,6 @@ async function getBase64FileLikeStr(file) {
414
414
  return undefined;
415
415
  }
416
416
  function prepareBaseAddress(url, add = '') {
417
- // if (url.search('https://') !== 0 && url.search('http://')) {
418
- // url = 'https://' + url
419
- // }
420
417
  if (add && add.length > 0) {
421
418
  if (url.lastIndexOf('/') !== (url.length - 1)) {
422
419
  url = url + '/';
@@ -523,6 +520,64 @@ class SessionStorage {
523
520
  }
524
521
  }
525
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
+
526
581
  class SessionKeyError extends Error {
527
582
  constructor(message) {
528
583
  super(message);
@@ -534,12 +589,18 @@ class SessionKeyServices {
534
589
  // НОВЫЙ объект (this.value = {...this.value, ...}), а не мутирует старый —
535
590
  // поэтому `= BXRestSettings.value` в виде обычного поля навсегда
536
591
  // "заморозил" бы то, что было на момент создания SessionKeyServices.
537
- // Геттер вместо этого читает актуальный BXRestSettings.value при каждом
538
- // обращении.
592
+ // Геттер вместо этого читает актуальные настройки при каждом обращении:
593
+ // свои настройки клиента или глобальные BXRestSettings.value.
539
594
  get BX_REST_SETTINGS() {
540
- return BXRestSettings.value;
595
+ return this.ctx.settings;
541
596
  }
542
597
  constructor() {
598
+ /**
599
+ * Контекст клиента, в котором создан объект: внутри `new BXRestNavvy(settings)`
600
+ * — контекст этого клиента, в остальных случаях — глобальные настройки.
601
+ * Объявлен первым: конструктор ниже уже читает настройки.
602
+ */
603
+ this.ctx = currentContext();
543
604
  this.authHave = false;
544
605
  this.subscribe = {
545
606
  authData: new Subscription()
@@ -598,6 +659,10 @@ class SessionKeyServices {
598
659
  getHeaders() {
599
660
  return { ...this.BX_REST_SETTINGS.headers };
600
661
  }
662
+ /** Свои middleware из настроек (`middleware`), читаются при каждом запросе — как и остальные настройки. */
663
+ getMiddleware() {
664
+ return this.BX_REST_SETTINGS.middleware ?? [];
665
+ }
601
666
  getSessid() {
602
667
  const check = this.getSearchParam('sessid');
603
668
  if (check) {
@@ -763,151 +828,29 @@ class SessionKeyServices {
763
828
  }
764
829
  }
765
830
 
766
- class HttpData {
767
- constructor() {
768
- this.defSettings = {
769
- timeZone: {
770
- calc: true,
771
- levelOut: false
772
- }
773
- };
774
- }
775
- getHttpParamsPost(obj, sendHttpParams = new FormData(), nesting = [], settings = this.defSettings) {
776
- if (obj instanceof Blob) {
777
- let first = nesting[0];
778
- let setKey = (nesting.length > 1)
779
- ? first + '[' + nesting.slice(1).join('][') + ']'
780
- : first;
781
- sendHttpParams.set(setKey, obj);
782
- return sendHttpParams;
783
- }
784
- else if (obj instanceof Date) {
785
- let first = nesting[0];
786
- let tzoffset = (settings.timeZone.calc) ? obj.getTimezoneOffset() * 60000 : 0; // вычисляем влияние часового пояса
787
- let levelOut = (settings.timeZone.levelOut) ? obj.getTimezoneOffset() * 60000 : 0; // вычисляем влияние часового пояса
788
- let setKey = (nesting.length > 1)
789
- ? first + '[' + nesting.slice(1).join('][') + ']'
790
- : first;
791
- sendHttpParams.set(setKey, (new Date(obj.valueOf() + tzoffset - levelOut)).toISOString());
792
- return sendHttpParams;
793
- }
794
- else {
795
- for (const key in obj) {
796
- let setKey = '';
797
- if (nesting.length) {
798
- let first = nesting[0];
799
- setKey = (nesting.length > 1)
800
- ? first + '[' + nesting.slice(1).join('][') + '][' + key + ']'
801
- : first + '[' + key + ']';
802
- }
803
- else {
804
- setKey = key;
805
- }
806
- switch (typeof obj[key]) {
807
- case 'string':
808
- sendHttpParams.set(setKey, obj[key]);
809
- break;
810
- case 'symbol':
811
- case 'number':
812
- case 'bigint':
813
- case 'boolean':
814
- sendHttpParams.set(setKey, String(obj[key]));
815
- break;
816
- case 'object':
817
- nesting.push(key);
818
- sendHttpParams = this.getHttpParamsPost(obj[key], sendHttpParams, nesting, settings);
819
- nesting.pop();
820
- break;
821
- case 'function':
822
- case 'undefined':
823
- default:
824
- console.error('You sent something wrong', obj[key], typeof obj[key], typeof obj);
825
- }
826
- }
827
- }
828
- return sendHttpParams;
829
- }
830
- sliceArrayIntoChunks(arr, chunkSize) {
831
- const res = [];
832
- for (let i = 0; i < arr.length; i += chunkSize) {
833
- const chunk = arr.slice(i, i + chunkSize);
834
- res.push(chunk);
835
- }
836
- return res;
837
- }
838
- removingMultipleSlashes(str) {
839
- return str.replace(/\/{2,}/g, '/');
840
- }
841
- }
842
-
843
- class BaseHttp extends HttpData {
844
- }
845
-
846
- class HttpServices extends BaseHttp {
847
- constructor() {
848
- super();
849
- this.session = new SessionKeyServices();
850
- this.axiosInstance = axios.create();
851
- }
852
- httpPost(url, params = {}, settings = this.defSettings) {
853
- const auth = this.session.getAuthParams();
854
- const checkIsOn = this.session.getCheckAuthParamsIsOn();
855
- const paramsClone = clone(params);
856
- if (checkIsOn) {
857
- if (!auth) {
858
- return throwError(() => this.session.getAuthError('post'));
859
- }
860
- paramsClone[this.session.getKeyAuth()] = auth;
861
- }
862
- return this.session.getBaseUrl().pipe(switchMap((baseUrl) => {
863
- if (!baseUrl) {
864
- return throwError(() => this.session.getBaseUrlError('post'));
865
- }
866
- const fullUrl = prepareBaseAddress(baseUrl) + url;
867
- if (this.session.getKeyAuth() === 'sessid') {
868
- const urlEncodedBody = new URLSearchParams();
869
- Object.keys(paramsClone).forEach((key) => {
870
- const value = paramsClone[key];
871
- if (typeof value === 'object' && value !== null) {
872
- for (const subKey in value) {
873
- if (Object.prototype.hasOwnProperty.call(value, subKey)) {
874
- urlEncodedBody.append(`${key}[${subKey}]`, value[subKey]);
875
- }
876
- }
877
- }
878
- else {
879
- urlEncodedBody.append(key, value);
880
- }
881
- });
882
- return from(this.axiosInstance.post(fullUrl, urlEncodedBody.toString(), {
883
- headers: {
884
- 'Content-Type': 'application/x-www-form-urlencoded',
885
- },
886
- }).then((response) => response.data));
887
- }
888
- const body = this.getHttpParamsPost(paramsClone, new FormData(), [], settings);
889
- return from(this.axiosInstance.post(fullUrl, body).then((response) => response.data));
890
- }));
831
+ /**
832
+ * Общая часть HTTP-клиента: экземпляр axios и источник токена и адреса.
833
+ * Сами запросы отправляет `HttpBXServices` (`BXRestRequest`).
834
+ */
835
+ class HttpServices {
836
+ /**
837
+ * @param settings свои настройки, как у `new BXRestNavvy(settings)`: запросы
838
+ * идут на этот портал с этим токеном, а `BXRestSettings` на них не влияют.
839
+ * Без них — настройки клиента, внутри которого создан объект, или
840
+ * глобальные `BXRestSettings`.
841
+ */
842
+ constructor(settings) {
843
+ this.session = settings
844
+ ? runInContext(new BXRestContext(settings), () => new SessionKeyServices())
845
+ : new SessionKeyServices();
891
846
  }
892
- httpGet(url, params = {}) {
893
- const auth = this.session.getAuthParams();
894
- const checkIsOn = this.session.getCheckAuthParamsIsOn();
895
- const paramsClone = clone(params);
896
- if (checkIsOn) {
897
- if (!auth) {
898
- return throwError(() => this.session.getAuthError('get'));
899
- }
900
- paramsClone[this.session.getKeyAuth()] = auth;
901
- }
902
- return this.session.getBaseUrl().pipe(switchMap((baseUrl) => {
903
- if (!baseUrl) {
904
- return throwError(() => this.session.getBaseUrlError('get'));
905
- }
906
- const fullUrl = prepareBaseAddress(baseUrl) + url;
907
- const queryString = new URLSearchParams(paramsClone).toString();
908
- const finalUrl = `${fullUrl}?${queryString}`;
909
- return from(this.axiosInstance.get(finalUrl).then((response) => response.data));
910
- }));
847
+ /**
848
+ * Экземпляр axios клиента. Один на контекст (клиента со своими настройками
849
+ * или глобальные настройки) и создаётся при первом запросе — раньше каждый
850
+ * объект запроса создавал свой.
851
+ */
852
+ get axiosInstance() {
853
+ return this.session.ctx.axios ??= axios.create();
911
854
  }
912
855
  }
913
856
 
@@ -1008,20 +951,33 @@ function parseBXRestErrorBody(body) {
1008
951
  * Bitrix error body, so the caller can keep its own handling for them.
1009
952
  */
1010
953
  function bxRestApiErrorFromHttp(err, method) {
1011
- if (!axios.isAxiosError(err) || !err.response) {
954
+ const response = httpErrorResponse(err);
955
+ if (!response) {
1012
956
  return undefined;
1013
957
  }
1014
- const parsed = parseBXRestErrorBody(err.response.data);
958
+ const parsed = parseBXRestErrorBody(response.data);
1015
959
  if (!parsed) {
1016
960
  return undefined;
1017
961
  }
1018
962
  return new BXRestApiError(parsed.error, parsed.error_description, {
1019
- status: err.response.status,
963
+ status: response.status,
1020
964
  method,
1021
965
  cause: err,
1022
966
  authRefreshError: getAuthRefreshError(err)
1023
967
  });
1024
968
  }
969
+ /**
970
+ * HTTP-ответ из ошибки транспорта: `response: { status, data }`. Так устроен
971
+ * `AxiosError`, и так же должны отклоняться свои транспорты (middleware).
972
+ * Для сетевых ошибок, отмены и прочих ошибок — `undefined`.
973
+ */
974
+ function httpErrorResponse(error) {
975
+ const response = (error && typeof error === 'object') ? error.response : undefined;
976
+ if (!response || typeof response !== 'object' || typeof response.status !== 'number') {
977
+ return undefined;
978
+ }
979
+ return response;
980
+ }
1025
981
 
1026
982
  /**
1027
983
  * Коды ошибок Bitrix, которые лечатся продлением токена. `expired_token` —
@@ -1044,34 +1000,34 @@ const AUTH_ERROR_CODES = ['expired_token', 'invalid_token'];
1044
1000
  * Ответ 401 с другим кодом Bitrix ошибкой авторизации не считается.
1045
1001
  */
1046
1002
  function isBXRestAuthError(error) {
1047
- if (!axios.isAxiosError(error) || !error.response) {
1003
+ const response = httpErrorResponse(error);
1004
+ if (!response) {
1048
1005
  return false;
1049
1006
  }
1050
- const parsed = parseBXRestErrorBody(error.response.data);
1007
+ const parsed = parseBXRestErrorBody(response.data);
1051
1008
  if (parsed) {
1052
1009
  return AUTH_ERROR_CODES.includes(parsed.error);
1053
1010
  }
1054
- return error.response.status === 401;
1011
+ return response.status === 401;
1055
1012
  }
1056
- // Общее на всю библиотеку состояние продления — как и сами BXRestSettings.
1057
- // pendingRefresh — идущее сейчас продление, его ждут все упавшие запросы;
1058
- // refreshCount — сколько продлений уже завершилось успешно.
1059
- let pendingRefresh;
1060
- let refreshCount = 0;
1061
- function sharedRefresh(refresh) {
1062
- if (!pendingRefresh) {
1063
- pendingRefresh = Promise.resolve()
1013
+ // Состояние продления живёт в контексте клиента (BXRestContext): у глобальных
1014
+ // настроек оно одно на всю библиотеку, у каждого new BXRestNavvy(settings) —
1015
+ // своё. pendingRefresh — идущее сейчас продление, его ждут все упавшие
1016
+ // запросы клиента; refreshCount — сколько продлений уже завершилось успешно.
1017
+ function sharedRefresh(refresh, ctx) {
1018
+ if (!ctx.pendingRefresh) {
1019
+ ctx.pendingRefresh = Promise.resolve()
1064
1020
  // Через then, чтобы синхронное исключение в refresh() тоже стало
1065
1021
  // отклонённым промисом, а не вылетело из catchError
1066
1022
  .then(() => refresh())
1067
1023
  .then(() => {
1068
- refreshCount++;
1024
+ ctx.refreshCount++;
1069
1025
  })
1070
1026
  .finally(() => {
1071
- pendingRefresh = undefined;
1027
+ ctx.pendingRefresh = undefined;
1072
1028
  });
1073
1029
  }
1074
- return pendingRefresh;
1030
+ return ctx.pendingRefresh;
1075
1031
  }
1076
1032
  /**
1077
1033
  * Повтор запроса после продления авторизации (`BXRestSettings.auth.refresh`).
@@ -1080,23 +1036,26 @@ function sharedRefresh(refresh) {
1080
1036
  * `defer()` в HttpBXServices): повтор — это повторная подписка, поэтому
1081
1037
  * токен, адрес и заголовки берутся уже новые. На второй попытке ошибка не
1082
1038
  * перехватывается — запрос повторяется не больше одного раза.
1039
+ *
1040
+ * `ctx` — контекст клиента, из которого берутся `refresh`, `isAuthError` и
1041
+ * общее состояние продления.
1083
1042
  */
1084
- function withAuthRefresh(request$) {
1043
+ function withAuthRefresh(request$, ctx = globalContext) {
1085
1044
  return defer(() => {
1086
- const { refresh, isAuthError = isBXRestAuthError } = BXRestSettings.value.auth;
1045
+ const { refresh, isAuthError = isBXRestAuthError } = ctx.settings.auth;
1087
1046
  if (!refresh) {
1088
1047
  return request$;
1089
1048
  }
1090
- const refreshCountAtStart = refreshCount;
1049
+ const refreshCountAtStart = ctx.refreshCount;
1091
1050
  return request$.pipe(catchError((error) => {
1092
1051
  if (!isAuthError(error)) {
1093
1052
  return throwError(() => error);
1094
1053
  }
1095
1054
  // Пока этот запрос был в пути, токен уже продлили по ошибке другого
1096
1055
  // запроса — повторяем без нового продления
1097
- const refreshed = (refreshCount !== refreshCountAtStart)
1056
+ const refreshed = (ctx.refreshCount !== refreshCountAtStart)
1098
1057
  ? Promise.resolve()
1099
- : sharedRefresh(refresh);
1058
+ : sharedRefresh(refresh, ctx);
1100
1059
  return from(refreshed).pipe(catchError((refreshError) => {
1101
1060
  if (error && typeof error === 'object') {
1102
1061
  error.authRefreshError = refreshError;
@@ -1107,6 +1066,258 @@ function withAuthRefresh(request$) {
1107
1066
  });
1108
1067
  }
1109
1068
 
1069
+ /** Первый middleware в списке — внешний: он первым видит запрос и последним — ответ. */
1070
+ function composeMiddleware(middleware, terminal) {
1071
+ return middleware.reduceRight((next, step) => config => step(config, next), terminal);
1072
+ }
1073
+
1074
+ /** `retryOnQueryLimit: true`: всего 3 попытки, пауза перед второй — 1000 мс, дальше вдвое больше. */
1075
+ const DEFAULT_RETRY_ON_QUERY_LIMIT = { attempts: 3, delay: 1000 };
1076
+ /** `timeout: true`: 60 000 мс на один HTTP-запрос. */
1077
+ const DEFAULT_TIMEOUT$1 = 60_000;
1078
+ /** `throttle: true`: 2 запроса в секунду — лимит Bitrix24 на обычных тарифах. */
1079
+ const DEFAULT_THROTTLE = { perSecond: 2 };
1080
+ /**
1081
+ * Запрос не завершился за время из `timeout` в настройках. В `.resVanilla()`
1082
+ * приходит сама эта ошибка, в `.res()` — в `cause`.
1083
+ */
1084
+ class BXRestTimeoutError extends Error {
1085
+ constructor(timeout) {
1086
+ super(`The request did not finish in ${timeout} ms`);
1087
+ this.timeout = timeout;
1088
+ this.name = 'BXRestTimeoutError';
1089
+ }
1090
+ }
1091
+ /**
1092
+ * Встроенные шаги из настроек, в этом порядке: повтор, очередь, таймаут, журнал.
1093
+ * Повтор — снаружи: каждая попытка заново встаёт в очередь и получает свой
1094
+ * таймаут. Таймаут — внутри очереди: ожидание своей очереди его не тратит.
1095
+ * Журнал — внутри всех: каждая попытка — своя запись, без времени в очереди.
1096
+ */
1097
+ function builtInMiddleware(settings, state) {
1098
+ const steps = [];
1099
+ if (settings.retryOnQueryLimit) {
1100
+ const own = (settings.retryOnQueryLimit === true) ? {} : settings.retryOnQueryLimit;
1101
+ const attempts = own.attempts ?? DEFAULT_RETRY_ON_QUERY_LIMIT.attempts;
1102
+ const delay = own.delay ?? DEFAULT_RETRY_ON_QUERY_LIMIT.delay;
1103
+ if (!Number.isInteger(attempts) || attempts < 1) {
1104
+ throw invalid('retryOnQueryLimit.attempts', attempts, 'a whole number from 1');
1105
+ }
1106
+ if (!Number.isFinite(delay) || delay < 0) {
1107
+ throw invalid('retryOnQueryLimit.delay', delay, 'a number of milliseconds from 0');
1108
+ }
1109
+ steps.push(retryOnQueryLimit(attempts, delay));
1110
+ }
1111
+ if (settings.throttle) {
1112
+ const own = (settings.throttle === true) ? {} : settings.throttle;
1113
+ const perSecond = own.perSecond ?? DEFAULT_THROTTLE.perSecond;
1114
+ if (!Number.isFinite(perSecond) || perSecond <= 0) {
1115
+ throw invalid('throttle.perSecond', perSecond, 'a number above 0');
1116
+ }
1117
+ steps.push(throttle(perSecond, state));
1118
+ }
1119
+ if (settings.timeout) {
1120
+ const ms = (settings.timeout === true) ? DEFAULT_TIMEOUT$1 : settings.timeout;
1121
+ // setTimeout считает больше 2^31 − 1 мс за 0 и сработал бы сразу
1122
+ if (!Number.isFinite(ms) || ms <= 0 || ms > 2_147_483_647) {
1123
+ throw invalid('timeout', ms, 'a number of milliseconds from 1 to 2147483647');
1124
+ }
1125
+ steps.push(timeout(ms));
1126
+ }
1127
+ if (settings.logRequests !== undefined) {
1128
+ if (typeof settings.logRequests !== 'function') {
1129
+ throw invalid('logRequests', settings.logRequests, 'a function');
1130
+ }
1131
+ steps.push(logRequests(settings.logRequests));
1132
+ }
1133
+ if (settings.transport !== undefined && settings.transport !== 'axios' && settings.transport !== 'fetch') {
1134
+ throw invalid('transport', settings.transport, "'axios' or 'fetch'");
1135
+ }
1136
+ return steps;
1137
+ }
1138
+ function invalid(name, value, expected) {
1139
+ return new TypeError(`bx-rest settings: ${name} must be ${expected}, got ${String(value)}`);
1140
+ }
1141
+ function abortReason(signal) {
1142
+ return signal.reason ?? new Error('The request was aborted');
1143
+ }
1144
+ /** Пауза, которую прерывает отмена запроса. */
1145
+ function wait(ms, signal) {
1146
+ return new Promise((resolve, reject) => {
1147
+ if (signal?.aborted) {
1148
+ reject(abortReason(signal));
1149
+ return;
1150
+ }
1151
+ const onAbort = () => {
1152
+ clearTimeout(timer);
1153
+ reject(abortReason(signal));
1154
+ };
1155
+ const timer = setTimeout(() => {
1156
+ signal?.removeEventListener('abort', onAbort);
1157
+ resolve();
1158
+ }, ms);
1159
+ signal?.addEventListener('abort', onAbort, { once: true });
1160
+ });
1161
+ }
1162
+ /**
1163
+ * Повтор при `QUERY_LIMIT_EXCEEDED`: портал отвечает так (HTTP 503), когда
1164
+ * превышен лимит частоты запросов. Пауза растёт вдвое: `delay`, `2 × delay`, ...
1165
+ * `attempts` — сколько всего попыток, вместе с первой.
1166
+ */
1167
+ function retryOnQueryLimit(attempts, delay) {
1168
+ return async (config, next) => {
1169
+ for (let attempt = 1;; attempt++) {
1170
+ try {
1171
+ return await next(config);
1172
+ }
1173
+ catch (error) {
1174
+ const code = parseBXRestErrorBody(httpErrorResponse(error)?.data)?.error;
1175
+ if (attempt >= attempts || code !== 'QUERY_LIMIT_EXCEEDED') {
1176
+ throw error;
1177
+ }
1178
+ await wait(delay * 2 ** (attempt - 1), config.signal);
1179
+ }
1180
+ }
1181
+ };
1182
+ }
1183
+ /**
1184
+ * Не больше `perSecond` запросов в секунду: лишние ждут своей очереди.
1185
+ * Очередь общая для всех запросов клиента (`state` — его контекст).
1186
+ */
1187
+ function throttle(perSecond, state) {
1188
+ const interval = 1000 / perSecond;
1189
+ return (config, next) => {
1190
+ const now = Date.now();
1191
+ const start = Math.max(now, state.throttleNextSlot);
1192
+ const reserved = start + interval;
1193
+ state.throttleNextSlot = reserved;
1194
+ if (start <= now) {
1195
+ return next(config);
1196
+ }
1197
+ return wait(start - now, config.signal).then(() => next(config), (error) => {
1198
+ // Отменённый запрос освобождает своё место, если за ним никто не встал
1199
+ if (state.throttleNextSlot === reserved) {
1200
+ state.throttleNextSlot = start;
1201
+ }
1202
+ throw error;
1203
+ });
1204
+ };
1205
+ }
1206
+ /** Код ошибки Bitrix из тела ответа или, если его нет, текст ошибки запроса. */
1207
+ function errorText(body, error) {
1208
+ const code = parseBXRestErrorBody(body)?.error;
1209
+ if (code) {
1210
+ return code;
1211
+ }
1212
+ return (error instanceof Error) ? error.message : undefined;
1213
+ }
1214
+ /**
1215
+ * Пишет в журнал запись о каждом HTTP-запросе. Исключение из `log` проглатывается:
1216
+ * журнал не должен ломать запрос.
1217
+ */
1218
+ function logRequests(log) {
1219
+ const write = (entry) => {
1220
+ try {
1221
+ log(entry);
1222
+ }
1223
+ catch {
1224
+ // Сбой журнала — не ошибка запроса
1225
+ }
1226
+ };
1227
+ return async (config, next) => {
1228
+ const started = Date.now();
1229
+ try {
1230
+ const data = await next(config);
1231
+ const error = errorText(data);
1232
+ write({ method: config.method, url: config.url, duration: Date.now() - started, failed: false, ...(error ? { error } : {}) });
1233
+ return data;
1234
+ }
1235
+ catch (cause) {
1236
+ const response = httpErrorResponse(cause);
1237
+ const error = errorText(response?.data, cause);
1238
+ write({
1239
+ method: config.method,
1240
+ url: config.url,
1241
+ duration: Date.now() - started,
1242
+ failed: true,
1243
+ ...(response ? { status: response.status } : {}),
1244
+ ...(error ? { error } : {}),
1245
+ });
1246
+ throw cause;
1247
+ }
1248
+ };
1249
+ }
1250
+ /** Отменяет запрос, если он не завершился за `ms` миллисекунд. */
1251
+ function timeout(ms) {
1252
+ return (config, next) => {
1253
+ const controller = new AbortController();
1254
+ const onAbort = () => controller.abort(abortReason(config.signal));
1255
+ if (config.signal?.aborted) {
1256
+ onAbort();
1257
+ }
1258
+ else {
1259
+ config.signal?.addEventListener('abort', onAbort, { once: true });
1260
+ }
1261
+ let timer;
1262
+ const timedOut = new Promise((_, reject) => {
1263
+ timer = setTimeout(() => {
1264
+ const error = new BXRestTimeoutError(ms);
1265
+ controller.abort(error);
1266
+ reject(error);
1267
+ }, ms);
1268
+ });
1269
+ return Promise.race([next({ ...config, signal: controller.signal }), timedOut]).finally(() => {
1270
+ clearTimeout(timer);
1271
+ config.signal?.removeEventListener('abort', onAbort);
1272
+ });
1273
+ };
1274
+ }
1275
+
1276
+ /**
1277
+ * Ответ не 2xx при `transport: 'fetch'`. Поле `response` такое же, как у
1278
+ * `AxiosError`: по нему библиотека узнаёт ошибки Bitrix и ошибки авторизации.
1279
+ * В `.resVanilla()` приходит сама эта ошибка, в `.res()` — в `cause`.
1280
+ */
1281
+ class BXRestHttpError extends Error {
1282
+ constructor(response) {
1283
+ super(`Request failed with status code ${response.status}`);
1284
+ this.response = response;
1285
+ this.name = 'BXRestHttpError';
1286
+ }
1287
+ }
1288
+ /**
1289
+ * Транспорт `transport: 'fetch'`: глобальный `fetch` браузера или Node 18+.
1290
+ * Тело ответа разбирается как JSON, а если это не JSON (например, HTML от
1291
+ * прокси) — отдаётся строкой, как это делает axios.
1292
+ */
1293
+ async function fetchSend(config) {
1294
+ let body;
1295
+ if (config.method === 'POST') {
1296
+ body = (typeof config.data === 'string') ? config.data : JSON.stringify(config.data ?? {});
1297
+ }
1298
+ const response = await fetch(config.url, {
1299
+ method: config.method,
1300
+ headers: config.headers,
1301
+ body,
1302
+ credentials: config.withCredentials ? 'include' : 'same-origin',
1303
+ signal: config.signal,
1304
+ });
1305
+ const text = await response.text();
1306
+ let data = text;
1307
+ if (text) {
1308
+ try {
1309
+ data = JSON.parse(text);
1310
+ }
1311
+ catch {
1312
+ // Не JSON — отдаём текстом
1313
+ }
1314
+ }
1315
+ if (!response.ok) {
1316
+ throw new BXRestHttpError({ status: response.status, data });
1317
+ }
1318
+ return data;
1319
+ }
1320
+
1110
1321
  class HttpBXServices extends HttpServices {
1111
1322
  /**
1112
1323
  * Не считайте этот метод образцом/финальным API.
@@ -1171,8 +1382,8 @@ class HttpBXServices extends HttpServices {
1171
1382
  get(name, params = {}, headers) {
1172
1383
  return this.httpGet(this.getNameMethod(name), params, undefined, headers);
1173
1384
  }
1174
- // settings — только для совместимости сигнатуры с HttpServices: здесь тело
1175
- // уходит JSON-ом/urlencoded, и пересчёт дат из iHttpParamSettings не нужен.
1385
+ // settings не используется и оставлен ради прежней сигнатуры: headers
1386
+ // остаётся четвёртым параметром у httpPost и httpGet.
1176
1387
  httpPost(url, params = {}, settings, headers) {
1177
1388
  // defer() откладывает всё содержимое (в том числе чтение BXRestSettings
1178
1389
  // через this.session.*) до реальной подписки — иначе даже с "живым"
@@ -1203,20 +1414,19 @@ class HttpBXServices extends HttpServices {
1203
1414
  return throwError(() => this.session.getBaseUrlError('post'));
1204
1415
  }
1205
1416
  const fullUrl = prepareBaseAddress(baseUrl) + url;
1206
- if (key === 'sessid') {
1207
- // Преобразуем параметры в формат x-www-form-urlencoded
1208
- const bodyString = this.serializeBitrixParams(paramsClone);
1209
- return from(this.axiosInstance.post(fullUrl, bodyString, {
1210
- withCredentials: this.session.getWithCredentials(),
1211
- headers: this.buildHeaders(headers, { 'Content-Type': 'application/x-www-form-urlencoded' }),
1212
- }).then((response) => response.data));
1213
- }
1214
- return from(this.axiosInstance.post(fullUrl, paramsClone, {
1417
+ // sessid — тело x-www-form-urlencoded, остальные ключи — JSON
1418
+ const urlencoded = key === 'sessid';
1419
+ return this.send({
1420
+ method: 'POST',
1421
+ url: fullUrl,
1422
+ data: urlencoded ? this.serializeBitrixParams(paramsClone) : paramsClone,
1215
1423
  withCredentials: this.session.getWithCredentials(),
1216
- headers: this.buildHeaders(headers, { 'Content-Type': 'application/json' }),
1217
- }).then((response) => response.data));
1424
+ headers: this.buildHeaders(headers, {
1425
+ 'Content-Type': urlencoded ? 'application/x-www-form-urlencoded' : 'application/json'
1426
+ }),
1427
+ });
1218
1428
  }));
1219
- }));
1429
+ }), this.session.ctx);
1220
1430
  }
1221
1431
  httpGet(url, params = {}, settings, headers) {
1222
1432
  // Та же причина, что и у httpPost выше: откладываем чтение BXRestSettings
@@ -1244,12 +1454,43 @@ class HttpBXServices extends HttpServices {
1244
1454
  const fullUrl = prepareBaseAddress(baseUrl) + url;
1245
1455
  const queryString = this.serializeBitrixParams(paramsClone);
1246
1456
  const finalUrl = `${fullUrl}?${queryString}`;
1247
- return from(this.axiosInstance.get(finalUrl, {
1457
+ return this.send({
1458
+ method: 'GET',
1459
+ url: finalUrl,
1248
1460
  withCredentials: this.session.getWithCredentials(),
1249
1461
  headers: this.buildHeaders(headers),
1250
- }).then((response) => response.data));
1462
+ });
1251
1463
  }));
1252
- }));
1464
+ }), this.session.ctx);
1465
+ }
1466
+ /**
1467
+ * Отправка через шаги из настроек: `retryOnQueryLimit`, `throttle`,
1468
+ * `timeout`, `logRequests`, затем `middleware`; последним идёт транспорт
1469
+ * клиента — axios или `fetch` (`transport`). Настройки читаются при
1470
+ * подписке. Отписка отменяет HTTP-запрос (AbortSignal). Ошибка транспорта
1471
+ * уходит дальше как есть: у axios в ней весь запрос, вместе с токеном и
1472
+ * секретом вебхука (см. README, «Обработка ошибок»).
1473
+ */
1474
+ send(config) {
1475
+ return new Observable(subscriber => {
1476
+ const controller = new AbortController();
1477
+ const ctx = this.session.ctx;
1478
+ const settings = ctx.settings;
1479
+ const send = composeMiddleware([...builtInMiddleware(settings, ctx), ...this.session.getMiddleware()], (settings.transport === 'fetch') ? fetchSend : request => this.axiosSend(request));
1480
+ send({ ...config, signal: controller.signal }).then(data => {
1481
+ subscriber.next(data);
1482
+ subscriber.complete();
1483
+ }, (error) => subscriber.error(error));
1484
+ return () => controller.abort();
1485
+ });
1486
+ }
1487
+ /** Транспорт по умолчанию: axios клиента, как и раньше через post()/get(). */
1488
+ axiosSend(config) {
1489
+ const options = { headers: config.headers, withCredentials: config.withCredentials, signal: config.signal };
1490
+ const request = (config.method === 'GET')
1491
+ ? this.axiosInstance.get(config.url, options)
1492
+ : this.axiosInstance.post(config.url, config.data, options);
1493
+ return request.then(response => response.data);
1253
1494
  }
1254
1495
  /**
1255
1496
  * Заголовки запроса: `BXRestSettings.headers`, поверх них — заголовки
@@ -1503,25 +1744,49 @@ class NavvyPagNavResultKeyObject extends NavvyPagBase {
1503
1744
  }
1504
1745
  }
1505
1746
 
1506
- class NavvySupport {
1507
- constructor(requestClass) {
1508
- this.requestClass = requestClass;
1509
- this.pageSize = 50; // стандартный размер страницы
1747
+ /**
1748
+ * Пагинация для методов, у которых `result` — объект, а список лежит в нём под ключом:
1749
+ * `{ products: [...] }`, `{ orders: [...] }`.
1750
+ *
1751
+ * В отличие от {@link NavvyPagNavResultKey}, `.res()` отдаёт объект как есть, а `.resAll()` —
1752
+ * такой же объект, где под ключом собраны записи всех страниц. Так `.resAll()` можно добавить
1753
+ * методу, который раньше создавался через `simple`, не меняя результат его `.res()`.
1754
+ */
1755
+ class NavvyPagNavKeyed extends NavvyPagBase {
1756
+ constructor(url, param, key, map, restApi) {
1757
+ super(url, param, map, restApi);
1758
+ this.key = key;
1510
1759
  }
1511
- mapAndError(request) {
1512
- return request.pipe(map(v => BXRestMapResult(v)), catchError((err) => {
1513
- console.error(err);
1514
- throw new Error((err.error) ? err.error : err);
1515
- }));
1760
+ resAll() {
1761
+ return this.resFirstPage().pipe(mergeMap(first => this.resPages(offsetPageParams(this.param, first.total, this.pageSize)).pipe(map(pages => {
1762
+ const items = [first.result, ...pages].flatMap(page => this.listIn(page));
1763
+ const joined = { ...first.result, [this.key]: items };
1764
+ return (this.map ? this.map(joined) : joined);
1765
+ }))),
1766
+ // refCount: без подписчиков оставшиеся страницы запрашивать незачем
1767
+ shareReplay({ bufferSize: 1, refCount: true }));
1768
+ }
1769
+ listIn(page) {
1770
+ const list = page?.[this.key];
1771
+ return Array.isArray(list) ? list : [];
1516
1772
  }
1517
1773
  }
1518
1774
 
1519
1775
  class Navvy {
1776
+ /**
1777
+ * @param settings свои настройки, как у `new BXRestNavvy(settings)`: запросы
1778
+ * идут на этот портал с этим токеном, а `BXRestSettings` на них не влияют.
1779
+ * Без них — настройки клиента, внутри которого создан объект, или
1780
+ * глобальные `BXRestSettings`.
1781
+ */
1782
+ constructor(settings) {
1783
+ this.ctx = settings ? new BXRestContext(settings) : currentContext();
1784
+ }
1520
1785
  simple(url, arg, map) {
1521
- return new NavvySimple(url, arg !== undefined ? arg : undefined, map);
1786
+ return runInContext(this.ctx, () => new NavvySimple(url, arg !== undefined ? arg : undefined, map));
1522
1787
  }
1523
1788
  simpleV3(url, arg, map) {
1524
- return new NavvySimple(url, arg !== undefined ? arg : undefined, map, true);
1789
+ return runInContext(this.ctx, () => new NavvySimple(url, arg !== undefined ? arg : undefined, map, true));
1525
1790
  }
1526
1791
  /**
1527
1792
  * Новый, пока тестируемый метод для api методов с пагинацией
@@ -1532,41 +1797,30 @@ class Navvy {
1532
1797
  * @constructor
1533
1798
  */
1534
1799
  pagNav(url, arg, map) {
1535
- return new NavvyPag(url, arg, map);
1536
- }
1537
- // old PagNav
1538
- // PagNav<T, R, A extends iBXRestPagination>(
1539
- // func: (param: A) => Observable<iBXRestAnswer<T[]> | undefined>,
1540
- // arg: A,
1541
- // map: ((param: T[] | undefined) => R[] | undefined) | undefined) {
1542
- // return new NavvyPagNav(this.requestClass, this.mapClass, func, arg, map)
1543
- // }
1544
- // Batch<T, R, A extends iBXRestPagination>(
1545
- // func: (param: A) => Observable<iBXRestAnswer<T[]> | undefined>,
1546
- // arg: A,
1547
- // map: ((param: T[] | undefined) => R[] | undefined) | undefined) {
1548
- // return new NavvyBatch(this.requestClass, this.mapClass, func, arg, map)
1549
- // }
1550
- pagNavTasks(url,
1551
- // func: (param: A) => Observable<iBXRestAnswer<{tasks: T[] | undefined}> | undefined>,
1552
- arg, map) {
1553
- return new NavvyPagNavTasks(url, arg, map);
1800
+ return runInContext(this.ctx, () => new NavvyPag(url, arg, map));
1801
+ }
1802
+ pagNavTasks(url, arg, map) {
1803
+ return runInContext(this.ctx, () => new NavvyPagNavTasks(url, arg, map));
1554
1804
  }
1555
1805
  pagNavResultKey(url, arg, key, map) {
1556
- return new NavvyPagNavResultKey(url, arg, key, map);
1806
+ return runInContext(this.ctx, () => new NavvyPagNavResultKey(url, arg, key, map));
1557
1807
  }
1558
1808
  pagNavResultKeyObject(url, arg, key, map) {
1559
- return new NavvyPagNavResultKeyObject(url, arg, key, map);
1809
+ return runInContext(this.ctx, () => new NavvyPagNavResultKeyObject(url, arg, key, map));
1560
1810
  }
1561
- pagNavWithUselessKey(url,
1562
- // func: (param: A) => Observable<iBXRestAnswer<{ [key: string]: T }> | undefined>,
1563
- arg, map) {
1564
- return new NavvyPagNavWithUselessKey(url, arg, map);
1811
+ /**
1812
+ * Для методов, у которых `result` — объект со списком под ключом `key`, например
1813
+ * `{ products: [...] }`. `.res()` отдаёт объект как есть, `.resAll()` — такой же объект
1814
+ * с записями всех страниц под ключом.
1815
+ */
1816
+ pagNavKeyed(url, arg, key, map) {
1817
+ return runInContext(this.ctx, () => new NavvyPagNavKeyed(url, arg, key, map));
1818
+ }
1819
+ pagNavWithUselessKey(url, arg, map) {
1820
+ return runInContext(this.ctx, () => new NavvyPagNavWithUselessKey(url, arg, map));
1565
1821
  }
1566
- alterPagNav(url,
1567
- // func: (param: A) => Observable<iBXRestAnswer<T[]> | undefined>,
1568
- arg, map) {
1569
- return new NavvyAlterPagNav(url, arg, map);
1822
+ alterPagNav(url, arg, map) {
1823
+ return runInContext(this.ctx, () => new NavvyAlterPagNav(url, arg, map));
1570
1824
  }
1571
1825
  }
1572
1826
 
@@ -1677,6 +1931,7 @@ const $pull = 'pull';
1677
1931
  const $channel = 'channel';
1678
1932
  const $public = 'public';
1679
1933
  const $application = 'application';
1934
+ const $push = 'push';
1680
1935
  const $dialog = 'dialog';
1681
1936
  const $users = 'users';
1682
1937
  const $messages = 'messages';
@@ -2478,6 +2733,7 @@ var partNameMethods$1 = /*#__PURE__*/Object.freeze({
2478
2733
  $publication: $publication,
2479
2734
  $publicationFolder: $publicationFolder,
2480
2735
  $pull: $pull,
2736
+ $push: $push,
2481
2737
  $quick: $quick,
2482
2738
  $quote: $quote,
2483
2739
  $ratio: $ratio,
@@ -3600,12 +3856,6 @@ class BXRestNavvyTasksTask {
3600
3856
  * Переводит задачу в статус «завершена»
3601
3857
  */
3602
3858
  complete: [$tasks, $task, $complete],
3603
- // counters: {
3604
- // /**
3605
- // * Получает счетчики пользователя
3606
- // */
3607
- // get: [$tasks, $task, $counters, $get],
3608
- // },
3609
3859
  /**
3610
3860
  * Переводит задачу в статус «отложена»
3611
3861
  */
@@ -3618,30 +3868,6 @@ class BXRestNavvyTasksTask {
3618
3868
  * Возвращает информацию о конкретной задаче
3619
3869
  */
3620
3870
  get: [$tasks, $task, $get],
3621
- // /**
3622
- // * Удаляет задачу
3623
- // */
3624
- // delete: [$tasks, $task, $delete],
3625
- // /**
3626
- // * Позволяет отклонить задачу
3627
- // */
3628
- // disapprove: [$tasks, $task, $disapprove],
3629
- // favorite: {
3630
- // /**
3631
- // * Добавляет задачи в "Избранное"
3632
- // */
3633
- // add: [$tasks, $task, $favorite, $add],
3634
- // /**
3635
- // * Удаляет задачи из "Избранного"
3636
- // */
3637
- // delete: [$tasks, $task, $favorite, $delete],
3638
- // },
3639
- // files: {
3640
- // /**
3641
- // * Прикрепляет загруженный на диск файл к задаче
3642
- // */
3643
- // attach: [$tasks, $task, $files, $attach],
3644
- // },
3645
3871
  /**
3646
3872
  * Возвращает все доступные поля
3647
3873
  */
@@ -3650,36 +3876,10 @@ class BXRestNavvyTasksTask {
3650
3876
  * Метод для проверки доступа к задаче
3651
3877
  */
3652
3878
  getAccess: [$tasks, $task, $getaccess],
3653
- // history: {
3654
- // /**
3655
- // * Получает историю задачи
3656
- // */
3657
- // list: [$tasks, $task, $history, $list],
3658
- // },
3659
3879
  /**
3660
3880
  * Возвращает массив задач, каждая из которых содержит массив полей
3661
3881
  */
3662
3882
  list: [$tasks, $task, $list],
3663
- // /**
3664
- // * Останавливает выполнение задачи, переводя ее в статус "ждет выполнения"
3665
- // */
3666
- // pause: [$tasks, $task, $pause],
3667
- // /**
3668
- // * Возобновляет задачу после ее завершения
3669
- // */
3670
- // renew: [$tasks, $task, $renew],
3671
- // /**
3672
- // * Переводит задачу в статус «выполняется»
3673
- // */
3674
- // start: [$tasks, $task, $start],
3675
- // /**
3676
- // * Позволяет наблюдать за задачей
3677
- // */
3678
- // startWatch: [$tasks, $task, 'startwatch'],
3679
- // /**
3680
- // * Останавливает наблюдение за задачей
3681
- // */
3682
- // stopwatch: [$tasks, $task, 'stopwatch'],
3683
3883
  /**
3684
3884
  * Обновляет задачу
3685
3885
  */
@@ -3784,68 +3984,6 @@ class BXRestNavvyTasksTask {
3784
3984
  list(param = {}) {
3785
3985
  return this.Navvy.pagNavTasks(this.url.list, param, (BXRestMapTasksTask.list));
3786
3986
  }
3787
- /*
3788
- listArray(requestArray: RequestApiTaskListBX = {}) {
3789
- return this.list(requestArray).pipe(
3790
- map(v => this.http.mapResult(v)),
3791
- map(v => (v && v.tasks) ? v.tasks : [])
3792
- )
3793
- }
3794
-
3795
- listAll(requestArray: RequestApiTaskListBX = {}, cache = false): Observable<TaskBX[]> {
3796
- if (!requestArray.select) {
3797
- requestArray.select = this.def.select
3798
- if (cache) {
3799
- return this.storeTask$.pipe(
3800
- take(1),
3801
- mergeMap(tasks => {
3802
- if (tasks && tasks.data.http.list && requestArray.filter && requestArray.filter.ID) {
3803
- const ids = (typeof requestArray.filter.ID === 'number') ? [requestArray.filter.ID] : requestArray.filter.ID
3804
- let filter = tasks.data.http.list.filter(i => (i.id) ? ids.includes(i.id) : false)
3805
- if (filter.length === ids.length) {
3806
- return of(filter)
3807
- }
3808
- }
3809
- return this.getEndListArray(requestArray)
3810
- })
3811
- )
3812
- }
3813
- return this.getEndListArray(requestArray)
3814
- }
3815
- return this.getEndListArray(requestArray)
3816
- }
3817
-
3818
- getEndListArray(requestArray: RequestApiTaskListBX): Observable<TaskBX[]> {
3819
- return this.list(requestArray).pipe(
3820
- mergeMap((items: AnswerApiTaskBX | undefined): ObservableInput<any> | Observable<AnswerApiTaskBX[]> => {
3821
- if (items && items.result && typeof items.result.tasks === 'object') {
3822
- const items$ = of(items.result.tasks)
3823
- if (items.next) {
3824
- this.nowLoad$.next({
3825
- total: (items.total) ? items.total : 0,
3826
- next: items.next
3827
- })
3828
- requestArray.start = items.next
3829
- return this.getEndListArray(requestArray).pipe(
3830
- map(vEnd => {
3831
- if (vEnd && items.result.tasks) {
3832
- return [...items.result.tasks, ...vEnd]
3833
- }
3834
- return (items.result.tasks) ? items.result.tasks : []
3835
- }))
3836
- }
3837
- this.nowLoad$.next({
3838
- total: 0,
3839
- next: 0
3840
- })
3841
- return items$
3842
- } else {
3843
- return of([])
3844
- }
3845
- })
3846
- )
3847
- }
3848
- */
3849
3987
  /**
3850
3988
  * Возвращает список полей задачи.
3851
3989
  */
@@ -4143,6 +4281,18 @@ class BXRestNavvyDelegateElapsedItem {
4143
4281
  }
4144
4282
  }
4145
4283
 
4284
+ /** Результаты и `total` команд из ответов batch по ключам команд. Команды с ошибкой пропускаются. */
4285
+ function batchValues(answers) {
4286
+ const values = { result: {}, total: {} };
4287
+ for (const answer of answers ?? []) {
4288
+ if (instanceOfiBXRestAnswerSuccess(answer) && answer.result && typeof answer.result === 'object') {
4289
+ const batch = answer.result;
4290
+ Object.assign(values.result, batch.result);
4291
+ Object.assign(values.total, batch.result_total);
4292
+ }
4293
+ }
4294
+ return values;
4295
+ }
4146
4296
  class BXRestNavvyOperationElapsedItem {
4147
4297
  constructor(BXRestNavvyElapsedItem) {
4148
4298
  this.BXRestNavvyElapsedItem = BXRestNavvyElapsedItem;
@@ -4171,35 +4321,45 @@ class BXRestNavvyOperationElapsedItem {
4171
4321
  };
4172
4322
  return this.delegate.getList(param);
4173
4323
  }
4174
- // TODO: Сделать нормально
4175
4324
  /**
4176
- * Возвращает список записей о затраченном времени по задаче.
4325
+ * Возвращает все записи о затраченном времени по задачам `ids`: сначала записи первой задачи,
4326
+ * затем второй и так далее.
4327
+ *
4328
+ * Портал отдаёт не больше 50 записей на страницу. Первые страницы всех задач уходят одним
4329
+ * batch, остальные страницы запрашиваются только у задач, где записей больше 50.
4177
4330
  */
4178
4331
  getListByIDTask(ids) {
4179
4332
  // Пустой batch завершается без значения, и вызывающий код получил бы EmptyError
4180
4333
  if (!ids.length) {
4181
4334
  return of([]);
4182
4335
  }
4183
- // Работает только потому что "nPageSize: 99999"
4184
- return this.http.branch(ids.map(i => {
4185
- return {
4336
+ const pageSize = 50;
4337
+ const key = (index, page) => `${index}_${page}`;
4338
+ const commands = (pages) => Object.fromEntries(pages.map(({ index, page }) => [
4339
+ key(index, page),
4340
+ {
4186
4341
  name: this.http.getNameMethod([$task, $elapseditem, $getlist]),
4187
- param: {
4188
- TASKID: i,
4189
- PARAMS: {
4190
- NAV_PARAMS: {
4191
- nPageSize: 99999,
4192
- iNumPage: 1
4193
- }
4194
- }
4195
- }
4196
- };
4197
- })).pipe(map(v => {
4198
- if (v && v.length) {
4199
- const res = this.http.mapBranchResultWithoutKey(v);
4200
- return BXRestMapTaskElapsedItem.getList(res);
4342
+ param: { TASKID: ids[index], PARAMS: { NAV_PARAMS: { nPageSize: pageSize, iNumPage: page } } }
4201
4343
  }
4202
- return undefined;
4344
+ ]));
4345
+ const load = (pages) => pages.length
4346
+ ? this.http.branch(commands(pages)).pipe(map(v => batchValues(v)))
4347
+ : of({ result: {}, total: {} });
4348
+ return load(ids.map((_, index) => ({ index, page: 1 }))).pipe(mergeMap(first => {
4349
+ const rest = ids.flatMap((_, index) => {
4350
+ const pages = Math.ceil((Number(first.total[key(index, 1)]) || 0) / pageSize);
4351
+ return Array.from({ length: Math.max(pages - 1, 0) }, (_, i) => ({ index, page: i + 2 }));
4352
+ });
4353
+ return load(rest).pipe(map(more => ({ ...first.result, ...more.result })));
4354
+ }), map(result => {
4355
+ const items = ids.flatMap((_, index) => {
4356
+ const list = [];
4357
+ for (let page = 1; result[key(index, page)]; page++) {
4358
+ list.push(...result[key(index, page)]);
4359
+ }
4360
+ return list;
4361
+ });
4362
+ return BXRestMapTaskElapsedItem.getList(items);
4203
4363
  }));
4204
4364
  }
4205
4365
  /**
@@ -4327,12 +4487,12 @@ class BXRestNavvyOperationElapsedItem {
4327
4487
  return this.BXRestNavvyElapsedItem.add(param).res();
4328
4488
  }
4329
4489
  else {
4330
- return throwError(() => new Error('Отсутствуют права на добавление записи затраченного времени'));
4490
+ return throwError(() => new Error('No permission to add an elapsed time record to the task'));
4331
4491
  }
4332
4492
  }));
4333
4493
  }
4334
4494
  else {
4335
- return throwError(() => new Error('Отсутствуют права на чтение задачи'));
4495
+ return throwError(() => new Error('No permission to read the task'));
4336
4496
  }
4337
4497
  }));
4338
4498
  }
@@ -4349,10 +4509,10 @@ class BXRestNavvyOperationElapsedItem {
4349
4509
  if (allowed) {
4350
4510
  return this.BXRestNavvyElapsedItem.update(param).res();
4351
4511
  }
4352
- return throwError(() => new Error('Отсутствуют права на изменение записи затраченного времени'));
4512
+ return throwError(() => new Error('No permission to update the elapsed time record'));
4353
4513
  }));
4354
4514
  }
4355
- return throwError(() => new Error('Отсутствуют права на чтение задачи'));
4515
+ return throwError(() => new Error('No permission to read the task'));
4356
4516
  }));
4357
4517
  }
4358
4518
  /**
@@ -4380,7 +4540,7 @@ class BXRestNavvyOperationElapsedItem {
4380
4540
  if (canRead) {
4381
4541
  return this.BXRestNavvyElapsedItem.isActionAllowed(param).res();
4382
4542
  }
4383
- return throwError(() => new Error('Отсутствуют права на чтение задачи'));
4543
+ return throwError(() => new Error('No permission to read the task'));
4384
4544
  }));
4385
4545
  }
4386
4546
  /**
@@ -4396,12 +4556,12 @@ class BXRestNavvyOperationElapsedItem {
4396
4556
  return this.BXRestNavvyElapsedItem.delete(param).res();
4397
4557
  }
4398
4558
  else {
4399
- return throwError(() => new Error('Отсутствуют права на удаление записи затраченного времени'));
4559
+ return throwError(() => new Error('No permission to delete the elapsed time record'));
4400
4560
  }
4401
4561
  }));
4402
4562
  }
4403
4563
  else {
4404
- return throwError(() => new Error('Отсутствуют права на чтение задачи'));
4564
+ return throwError(() => new Error('No permission to read the task'));
4405
4565
  }
4406
4566
  }));
4407
4567
  }
@@ -5414,7 +5574,7 @@ class BXRestNavvyDiskOperation {
5414
5574
  generateUniqueName: true
5415
5575
  }).res();
5416
5576
  }
5417
- return throwError(() => new Error('Отсутствует общее хранилище для приложения'));
5577
+ return throwError(() => new Error('Could not get the app storage'));
5418
5578
  }));
5419
5579
  }
5420
5580
  /**
@@ -5432,13 +5592,6 @@ class BXRestNavvyDiskOperation {
5432
5592
  * Возвращает список папок и файлов в общем хранилище приложения.
5433
5593
  */
5434
5594
  getRootFoldersApp() {
5435
- // return this.BXDiskFolder$.pipe(
5436
- // take(1),
5437
- // mergeMap(
5438
- // saveData => {
5439
- // if (saveData.content.root.app) {
5440
- // return of(saveData.content.root.app)
5441
- // }
5442
5595
  return this.storage.getForApp().res().pipe(mergeMap$1(v => {
5443
5596
  if (v && v.ID) {
5444
5597
  return this.storage.getChildren({ id: v.ID }).res();
@@ -5464,7 +5617,7 @@ class BXRestNavvyDiskOperation {
5464
5617
  if (v && v.ID) {
5465
5618
  return this.storage.addFolder({ id: v.ID, data: { NAME: folderName } }).res();
5466
5619
  }
5467
- return throwError(() => new Error('Отсутствуют права добавление записи затраченного времени'));
5620
+ return throwError(() => new Error('Could not get the app storage'));
5468
5621
  }));
5469
5622
  }));
5470
5623
  }
@@ -5835,6 +5988,32 @@ class BXRestNavvyBizProcRobot {
5835
5988
  }
5836
5989
  }
5837
5990
 
5991
+ /**
5992
+ * Символьный код нового элемента списка: `bx_rest_` и 128 случайных бит в hex.
5993
+ * Только латиница, цифры и `_`: допустимые символы документация Bitrix24 не
5994
+ * описывает.
5995
+ *
5996
+ * Случайные байты дают `crypto.getRandomValues` (в отличие от
5997
+ * `crypto.randomUUID`, он есть и на страницах по http). Глобального `crypto`
5998
+ * нет только в Node 18: там байты берутся из `Math.random`. Это не
5999
+ * криптостойко, но код нужен лишь уникальный, а совпадение с уже занятым кодом
6000
+ * ловит повтор в вызывающем методе.
6001
+ */
6002
+ function uniqueElementCode() {
6003
+ const bytes = new Uint8Array(16);
6004
+ if (typeof globalThis.crypto?.getRandomValues === 'function') {
6005
+ globalThis.crypto.getRandomValues(bytes);
6006
+ }
6007
+ else {
6008
+ for (let i = 0; i < bytes.length; i++) {
6009
+ bytes[i] = Math.floor(Math.random() * 256);
6010
+ }
6011
+ }
6012
+ return 'bx_rest_' + Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
6013
+ }
6014
+
6015
+ /** Сколько раз пробуем новый `ELEMENT_CODE`, если такой код в списке уже занят. */
6016
+ const ELEMENT_CODE_ATTEMPTS = 3;
5838
6017
  /** Бизнес-процессы, задания, действия и роботы (`bizproc.*`). */
5839
6018
  class BXRestNavvyBizProc {
5840
6019
  constructor() {
@@ -5867,18 +6046,23 @@ class BXRestNavvyBizProc {
5867
6046
  if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
5868
6047
  parametersElement['DATE_CREATE'] = new Date();
5869
6048
  }
5870
- return this.BXRestNavvyLists.element.add({
6049
+ // ELEMENT_CODE обязателен и должен быть уникальным в списке. Занятые коды
6050
+ // знает только портал, поэтому на совпадение создаём новый код и повторяем.
6051
+ // throwOnApiError: иначе ошибка в ответе 2xx пришла бы как undefined.
6052
+ const addElement = (attempt) => this.BXRestNavvyLists.element.add({
5871
6053
  IBLOCK_TYPE_ID: 'bitrix_processes',
5872
6054
  IBLOCK_ID: id,
5873
- ELEMENT_CODE: 'trace_studio_' + Date.now() + '_' + Math.random(),
5874
- // тут должно быть уникально значение (генерация уникальных значений на фронте лол),
5875
- // как ещё уникальнее сделать я просто не знаю
5876
- // это поле обязательно без него не работает
6055
+ ELEMENT_CODE: uniqueElementCode(),
5877
6056
  FIELDS: {
5878
6057
  NAME: String(parametersElement['NAME']),
5879
6058
  ...parametersElement
5880
6059
  }
5881
- }).res().pipe(mergeMap(v => {
6060
+ }).res({ throwOnApiError: true }).pipe(catchError$1((error) => (attempt < ELEMENT_CODE_ATTEMPTS
6061
+ && error instanceof BXRestApiError
6062
+ && error.error === 'ERROR_ELEMENT_ALREADY_EXISTS')
6063
+ ? addElement(attempt + 1)
6064
+ : throwError(() => error)));
6065
+ return addElement(1).pipe(mergeMap(v => {
5882
6066
  if (v) {
5883
6067
  if (Object.keys(parametersBizProc).length && templateIDs.length) {
5884
6068
  let request = [];
@@ -5895,7 +6079,7 @@ class BXRestNavvyBizProc {
5895
6079
  return of(true);
5896
6080
  }
5897
6081
  }
5898
- return throwError(() => new Error('Не удалось запустить бизнес процесс'));
6082
+ return throwError(() => new Error('Could not start the business process: the list element was not created'));
5899
6083
  }));
5900
6084
  }
5901
6085
  }
@@ -6165,14 +6349,6 @@ class BXRestNavvyRestCalendarEvent {
6165
6349
  update: [$calendar, $event, $update],
6166
6350
  };
6167
6351
  this.Navvy = new Navvy();
6168
- // /** Возвращает список событий календаря, всегда весь список, паганации в методе нет да и не нужна */
6169
- // get(param: iBXRestCalendarEventGetParam) {
6170
- // return this.Navvy.simple(
6171
- // this.url.get,
6172
- // param,
6173
- // BXRestMapCalendarEvent.get
6174
- // )
6175
- // }
6176
6352
  this.get = Object.assign(
6177
6353
  /**
6178
6354
  * Возвращает список событий календаря, всегда весь список, паганации в методе нет да и не нужна.
@@ -8070,12 +8246,8 @@ class BXRestNavvySocialNetWorkApiLiveFeedBlogPost {
8070
8246
  }
8071
8247
  }
8072
8248
 
8073
- // import { Navvy } from '../../../services/navvy'
8074
- // import { BXRestSocialNetWorkApiLiveFeed } from '../../../request/socialnetwork/api/livefeed'
8075
8249
  class BXRestNavvySocialNetWorkApiLiveFeed {
8076
8250
  constructor() {
8077
- // private readonly contentView = new BXRestSocialNetWorkApiLiveFeed)
8078
- // private readonly Navvy = new Navvy(this.contentView, null)
8079
8251
  /**
8080
8252
  * Сообщения Ленты новостей в социальной сети (`socialnetwork.api.liveFeed.blogPost.*`).
8081
8253
  */
@@ -8119,53 +8291,44 @@ class BXRestNavvySocialNetWork {
8119
8291
  }
8120
8292
  }
8121
8293
 
8294
+ /** Поля `start` и `end` канала — в `Date`. Канал, которого нет в ответе, так и остаётся пустым. */
8295
+ function withDates(channel) {
8296
+ return channel
8297
+ ? { ...channel, start: toDate(channel.start), end: toDate(channel.end) }
8298
+ : undefined;
8299
+ }
8122
8300
  class BXRestMapPullApplicationConfig {
8301
+ /**
8302
+ * Даты каналов — в `Date`. `publicChannels: false` (сервер версии ниже 4) становится пустым объектом.
8303
+ */
8123
8304
  static get(value) {
8124
- return value ?
8125
- {
8126
- ...value,
8127
- ...{
8128
- channels: {
8129
- shared: {
8130
- ...value.channels.shared, ...{
8131
- start: toDate(value.channels.shared.start),
8132
- end: toDate(value.channels.shared.end),
8133
- }
8134
- },
8135
- private: {
8136
- ...value.channels.private, ...{
8137
- start: toDate(value.channels.private.start),
8138
- end: toDate(value.channels.private.end),
8139
- }
8140
- }
8141
- },
8142
- publicChannels: Object.fromEntries(Object.entries(value.publicChannels).map(([key, val]) => ([key,
8143
- {
8144
- ...val,
8145
- start: toDate(val.start),
8146
- end: toDate(val.end)
8147
- }
8148
- ]))),
8149
- }
8150
- }
8151
- : undefined;
8305
+ if (!value) {
8306
+ return undefined;
8307
+ }
8308
+ const publicChannels = value.publicChannels && typeof value.publicChannels === 'object'
8309
+ ? value.publicChannels
8310
+ : {};
8311
+ return {
8312
+ ...value,
8313
+ channels: {
8314
+ ...value.channels,
8315
+ shared: withDates(value.channels?.shared),
8316
+ private: withDates(value.channels?.private),
8317
+ },
8318
+ publicChannels: Object.fromEntries(Object.entries(publicChannels).map(([key, channel]) => [key, withDates(channel)])),
8319
+ };
8152
8320
  }
8153
8321
  }
8154
8322
 
8155
8323
  class BXRestMapPull {
8156
8324
  static get(value) {
8157
- // console.log('Object.entries(value.publicChannels)', value)
8158
- //if(value?.publicChannels) {
8159
- // console.log('Object.entries(value.publicChannels)',
8160
- // value.publicChannels, Object.entries(value.publicChannels), Object.fromEntries(Object.entries(value.publicChannels).map(([key, val]) => (
8161
- // [key,
8162
- // {
8163
- // ...val,
8164
- // start: toDate(val.start), end: toDate(val.end)
8165
- // } as iBXRestPullConfigPublicChannelsGet
8166
- // ]))) as Record<string, iBXRestPullConfigPublicChannelsGet>,)
8167
- //}
8168
- return value ? { ...BXRestMapPullApplicationConfig.get(value), ...{ serverTime: toDate(value.serverTime) } } : undefined;
8325
+ if (!value) {
8326
+ return undefined;
8327
+ }
8328
+ return {
8329
+ ...BXRestMapPullApplicationConfig.get(value),
8330
+ ...(value.serverTime ? { serverTime: toDate(value.serverTime) } : {}),
8331
+ };
8169
8332
  }
8170
8333
  }
8171
8334
 
@@ -8180,11 +8343,15 @@ class BXRestNavvyPullConfig {
8180
8343
  this.Navvy = new Navvy();
8181
8344
  }
8182
8345
  /**
8346
+ * Возвращает настройки подключения к серверам Push & Pull для пользователя.
8347
+ * Приложению нужен `pull.application.config.get`: `bx.pull.application.config.get()`.
8348
+ *
8183
8349
  * @experimental
8184
- * Этот метод находится в процессе тестирования и может измениться.
8350
+ * Метода нет в документации Bitrix24, ответ сверен только с официальным JS SDK.
8351
+ * Типы могут измениться.
8185
8352
  */
8186
- get() {
8187
- return this.Navvy.simple(this.url.get, undefined, BXRestMapPull.get);
8353
+ get(param) {
8354
+ return this.Navvy.simple(this.url.get, param, BXRestMapPull.get);
8188
8355
  }
8189
8356
  }
8190
8357
 
@@ -8202,7 +8369,7 @@ class BXRestMapPullChannelPublic {
8202
8369
  class BXRestNavvyPullChannelPublic {
8203
8370
  constructor() {
8204
8371
  this.url = {
8205
- get: [$log, $blogpost, $add]
8372
+ get: [$pull, $channel, $public, $get]
8206
8373
  };
8207
8374
  this.Navvy = new Navvy();
8208
8375
  }
@@ -8210,7 +8377,7 @@ class BXRestNavvyPullChannelPublic {
8210
8377
  * Возвращает публичный канал Push & Pull (public_id и подпись) с ограниченным сроком действия для приёма событий без авторизации пользователя.
8211
8378
  */
8212
8379
  get() {
8213
- return this.Navvy.simple([$pull, $channel, $public, $get], undefined, BXRestMapPullChannelPublic.get);
8380
+ return this.Navvy.simple(this.url.get, undefined, BXRestMapPullChannelPublic.get);
8214
8381
  }
8215
8382
  }
8216
8383
 
@@ -8219,13 +8386,65 @@ class BXRestNavvyPullApplicationConfig {
8219
8386
  this.Navvy = new Navvy();
8220
8387
  }
8221
8388
  /**
8222
- * Возвращает конфигурацию подключения приложения к серверам Push & Pull.
8389
+ * Возвращает настройки подключения приложения к серверам Push & Pull: адреса сервера и каналы.
8390
+ * Настройки личные: канал `private` принадлежит пользователю, с чьим токеном идёт запрос.
8391
+ * Запрашивайте их заново, когда истекут `exp` или `end` каналов.
8392
+ *
8393
+ * Работает только в контексте приложения: через вебхук портал ответит `WRONG_AUTH_TYPE`.
8394
+ *
8395
+ * @see https://apidocs.bitrix24.com/settings/interactivity/pull-application-config-get.html
8223
8396
  */
8224
- get() {
8225
- return this.Navvy.simple([$pull, $application, $config, $get], undefined, BXRestMapPullApplicationConfig.get);
8397
+ get(param) {
8398
+ return this.Navvy.simple([$pull, $application, $config, $get], param, BXRestMapPullApplicationConfig.get);
8226
8399
  }
8227
8400
  }
8228
8401
 
8402
+ class BXRestNavvyPullApplicationEvent {
8403
+ constructor() {
8404
+ this.url = {
8405
+ add: [$pull, $application, $event, $add]
8406
+ };
8407
+ this.Navvy = new Navvy();
8408
+ }
8409
+ /**
8410
+ * Отправляет событие в канал приложения: в общий `shared` или, с `USER_ID`, в личные каналы
8411
+ * пользователей. Событие получает клиент Push & Pull, подписанный на эти `MODULE_ID` и `COMMAND`.
8412
+ *
8413
+ * Работает только в контексте приложения: через вебхук портал ответит `WRONG_AUTH_TYPE`.
8414
+ * `true` в ответе значит, что событие принято к отправке, а не что оно дошло до клиента.
8415
+ *
8416
+ * @see https://apidocs.bitrix24.com/settings/interactivity/pull-application-event-add.html
8417
+ */
8418
+ add(param) {
8419
+ return this.Navvy.simple(this.url.add, param);
8420
+ }
8421
+ }
8422
+
8423
+ class BXRestNavvyPullApplicationPush {
8424
+ constructor() {
8425
+ this.url = {
8426
+ add: [$pull, $application, $push, $add]
8427
+ };
8428
+ this.Navvy = new Navvy();
8429
+ }
8430
+ /**
8431
+ * Отправляет push-уведомление пользователям в мобильное приложение Bitrix24 от имени приложения.
8432
+ * У приложения должно быть заполнено название на текущем языке, иначе портал ответит `EMPTY_APP_NAME`.
8433
+ *
8434
+ * Работает только в контексте приложения и только у администратора портала.
8435
+ * `true` в ответе значит, что уведомление принято к отправке, а не что оно дошло.
8436
+ *
8437
+ * @see https://apidocs.bitrix24.com/settings/interactivity/pull-application-push-add.html
8438
+ */
8439
+ add(param) {
8440
+ return this.Navvy.simple(this.url.add, param);
8441
+ }
8442
+ }
8443
+
8444
+ /**
8445
+ * Push & Pull: настройки подключения к серверу и отправка событий приложения.
8446
+ * Клиента веб-сокета в библиотеке нет, подключаться к серверу нужно своим клиентом.
8447
+ */
8229
8448
  class BXRestNavvyPull {
8230
8449
  constructor() {
8231
8450
  /**
@@ -8236,7 +8455,12 @@ class BXRestNavvyPull {
8236
8455
  public: new BXRestNavvyPullChannelPublic()
8237
8456
  };
8238
8457
  this.application = {
8458
+ /** Настройки подключения для приложения (`pull.application.config.*`). */
8239
8459
  config: new BXRestNavvyPullApplicationConfig(),
8460
+ /** События в канал приложения (`pull.application.event.*`). */
8461
+ event: new BXRestNavvyPullApplicationEvent(),
8462
+ /** Push-уведомления в мобильное приложение (`pull.application.push.*`). */
8463
+ push: new BXRestNavvyPullApplicationPush(),
8240
8464
  };
8241
8465
  }
8242
8466
  }
@@ -9033,7 +9257,7 @@ class BXRestNavvyCrmDealRecurring {
9033
9257
  /**
9034
9258
  * Возвращает список шаблонов регулярных сделок.
9035
9259
  */
9036
- list(param = {}) { return this.Navvy.simple([$crm, $deal, $recurring, $list], param); }
9260
+ list(param = {}) { return this.Navvy.pagNav([$crm, $deal, $recurring, $list], param); }
9037
9261
  /**
9038
9262
  * Изменяет настройки шаблона регулярной сделки.
9039
9263
  */
@@ -10892,7 +11116,7 @@ class BXRestNavvyCrmRequisiteLink {
10892
11116
  * @see https://apidocs.bitrix24.ru/api-reference/crm/requisites/links/crm-requisite-link-list.html
10893
11117
  */
10894
11118
  list(param = {}) {
10895
- return this.Navvy.simple(this.url.list, param);
11119
+ return this.Navvy.pagNav(this.url.list, param);
10896
11120
  }
10897
11121
  /**
10898
11122
  * Удаляет связь реквизитов с объектом, не удаляя сами реквизиты.
@@ -11240,7 +11464,7 @@ class BXRestNavvyCrmTimelineBindings {
11240
11464
  * @see https://apidocs.bitrix24.ru/api-reference/crm/timeline/bindings/crm-timeline-bindings-list.html
11241
11465
  */
11242
11466
  list(param) {
11243
- return this.Navvy.simple(this.url.list, param);
11467
+ return this.Navvy.pagNav(this.url.list, param);
11244
11468
  }
11245
11469
  /**
11246
11470
  * Удаляет связь записи таймлайна с указанным элементом CRM.
@@ -11905,7 +12129,7 @@ class BXRestNavvyCrmItemProductRow {
11905
12129
  * Возвращает список товарных позиций.
11906
12130
  */
11907
12131
  list(param) {
11908
- return this.Navvy.simple([$crm, $item, $productrow, $list], param);
12132
+ return this.Navvy.pagNavKeyed([$crm, $item, $productrow, $list], param, 'productRows');
11909
12133
  }
11910
12134
  /**
11911
12135
  * Сохраняет набор товарных позиций объекта CRM.
@@ -12381,7 +12605,7 @@ class BXRestNavvyCrmActivity {
12381
12605
  * Возвращает список дел всех типов по фильтру.
12382
12606
  */
12383
12607
  list(param = {}) {
12384
- return this.Navvy.simple([$crm, $activity, $list], param);
12608
+ return this.Navvy.pagNav([$crm, $activity, $list], param);
12385
12609
  }
12386
12610
  /**
12387
12611
  * Обновляет дело.
@@ -12417,7 +12641,7 @@ class BXRestNavvyCrmOrderEntity {
12417
12641
  * Возвращает список привязок заказов к объектам CRM.
12418
12642
  */
12419
12643
  list(param = {}) {
12420
- return this.Navvy.simple([$crm, $orderentity, $list], param);
12644
+ return this.Navvy.pagNavKeyed([$crm, $orderentity, $list], param, 'orderEntity');
12421
12645
  }
12422
12646
  }
12423
12647
 
@@ -12429,7 +12653,7 @@ class BXRestNavvyCrmStageHistory {
12429
12653
  * Возвращает историю движения элемента по стадиям.
12430
12654
  */
12431
12655
  list(param = {}) {
12432
- return this.Navvy.simple([$crm, $stagehistory, $list], param);
12656
+ return this.Navvy.pagNavKeyed([$crm, $stagehistory, $list], param, 'items');
12433
12657
  }
12434
12658
  }
12435
12659
 
@@ -14273,7 +14497,7 @@ class BXRestNavvyDocumentGeneratorDocument {
14273
14497
  * Возвращает список документов.
14274
14498
  */
14275
14499
  list(param = {}) {
14276
- return this.Navvy.simple([$documentgenerator, $document, $list], param);
14500
+ return this.Navvy.pagNavKeyed([$documentgenerator, $document, $list], param, 'documents');
14277
14501
  }
14278
14502
  /**
14279
14503
  * Изменяет существующий документ.
@@ -14309,7 +14533,7 @@ class BXRestNavvyDocumentGeneratorNumerator {
14309
14533
  * Возвращает список нумераторов.
14310
14534
  */
14311
14535
  list(param = {}) {
14312
- return this.Navvy.simple([$documentgenerator, $numerator, $list], param);
14536
+ return this.Navvy.pagNavKeyed([$documentgenerator, $numerator, $list], param, 'numerators');
14313
14537
  }
14314
14538
  /**
14315
14539
  * Изменяет нумератор.
@@ -14387,7 +14611,7 @@ class BXRestNavvyDocumentGeneratorRole {
14387
14611
  * Возвращает список ролей без детального состава прав.
14388
14612
  */
14389
14613
  list(param = {}) {
14390
- return this.Navvy.simple([$documentgenerator, $role, $list], param);
14614
+ return this.Navvy.pagNavKeyed([$documentgenerator, $role, $list], param, 'roles');
14391
14615
  }
14392
14616
  /**
14393
14617
  * Обновляет роль и возвращает актуальные данные.
@@ -14429,7 +14653,7 @@ class BXRestNavvyDocumentGeneratorTemplate {
14429
14653
  * Возвращает список шаблонов документов по фильтру.
14430
14654
  */
14431
14655
  list(param = {}) {
14432
- return this.Navvy.simple([$documentgenerator, $template, $list], param);
14656
+ return this.Navvy.pagNavKeyed([$documentgenerator, $template, $list], param, 'templates');
14433
14657
  }
14434
14658
  /**
14435
14659
  * Обновляет существующий шаблон документа.
@@ -14966,7 +15190,7 @@ class BXRestNavvyBookingV1Resource {
14966
15190
  * Возвращает список ресурсов.
14967
15191
  */
14968
15192
  list(param = {}) {
14969
- return this.Navvy.simple([$booking, $v1, $resource, $list], param);
15193
+ return this.Navvy.pagNavKeyed([$booking, $v1, $resource, $list], param, 'resource');
14970
15194
  }
14971
15195
  /**
14972
15196
  * Обновляет ресурс.
@@ -15002,7 +15226,7 @@ class BXRestNavvyBookingV1ResourceType {
15002
15226
  * Возвращает список типов ресурсов.
15003
15227
  */
15004
15228
  list(param = {}) {
15005
- return this.Navvy.simple([$booking, $v1, $resourcetype, $list], param);
15229
+ return this.Navvy.pagNavKeyed([$booking, $v1, $resourcetype, $list], param, 'resourceType');
15006
15230
  }
15007
15231
  /**
15008
15232
  * Обновляет тип ресурса.
@@ -16383,7 +16607,7 @@ class BXRestNavvyCatalogCatalog {
16383
16607
  * Возвращает список торговых каталогов.
16384
16608
  */
16385
16609
  list(param = {}) {
16386
- return this.Navvy.simple([$catalog, $catalog, $list], param);
16610
+ return this.Navvy.pagNavKeyed([$catalog, $catalog, $list], param, 'catalogs');
16387
16611
  }
16388
16612
  /**
16389
16613
  * Обновляет параметры торгового каталога.
@@ -16419,7 +16643,7 @@ class BXRestNavvyCatalogDocumentElement {
16419
16643
  * Возвращает список товарных позиций документа складского учёта.
16420
16644
  */
16421
16645
  list(param = {}) {
16422
- return this.Navvy.simple([$catalog, $document, $element, $list], param);
16646
+ return this.Navvy.pagNavKeyed([$catalog, $document, $element, $list], param, 'documentElements');
16423
16647
  }
16424
16648
  /**
16425
16649
  * Обновляет товарную позицию документа складского учёта.
@@ -16505,7 +16729,7 @@ class BXRestNavvyCatalogDocument {
16505
16729
  * Возвращает список документов складского учёта.
16506
16730
  */
16507
16731
  list(param = {}) {
16508
- return this.Navvy.simple([$catalog, $document, $list], param);
16732
+ return this.Navvy.pagNavKeyed([$catalog, $document, $list], param, 'documents');
16509
16733
  }
16510
16734
  /**
16511
16735
  * Обновляет документ складского учёта.
@@ -16541,7 +16765,7 @@ class BXRestNavvyCatalogDocumentContractor {
16541
16765
  * Возвращает список поставщиков документов складского учёта.
16542
16766
  */
16543
16767
  list(param = {}) {
16544
- return this.Navvy.simple([$catalog, $documentcontractor, $list], param);
16768
+ return this.Navvy.pagNavKeyed([$catalog, $documentcontractor, $list], param, 'documentContractor');
16545
16769
  }
16546
16770
  }
16547
16771
 
@@ -16585,7 +16809,7 @@ class BXRestNavvyCatalogExtra {
16585
16809
  * Возвращает список наценок.
16586
16810
  */
16587
16811
  list(param = {}) {
16588
- return this.Navvy.simple([$catalog, $extra, $list], param);
16812
+ return this.Navvy.pagNavKeyed([$catalog, $extra, $list], param, 'extras');
16589
16813
  }
16590
16814
  }
16591
16815
 
@@ -16621,7 +16845,7 @@ class BXRestNavvyCatalogMeasure {
16621
16845
  * Возвращает список единиц измерения.
16622
16846
  */
16623
16847
  list(param = {}) {
16624
- return this.Navvy.simple([$catalog, $measure, $list], param);
16848
+ return this.Navvy.pagNavKeyed([$catalog, $measure, $list], param, 'measures');
16625
16849
  }
16626
16850
  /**
16627
16851
  * Обновляет единицу измерения.
@@ -16663,7 +16887,7 @@ class BXRestNavvyCatalogPrice {
16663
16887
  * Возвращает список цен.
16664
16888
  */
16665
16889
  list(param = {}) {
16666
- return this.Navvy.simple([$catalog, $price, $list], param);
16890
+ return this.Navvy.pagNavKeyed([$catalog, $price, $list], param, 'prices');
16667
16891
  }
16668
16892
  /**
16669
16893
  * Устанавливает или изменяет цену товара, создавая запись при её отсутствии.
@@ -16711,7 +16935,7 @@ class BXRestNavvyCatalogPriceType {
16711
16935
  * Возвращает список типов цен.
16712
16936
  */
16713
16937
  list(param = {}) {
16714
- return this.Navvy.simple([$catalog, $priceType, $list], param);
16938
+ return this.Navvy.pagNavKeyed([$catalog, $priceType, $list], param, 'priceTypes');
16715
16939
  }
16716
16940
  /**
16717
16941
  * Обновляет тип цены.
@@ -16747,7 +16971,7 @@ class BXRestNavvyCatalogPriceTypeGroup {
16747
16971
  * Возвращает список привязок типов цен к группам покупателей.
16748
16972
  */
16749
16973
  list(param = {}) {
16750
- return this.Navvy.simple([$catalog, $priceTypeGroup, $list], param);
16974
+ return this.Navvy.pagNavKeyed([$catalog, $priceTypeGroup, $list], param, 'priceTypeGroups');
16751
16975
  }
16752
16976
  }
16753
16977
 
@@ -16789,7 +17013,7 @@ class BXRestNavvyCatalogPriceTypeLang {
16789
17013
  * Возвращает список переводов названий типов цен.
16790
17014
  */
16791
17015
  list(param = {}) {
16792
- return this.Navvy.simple([$catalog, $priceTypeLang, $list], param);
17016
+ return this.Navvy.pagNavKeyed([$catalog, $priceTypeLang, $list], param, 'priceTypeLangs');
16793
17017
  }
16794
17018
  /**
16795
17019
  * Обновляет перевод названия типа цены.
@@ -16839,7 +17063,7 @@ class BXRestNavvyCatalogProductOffer {
16839
17063
  * Возвращает список товаров-вариаций.
16840
17064
  */
16841
17065
  list(param = {}) {
16842
- return this.Navvy.simple([$catalog, $product, $offer, $list], param);
17066
+ return this.Navvy.pagNavKeyed([$catalog, $product, $offer, $list], param, 'offers');
16843
17067
  }
16844
17068
  /**
16845
17069
  * Обновляет товар-вариацию.
@@ -16889,7 +17113,7 @@ class BXRestNavvyCatalogProductService {
16889
17113
  * Возвращает список услуг.
16890
17114
  */
16891
17115
  list(param = {}) {
16892
- return this.Navvy.simple([$catalog, $product, $service, $list], param);
17116
+ return this.Navvy.pagNavKeyed([$catalog, $product, $service, $list], param, 'services');
16893
17117
  }
16894
17118
  /**
16895
17119
  * Обновляет услугу.
@@ -16939,7 +17163,7 @@ class BXRestNavvyCatalogProductSku {
16939
17163
  * Возвращает список товаров с вариациями.
16940
17164
  */
16941
17165
  list(param = {}) {
16942
- return this.Navvy.simple([$catalog, $product, $sku, $list], param);
17166
+ return this.Navvy.pagNavKeyed([$catalog, $product, $sku, $list], param, 'units');
16943
17167
  }
16944
17168
  /**
16945
17169
  * Обновляет товар с вариациями.
@@ -16999,7 +17223,7 @@ class BXRestNavvyCatalogProduct {
16999
17223
  * Возвращает список товаров.
17000
17224
  */
17001
17225
  list(param = {}) {
17002
- return this.Navvy.simple([$catalog, $product, $list], param);
17226
+ return this.Navvy.pagNavKeyed([$catalog, $product, $list], param, 'products');
17003
17227
  }
17004
17228
  /**
17005
17229
  * Обновляет товар.
@@ -17077,7 +17301,7 @@ class BXRestNavvyCatalogProductProperty {
17077
17301
  * Возвращает список свойств товаров.
17078
17302
  */
17079
17303
  list(param = {}) {
17080
- return this.Navvy.simple([$catalog, $productProperty, $list], param);
17304
+ return this.Navvy.pagNavKeyed([$catalog, $productProperty, $list], param, 'productProperties');
17081
17305
  }
17082
17306
  /**
17083
17307
  * Обновляет свойство товара.
@@ -17119,7 +17343,7 @@ class BXRestNavvyCatalogProductPropertyEnum {
17119
17343
  * Возвращает список значений списочного свойства.
17120
17344
  */
17121
17345
  list(param = {}) {
17122
- return this.Navvy.simple([$catalog, $productPropertyEnum, $list], param);
17346
+ return this.Navvy.pagNavKeyed([$catalog, $productPropertyEnum, $list], param, 'productPropertyEnums');
17123
17347
  }
17124
17348
  /**
17125
17349
  * Обновляет значение списочного свойства товара.
@@ -17163,7 +17387,7 @@ class BXRestNavvyCatalogProductPropertyFeature {
17163
17387
  * Возвращает список параметров свойств товаров.
17164
17388
  */
17165
17389
  list(param = {}) {
17166
- return this.Navvy.simple([$catalog, $productPropertyFeature, $list], param);
17390
+ return this.Navvy.pagNavKeyed([$catalog, $productPropertyFeature, $list], param, 'productPropertyFeatures');
17167
17391
  }
17168
17392
  /**
17169
17393
  * Обновляет параметр свойства товара.
@@ -17187,7 +17411,7 @@ class BXRestNavvyCatalogProductPropertySection {
17187
17411
  * Возвращает список секционных настроек свойств.
17188
17412
  */
17189
17413
  list(param = {}) {
17190
- return this.Navvy.simple([$catalog, $productPropertySection, $list], param);
17414
+ return this.Navvy.pagNavKeyed([$catalog, $productPropertySection, $list], param, 'productPropertySections');
17191
17415
  }
17192
17416
  /**
17193
17417
  * Устанавливает секционные настройки свойства.
@@ -17217,7 +17441,7 @@ class BXRestNavvyCatalogRatio {
17217
17441
  * Возвращает список коэффициентов единиц измерения.
17218
17442
  */
17219
17443
  list(param = {}) {
17220
- return this.Navvy.simple([$catalog, $ratio, $list], param);
17444
+ return this.Navvy.pagNavKeyed([$catalog, $ratio, $list], param, 'ratios');
17221
17445
  }
17222
17446
  }
17223
17447
 
@@ -17253,7 +17477,7 @@ class BXRestNavvyCatalogRoundingRule {
17253
17477
  * Возвращает список правил округления цен.
17254
17478
  */
17255
17479
  list(param = {}) {
17256
- return this.Navvy.simple([$catalog, $roundingRule, $list], param);
17480
+ return this.Navvy.pagNavKeyed([$catalog, $roundingRule, $list], param, 'roundingRules');
17257
17481
  }
17258
17482
  /**
17259
17483
  * Обновляет правило округления цен.
@@ -17295,7 +17519,7 @@ class BXRestNavvyCatalogSection {
17295
17519
  * Возвращает список разделов каталога.
17296
17520
  */
17297
17521
  list(param = {}) {
17298
- return this.Navvy.simple([$catalog, $section, $list], param);
17522
+ return this.Navvy.pagNavKeyed([$catalog, $section, $list], param, 'sections');
17299
17523
  }
17300
17524
  /**
17301
17525
  * Обновляет раздел каталога.
@@ -17337,7 +17561,7 @@ class BXRestNavvyCatalogStore {
17337
17561
  * Возвращает список складов.
17338
17562
  */
17339
17563
  list(param = {}) {
17340
- return this.Navvy.simple([$catalog, $store, $list], param);
17564
+ return this.Navvy.pagNavKeyed([$catalog, $store, $list], param, 'stores');
17341
17565
  }
17342
17566
  /**
17343
17567
  * Обновляет склад.
@@ -17367,7 +17591,7 @@ class BXRestNavvyCatalogStoreProduct {
17367
17591
  * Возвращает список остатков товаров на складах.
17368
17592
  */
17369
17593
  list(param = {}) {
17370
- return this.Navvy.simple([$catalog, $storeProduct, $list], param);
17594
+ return this.Navvy.pagNavKeyed([$catalog, $storeProduct, $list], param, 'storeProducts');
17371
17595
  }
17372
17596
  }
17373
17597
 
@@ -17379,7 +17603,7 @@ class BXRestNavvyCatalogUserfieldDocument {
17379
17603
  * Возвращает список пользовательских полей документов складского учёта.
17380
17604
  */
17381
17605
  list(param = {}) {
17382
- return this.Navvy.simple([$catalog, $userfield, $document, $list], param);
17606
+ return this.Navvy.pagNavKeyed([$catalog, $userfield, $document, $list], param, 'documents');
17383
17607
  }
17384
17608
  /**
17385
17609
  * Обновляет пользовательское поле документа складского учёта.
@@ -17430,7 +17654,7 @@ class BXRestNavvyCatalogVat {
17430
17654
  * Возвращает список ставок НДС.
17431
17655
  */
17432
17656
  list(param = {}) {
17433
- return this.Navvy.simple([$catalog, $vat, $list], param);
17657
+ return this.Navvy.pagNavKeyed([$catalog, $vat, $list], param, 'vats');
17434
17658
  }
17435
17659
  /**
17436
17660
  * Обновляет ставку НДС.
@@ -17583,7 +17807,7 @@ class BXRestNavvySaleBasketItem {
17583
17807
  * Возвращает список элементов корзины.
17584
17808
  */
17585
17809
  list(param = {}) {
17586
- return this.Navvy.simple([$sale, $basketItem, $list], param);
17810
+ return this.Navvy.pagNavKeyed([$sale, $basketItem, $list], param, 'basketItems');
17587
17811
  }
17588
17812
  /**
17589
17813
  * Обновляет элемент корзины.
@@ -17633,7 +17857,7 @@ class BXRestNavvySaleBasketProperties {
17633
17857
  * Возвращает список свойств элементов корзины.
17634
17858
  */
17635
17859
  list(param = {}) {
17636
- return this.Navvy.simple([$sale, $basketProperties, $list], param);
17860
+ return this.Navvy.pagNavKeyed([$sale, $basketProperties, $list], param, 'basketProperties');
17637
17861
  }
17638
17862
  /**
17639
17863
  * Обновляет свойство элемента корзины.
@@ -17671,7 +17895,7 @@ class BXRestNavvySaleBusinessValuePersonDomain {
17671
17895
  * Возвращает список соответствий типов плательщиков.
17672
17896
  */
17673
17897
  list(param = {}) {
17674
- return this.Navvy.simple([$sale, $businessValuePersonDomain, $list], param);
17898
+ return this.Navvy.pagNavKeyed([$sale, $businessValuePersonDomain, $list], param, 'businessValuePersonDomains');
17675
17899
  }
17676
17900
  }
17677
17901
 
@@ -17944,7 +18168,7 @@ class BXRestNavvySaleOrder {
17944
18168
  * Возвращает список заказов.
17945
18169
  */
17946
18170
  list(param = {}) {
17947
- return this.Navvy.simple([$sale, $order, $list], param);
18171
+ return this.Navvy.pagNavKeyed([$sale, $order, $list], param, 'orders');
17948
18172
  }
17949
18173
  /**
17950
18174
  * Обновляет заказ.
@@ -17986,7 +18210,7 @@ class BXRestNavvySalePayment {
17986
18210
  * Возвращает список оплат.
17987
18211
  */
17988
18212
  list(param = {}) {
17989
- return this.Navvy.simple([$sale, $payment, $list], param);
18213
+ return this.Navvy.pagNavKeyed([$sale, $payment, $list], param, 'payments');
17990
18214
  }
17991
18215
  /**
17992
18216
  * Обновляет оплату.
@@ -18028,7 +18252,7 @@ class BXRestNavvySalePaymentItemBasket {
18028
18252
  * Возвращает список привязок элементов корзины к оплатам.
18029
18253
  */
18030
18254
  list(param = {}) {
18031
- return this.Navvy.simple([$sale, $paymentItemBasket, $list], param);
18255
+ return this.Navvy.pagNavKeyed([$sale, $paymentItemBasket, $list], param, 'paymentItemsBasket');
18032
18256
  }
18033
18257
  /**
18034
18258
  * Обновляет привязку элемента корзины к оплате.
@@ -18070,7 +18294,7 @@ class BXRestNavvySalePaymentItemShipment {
18070
18294
  * Возвращает список привязок оплат к отгрузкам.
18071
18295
  */
18072
18296
  list(param = {}) {
18073
- return this.Navvy.simple([$sale, $paymentItemShipment, $list], param);
18297
+ return this.Navvy.pagNavKeyed([$sale, $paymentItemShipment, $list], param, 'paymentItemsShipment');
18074
18298
  }
18075
18299
  /**
18076
18300
  * Обновляет привязку оплаты к отгрузке.
@@ -18230,7 +18454,7 @@ class BXRestNavvySalePersonType {
18230
18454
  * Возвращает список типов плательщиков.
18231
18455
  */
18232
18456
  list(param = {}) {
18233
- return this.Navvy.simple([$sale, $personType, $list], param);
18457
+ return this.Navvy.pagNavKeyed([$sale, $personType, $list], param, 'personTypes');
18234
18458
  }
18235
18459
  /**
18236
18460
  * Обновляет тип плательщика.
@@ -18272,7 +18496,7 @@ class BXRestNavvySaleProperty {
18272
18496
  * Возвращает список свойств заказа.
18273
18497
  */
18274
18498
  list(param = {}) {
18275
- return this.Navvy.simple([$sale, $property, $list], param);
18499
+ return this.Navvy.pagNavKeyed([$sale, $property, $list], param, 'properties');
18276
18500
  }
18277
18501
  /**
18278
18502
  * Обновляет свойство заказа.
@@ -18350,7 +18574,7 @@ class BXRestNavvySalePropertyRelation {
18350
18574
  * Возвращает список привязок свойств заказа.
18351
18575
  */
18352
18576
  list(param = {}) {
18353
- return this.Navvy.simple([$sale, $propertyRelation, $list], param);
18577
+ return this.Navvy.pagNavKeyed([$sale, $propertyRelation, $list], param, 'propertyRelations');
18354
18578
  }
18355
18579
  }
18356
18580
 
@@ -18380,7 +18604,7 @@ class BXRestNavvySalePropertyValue {
18380
18604
  * Возвращает список значений свойств заказа.
18381
18605
  */
18382
18606
  list(param = {}) {
18383
- return this.Navvy.simple([$sale, $propertyValue, $list], param);
18607
+ return this.Navvy.pagNavKeyed([$sale, $propertyValue, $list], param, 'propertyValues');
18384
18608
  }
18385
18609
  /**
18386
18610
  * Устанавливает или изменяет значение свойства заказа.
@@ -18422,7 +18646,7 @@ class BXRestNavvySalePropertyVariant {
18422
18646
  * Возвращает список значений списочного свойства заказа.
18423
18647
  */
18424
18648
  list(param = {}) {
18425
- return this.Navvy.simple([$sale, $propertyVariant, $list], param);
18649
+ return this.Navvy.pagNavKeyed([$sale, $propertyVariant, $list], param, 'propertyVariants');
18426
18650
  }
18427
18651
  /**
18428
18652
  * Обновляет значение списочного свойства заказа.
@@ -18464,7 +18688,7 @@ class BXRestNavvySaleShipment {
18464
18688
  * Возвращает список отгрузок.
18465
18689
  */
18466
18690
  list(param = {}) {
18467
- return this.Navvy.simple([$sale, $shipment, $list], param);
18691
+ return this.Navvy.pagNavKeyed([$sale, $shipment, $list], param, 'shipments');
18468
18692
  }
18469
18693
  /**
18470
18694
  * Обновляет отгрузку.
@@ -18506,7 +18730,7 @@ class BXRestNavvySaleShipmentItem {
18506
18730
  * Возвращает список товарных позиций отгрузки.
18507
18731
  */
18508
18732
  list(param = {}) {
18509
- return this.Navvy.simple([$sale, $shipmentItem, $list], param);
18733
+ return this.Navvy.pagNavKeyed([$sale, $shipmentItem, $list], param, 'shipmentItems');
18510
18734
  }
18511
18735
  /**
18512
18736
  * Обновляет товарную позицию отгрузки.
@@ -18548,7 +18772,7 @@ class BXRestNavvySaleShipmentProperty {
18548
18772
  * Возвращает список свойств отгрузки.
18549
18773
  */
18550
18774
  list(param = {}) {
18551
- return this.Navvy.simple([$sale, $shipmentProperty, $list], param);
18775
+ return this.Navvy.pagNavKeyed([$sale, $shipmentProperty, $list], param, 'properties');
18552
18776
  }
18553
18777
  /**
18554
18778
  * Обновляет свойство отгрузки.
@@ -18584,7 +18808,7 @@ class BXRestNavvySaleShipmentPropertyValue {
18584
18808
  * Возвращает список значений свойств отгрузки.
18585
18809
  */
18586
18810
  list(param = {}) {
18587
- return this.Navvy.simple([$sale, $shipmentPropertyValue, $list], param);
18811
+ return this.Navvy.pagNavKeyed([$sale, $shipmentPropertyValue, $list], param, 'propertyValues');
18588
18812
  }
18589
18813
  /**
18590
18814
  * Устанавливает или изменяет значение свойства отгрузки.
@@ -18626,7 +18850,7 @@ class BXRestNavvySaleStatus {
18626
18850
  * Возвращает список статусов.
18627
18851
  */
18628
18852
  list(param = {}) {
18629
- return this.Navvy.simple([$sale, $status, $list], param);
18853
+ return this.Navvy.pagNavKeyed([$sale, $status, $list], param, 'statuses');
18630
18854
  }
18631
18855
  /**
18632
18856
  * Обновляет статус.
@@ -18668,7 +18892,7 @@ class BXRestNavvySaleStatusLang {
18668
18892
  * Возвращает список локализаций статусов.
18669
18893
  */
18670
18894
  list(param = {}) {
18671
- return this.Navvy.simple([$sale, $statusLang, $list], param);
18895
+ return this.Navvy.pagNavKeyed([$sale, $statusLang, $list], param, 'statusLangs');
18672
18896
  }
18673
18897
  }
18674
18898
 
@@ -18686,7 +18910,7 @@ class BXRestNavvySaleTradeBinding {
18686
18910
  * Возвращает список привязок источников заказов.
18687
18911
  */
18688
18912
  list(param = {}) {
18689
- return this.Navvy.simple([$sale, $tradeBinding, $list], param);
18913
+ return this.Navvy.pagNavKeyed([$sale, $tradeBinding, $list], param, 'tradeBindings');
18690
18914
  }
18691
18915
  }
18692
18916
 
@@ -18704,7 +18928,7 @@ class BXRestNavvySaleTradePlatform {
18704
18928
  * Возвращает список источников заказов.
18705
18929
  */
18706
18930
  list(param = {}) {
18707
- return this.Navvy.simple([$sale, $tradePlatform, $list], param);
18931
+ return this.Navvy.pagNavKeyed([$sale, $tradePlatform, $list], param, 'tradePlatforms');
18708
18932
  }
18709
18933
  }
18710
18934
 
@@ -18998,7 +19222,7 @@ class BXRestNavvyUserFieldType {
18998
19222
  * Возвращает список типов пользовательских полей, зарегистрированных приложением.
18999
19223
  */
19000
19224
  list(param = {}) {
19001
- return this.Navvy.simple([$userfieldtype, $list], param);
19225
+ return this.Navvy.pagNav([$userfieldtype, $list], param);
19002
19226
  }
19003
19227
  /**
19004
19228
  * Изменяет настройки зарегистрированного приложением типа пользовательских полей.
@@ -19009,69 +19233,70 @@ class BXRestNavvyUserFieldType {
19009
19233
  }
19010
19234
 
19011
19235
  class BXRestNavvy {
19012
- constructor() {
19013
- this.ai = new BXRestNavvyAi();
19014
- this.mailService = new BXRestNavvyMailService();
19015
- this.messageService = new BXRestNavvyMessageService();
19016
- this.userConsent = new BXRestNavvyUserConsent();
19017
- this.telephony = new BXRestNavvyTelephony();
19018
- this.vote = new BXRestNavvyVote();
19019
- this.imConnector = new BXRestNavvyImConnector();
19020
- this.entity = new BXRestNavvyEntity();
19021
- this.biConnector = new BXRestNavvyBiConnector();
19022
- this.voxImplant = new BXRestNavvyVoxImplant();
19023
- this.mail = new BXRestNavvyMail();
19024
- this.note = new BXRestNavvyNote();
19025
- this.documentGenerator = new BXRestNavvyDocumentGenerator();
19026
- this.imBot = new BXRestNavvyImBot();
19027
- this.booking = new BXRestNavvyBooking();
19028
- this.imOpenLines = new BXRestNavvyImOpenLines();
19029
- this.landing = new BXRestNavvyLanding();
19030
- this.catalog = new BXRestNavvyCatalog();
19031
- this.sale = new BXRestNavvySale();
19032
- this.sign = new BXRestNavvySign();
19033
- this.eventLog = new BXRestNavvyEventLog();
19034
- this.placement = new BXRestNavvyPlacement();
19035
- this.userFieldType = new BXRestNavvyUserFieldType();
19036
- this.user = new BXRestNavvyUser();
19037
- this.lists = new BXRestNavvyLists();
19038
- this.task = new BXRestNavvyTask();
19039
- this.tasks = new BXRestNavvyTasks();
19040
- this.disk = new BXRestNavvyDisk();
19041
- this.bizProc = new BXRestNavvyBizProc();
19042
- this.log = new BXRestNavvyLog();
19043
- this.calendar = new BXRestNavvyCalendar();
19044
- this.sonet_group = new BXRestNavvySonetGroup();
19045
- this.server = new BXRestNavvyServer();
19046
- this.department = new BXRestNavvyDepartment();
19047
- this.im = new BXRestNavvyIm();
19048
- this.app = new BXRestNavvyApp();
19049
- this.timeMan = new BXRestNavvyTimeMan();
19050
- this.socialNetWork = new BXRestNavvySocialNetWork();
19051
- this.pull = new BXRestNavvyPull();
19052
- this.crm = new BXRestNavvyCrm();
19053
- /** Регистрация обработчиков и работа с онлайн- и офлайн-событиями. */
19054
- this.event = new BXRestNavvyEvent();
19055
- /** Проверка существования и доступности REST-методов. */
19056
- this.method = new BXRestNavvyMethod();
19057
- /** Получение описаний кодов доступа. */
19058
- this.access = new BXRestNavvyAccess();
19059
- /** Проверка доступности возможностей портала. */
19060
- this.feature = new BXRestNavvyFeature();
19061
- this.Navvy = new Navvy();
19062
- // public batch<T, C, M>(param: iBXRestNavvyParamBatch<T, C, M>) {
19063
- // const modifiedObject = Object.fromEntries(
19064
- // Object.entries(param.cmd).map(([key, value]) => {
19065
- // let modifiedValue = value.resultVanilla.arguments
19066
- // return [key, modifiedValue]
19067
- // })
19068
- // )
19069
- //
19070
- // return this.BXRest.batch({
19071
- // halt: param.halt,
19072
- // cmd: modifiedObject
19073
- // })
19074
- // }
19236
+ /**
19237
+ * @param settings Свои настройки клиента: адрес портала, способ авторизации,
19238
+ * заголовки. Все запросы этого клиента идут с ними, даже если глобальные
19239
+ * `BXRestSettings` позже изменятся. Так в одном процессе можно работать
19240
+ * с несколькими порталами. Без аргумента клиент работает с глобальными
19241
+ * `BXRestSettings`, как раньше.
19242
+ */
19243
+ constructor(settings) {
19244
+ // Каждый HTTP-объект запоминает контекст в момент создания, поэтому все
19245
+ // разделы создаются, пока включён контекст клиента. Создание идёт в теле
19246
+ // конструктора, а не в инициализаторах полей: только так finally вернёт
19247
+ // прежний контекст, даже если какой-то раздел бросит исключение. Иначе
19248
+ // объекты, созданные приложением позже, ушли бы на портал этого клиента.
19249
+ const previous = enterContext(settings ? new BXRestContext(settings) : globalContext);
19250
+ try {
19251
+ this.ai = new BXRestNavvyAi();
19252
+ this.mailService = new BXRestNavvyMailService();
19253
+ this.messageService = new BXRestNavvyMessageService();
19254
+ this.userConsent = new BXRestNavvyUserConsent();
19255
+ this.telephony = new BXRestNavvyTelephony();
19256
+ this.vote = new BXRestNavvyVote();
19257
+ this.imConnector = new BXRestNavvyImConnector();
19258
+ this.entity = new BXRestNavvyEntity();
19259
+ this.biConnector = new BXRestNavvyBiConnector();
19260
+ this.voxImplant = new BXRestNavvyVoxImplant();
19261
+ this.mail = new BXRestNavvyMail();
19262
+ this.note = new BXRestNavvyNote();
19263
+ this.documentGenerator = new BXRestNavvyDocumentGenerator();
19264
+ this.imBot = new BXRestNavvyImBot();
19265
+ this.booking = new BXRestNavvyBooking();
19266
+ this.imOpenLines = new BXRestNavvyImOpenLines();
19267
+ this.landing = new BXRestNavvyLanding();
19268
+ this.catalog = new BXRestNavvyCatalog();
19269
+ this.sale = new BXRestNavvySale();
19270
+ this.sign = new BXRestNavvySign();
19271
+ this.eventLog = new BXRestNavvyEventLog();
19272
+ this.placement = new BXRestNavvyPlacement();
19273
+ this.userFieldType = new BXRestNavvyUserFieldType();
19274
+ this.user = new BXRestNavvyUser();
19275
+ this.lists = new BXRestNavvyLists();
19276
+ this.task = new BXRestNavvyTask();
19277
+ this.tasks = new BXRestNavvyTasks();
19278
+ this.disk = new BXRestNavvyDisk();
19279
+ this.bizProc = new BXRestNavvyBizProc();
19280
+ this.log = new BXRestNavvyLog();
19281
+ this.calendar = new BXRestNavvyCalendar();
19282
+ this.sonet_group = new BXRestNavvySonetGroup();
19283
+ this.server = new BXRestNavvyServer();
19284
+ this.department = new BXRestNavvyDepartment();
19285
+ this.im = new BXRestNavvyIm();
19286
+ this.app = new BXRestNavvyApp();
19287
+ this.timeMan = new BXRestNavvyTimeMan();
19288
+ this.socialNetWork = new BXRestNavvySocialNetWork();
19289
+ this.pull = new BXRestNavvyPull();
19290
+ this.crm = new BXRestNavvyCrm();
19291
+ this.event = new BXRestNavvyEvent();
19292
+ this.method = new BXRestNavvyMethod();
19293
+ this.access = new BXRestNavvyAccess();
19294
+ this.feature = new BXRestNavvyFeature();
19295
+ this.Navvy = new Navvy();
19296
+ }
19297
+ finally {
19298
+ restoreContext(previous);
19299
+ }
19075
19300
  }
19076
19301
  /**
19077
19302
  * Возвращает базовую информацию о текущем пользователе без scope `user`.
@@ -19757,19 +19982,6 @@ function toRecord(value) {
19757
19982
  : {};
19758
19983
  }
19759
19984
 
19760
- class HttpNavvyServices {
19761
- constructor() {
19762
- this.httpServices = new HttpBXServices();
19763
- }
19764
- // Реализация метода
19765
- post(url, params) {
19766
- if (params === undefined) {
19767
- params = {};
19768
- }
19769
- return this.httpServices.post(url, params);
19770
- }
19771
- }
19772
-
19773
19985
  /**
19774
19986
  * Public API Surface of bx-rest
19775
19987
  */
@@ -19778,5 +19990,5 @@ class HttpNavvyServices {
19778
19990
  * Generated bundle index. Do not edit.
19779
19991
  */
19780
19992
 
19781
- export { base as BXBaseServices, BXRestApiError, BXRestFrame, BXRestFrameError, BXRestMap, BXRestMapResult, BXRestNavvy, HttpBXServices as BXRestRequest, BXRestSettings, HttpNavvyServices, Navvy, SessionKeyError, SessionKeyServices, getAuthRefreshError, instanceOfiBXRestAnswerSuccess as isBXRestAnswerSuccess, isBXRestAuthError, partNameMethods$1 as partNameMethods };
19993
+ export { base as BXBaseServices, BXRestApiError, BXRestFrame, BXRestFrameError, BXRestHttpError, BXRestMap, BXRestMapResult, BXRestNavvy, HttpBXServices as BXRestRequest, BXRestSettings, BXRestTimeoutError, Navvy, SessionKeyError, SessionKeyServices, getAuthRefreshError, instanceOfiBXRestAnswerSuccess as isBXRestAnswerSuccess, isBXRestAuthError, partNameMethods$1 as partNameMethods };
19782
19994
  //# sourceMappingURL=bx-rest.mjs.map