@wazo/sdk 0.38.22 → 0.39.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (883) hide show
  1. package/README.md +62 -293
  2. package/dist/wazo-sdk.js +9 -25
  3. package/esm/__tests__/api-client.test.js +183 -5059
  4. package/esm/__tests__/web-rtc-client.test.js +177 -7930
  5. package/esm/api/agentd.js +23 -832
  6. package/esm/api/amid.js +9 -411
  7. package/esm/api/application.js +60 -829
  8. package/esm/api/auth.js +164 -1213
  9. package/esm/api/call-logd.js +24 -733
  10. package/esm/api/calld.js +114 -1469
  11. package/esm/api/chatd.js +48 -1311
  12. package/esm/api/confd.js +67 -1580
  13. package/esm/api/ctid-ng.js +92 -1343
  14. package/esm/api/dird.js +100 -1590
  15. package/esm/api/webhookd.js +7 -513
  16. package/esm/api-client.js +143 -4880
  17. package/esm/checker/Checker.js +45 -8727
  18. package/esm/checker/checks/aor.js +24 -4924
  19. package/esm/checker/checks/api.js +70 -4968
  20. package/esm/checker/checks/ice-ipv4.js +63 -117
  21. package/esm/checker/checks/index.js +8 -8677
  22. package/esm/checker/checks/symmetric-nat.js +54 -102
  23. package/esm/checker/checks/wazo-websocket.js +34 -999
  24. package/esm/checker/checks/webrtc-transport.js +28 -7845
  25. package/esm/checker/checks/webrtc.js +31 -7852
  26. package/esm/domain/AdHocAPIConference.js +86 -5115
  27. package/esm/domain/Agent.js +27 -61
  28. package/esm/domain/BadResponse.js +20 -43
  29. package/esm/domain/Call.js +120 -210
  30. package/esm/domain/CallLog.js +123 -305
  31. package/esm/domain/CallSession.js +251 -423
  32. package/esm/domain/ChatMessage.js +52 -105
  33. package/esm/domain/ChatRoom.js +28 -60
  34. package/esm/domain/Contact.js +435 -741
  35. package/esm/domain/Country.js +17 -19
  36. package/esm/domain/Device/DebugDevice.js +31 -47
  37. package/esm/domain/Device/Device.js +1 -1
  38. package/esm/domain/DirectorySource.js +1 -1
  39. package/esm/domain/ExternalApp.js +23 -56
  40. package/esm/domain/Features.js +57 -5009
  41. package/esm/domain/ForwardOption.js +35 -70
  42. package/esm/domain/IndirectTransfer.js +38 -97
  43. package/esm/domain/Line.js +37 -88
  44. package/esm/domain/Meeting.js +58 -113
  45. package/esm/domain/MeetingAuthorization.js +38 -68
  46. package/esm/domain/MeetingStatus.js +13 -28
  47. package/esm/domain/NotificationOptions.js +43 -77
  48. package/esm/domain/Phone/CTIPhone.js +245 -5743
  49. package/esm/domain/Phone/Phone.js +1 -2
  50. package/esm/domain/Phone/WebRTCPhone.js +1457 -2671
  51. package/esm/domain/Profile.js +120 -405
  52. package/esm/domain/Recording.js +27 -51
  53. package/esm/domain/Relocation.js +16 -40
  54. package/esm/domain/Room.js +90 -133
  55. package/esm/domain/SFUNotAvailableError.js +5 -8
  56. package/esm/domain/ServerError.js +8 -61
  57. package/esm/domain/Session.js +125 -251
  58. package/esm/domain/SipLine.js +78 -155
  59. package/esm/domain/Subscription.js +39 -83
  60. package/esm/domain/SwitchboardCall.js +51 -143
  61. package/esm/domain/Voicemail.js +57 -122
  62. package/esm/domain/__tests__/Agent.test.js +31 -101
  63. package/esm/domain/__tests__/Call.test.js +24 -232
  64. package/esm/domain/__tests__/CallLog.test.js +60 -386
  65. package/esm/domain/__tests__/CallSession.test.js +74 -502
  66. package/esm/domain/__tests__/Contact.test.js +220 -902
  67. package/esm/domain/__tests__/IndirectTransfer.test.js +63 -546
  68. package/esm/domain/__tests__/Line.test.js +48 -156
  69. package/esm/domain/__tests__/Meeting.test.js +73 -226
  70. package/esm/domain/__tests__/MeetingAuthorization.test.js +45 -105
  71. package/esm/domain/__tests__/Profile.test.js +135 -496
  72. package/esm/domain/__tests__/Room.test.js +227 -719
  73. package/esm/domain/__tests__/Session.test.js +357 -1025
  74. package/esm/domain/__tests__/SipLine.test.js +24 -179
  75. package/esm/domain/__tests__/Voicemail.test.js +82 -200
  76. package/esm/domain/types.js +1 -1
  77. package/esm/index.js +63 -14985
  78. package/esm/lib/WazoSessionDescriptionHandler.js +406 -890
  79. package/esm/pubkey.js +10 -0
  80. package/esm/service/CallApi.js +42 -5014
  81. package/esm/service/IssueReporter.js +278 -360
  82. package/esm/service/__tests__/IssueReporter.test.js +92 -494
  83. package/esm/service/getApiClient.js +53 -4972
  84. package/esm/simple/Auth.js +212 -14747
  85. package/esm/simple/Configuration.js +8 -14796
  86. package/esm/simple/Directory.js +6 -4964
  87. package/esm/simple/Phone.js +309 -14727
  88. package/esm/simple/Websocket.js +68 -1112
  89. package/esm/simple/index.js +125 -14792
  90. package/esm/simple/room/LocalParticipant.js +1 -14797
  91. package/esm/simple/room/Participant.js +274 -14760
  92. package/esm/simple/room/RemoteParticipant.js +6 -14796
  93. package/esm/simple/room/Room.js +648 -14736
  94. package/esm/simple/room/SipRoom.js +111 -14790
  95. package/esm/simple/room/Stream.js +40 -14792
  96. package/esm/simple/room/__tests__/Participant.test.js +68 -14872
  97. package/esm/simple/room/__tests__/RemoteParticipant.test.js +10 -14805
  98. package/esm/simple/utils.js +9 -14799
  99. package/esm/types/WebSocketMessage.js +1 -1
  100. package/esm/types/__tests__/api-client.test.d.ts +2 -0
  101. package/esm/types/__tests__/api-client.test.d.ts.map +1 -0
  102. package/esm/types/__tests__/web-rtc-client.test.d.ts +2 -0
  103. package/esm/types/__tests__/web-rtc-client.test.d.ts.map +1 -0
  104. package/esm/types/api/agentd.d.ts +17 -0
  105. package/esm/types/api/agentd.d.ts.map +1 -0
  106. package/esm/types/api/amid.d.ts +8 -0
  107. package/esm/types/api/amid.d.ts.map +1 -0
  108. package/esm/types/api/application.d.ts +34 -0
  109. package/esm/types/api/application.d.ts.map +1 -0
  110. package/esm/types/api/auth.d.ts +64 -0
  111. package/esm/types/api/auth.d.ts.map +1 -0
  112. package/esm/types/api/call-logd.d.ts +12 -0
  113. package/esm/types/api/call-logd.d.ts.map +1 -0
  114. package/esm/types/api/calld.d.ts +51 -0
  115. package/esm/types/api/calld.d.ts.map +1 -0
  116. package/esm/types/api/chatd.d.ts +42 -0
  117. package/esm/types/api/chatd.d.ts.map +1 -0
  118. package/esm/types/api/confd.d.ts +39 -0
  119. package/esm/types/api/confd.d.ts.map +1 -0
  120. package/esm/types/api/ctid-ng.d.ts +36 -0
  121. package/esm/types/api/ctid-ng.d.ts.map +1 -0
  122. package/esm/types/api/dird.d.ts +38 -0
  123. package/esm/types/api/dird.d.ts.map +1 -0
  124. package/esm/types/api/webhookd.d.ts +24 -0
  125. package/esm/types/api/webhookd.d.ts.map +1 -0
  126. package/esm/types/api-client.d.ts +63 -0
  127. package/esm/types/api-client.d.ts.map +1 -0
  128. package/esm/types/checker/Checker.d.ts +13 -0
  129. package/esm/types/checker/Checker.d.ts.map +1 -0
  130. package/esm/types/checker/checks/aor.d.ts +6 -0
  131. package/esm/types/checker/checks/aor.d.ts.map +1 -0
  132. package/esm/types/checker/checks/api.d.ts +6 -0
  133. package/esm/types/checker/checks/api.d.ts.map +1 -0
  134. package/esm/types/checker/checks/ice-ipv4.d.ts +6 -0
  135. package/esm/types/checker/checks/ice-ipv4.d.ts.map +1 -0
  136. package/esm/types/checker/checks/index.d.ts +9 -0
  137. package/esm/types/checker/checks/index.d.ts.map +1 -0
  138. package/esm/types/checker/checks/symmetric-nat.d.ts +6 -0
  139. package/esm/types/checker/checks/symmetric-nat.d.ts.map +1 -0
  140. package/esm/types/checker/checks/wazo-websocket.d.ts +6 -0
  141. package/esm/types/checker/checks/wazo-websocket.d.ts.map +1 -0
  142. package/esm/types/checker/checks/webrtc-transport.d.ts +7 -0
  143. package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -0
  144. package/esm/types/checker/checks/webrtc.d.ts +6 -0
  145. package/esm/types/checker/checks/webrtc.d.ts.map +1 -0
  146. package/esm/types/domain/AdHocAPIConference.d.ts +54 -0
  147. package/esm/types/domain/AdHocAPIConference.d.ts.map +1 -0
  148. package/esm/types/domain/Agent.d.ts +31 -0
  149. package/esm/types/domain/Agent.d.ts.map +1 -0
  150. package/esm/types/domain/BadResponse.d.ts +11 -0
  151. package/esm/types/domain/BadResponse.d.ts.map +1 -0
  152. package/esm/types/domain/Call.d.ts +79 -0
  153. package/esm/types/domain/Call.d.ts.map +1 -0
  154. package/esm/types/domain/CallLog.d.ts +91 -0
  155. package/esm/types/domain/CallLog.d.ts.map +1 -0
  156. package/esm/types/domain/CallSession.d.ts +120 -0
  157. package/esm/types/domain/CallSession.d.ts.map +1 -0
  158. package/esm/types/domain/ChatMessage.d.ts +41 -0
  159. package/esm/types/domain/ChatMessage.d.ts.map +1 -0
  160. package/esm/types/domain/ChatRoom.d.ts +22 -0
  161. package/esm/types/domain/ChatRoom.d.ts.map +1 -0
  162. package/esm/types/domain/Contact.d.ts +316 -0
  163. package/esm/types/domain/Contact.d.ts.map +1 -0
  164. package/esm/types/domain/Country.d.ts +20 -0
  165. package/esm/types/domain/Country.d.ts.map +1 -0
  166. package/esm/types/domain/Device/DebugDevice.d.ts +14 -0
  167. package/esm/types/domain/Device/DebugDevice.d.ts.map +1 -0
  168. package/esm/types/domain/Device/Device.d.ts +13 -0
  169. package/esm/types/domain/Device/Device.d.ts.map +1 -0
  170. package/esm/types/domain/DirectorySource.d.ts +13 -0
  171. package/esm/types/domain/DirectorySource.d.ts.map +1 -0
  172. package/esm/types/domain/ExternalApp.d.ts +22 -0
  173. package/esm/types/domain/ExternalApp.d.ts.map +1 -0
  174. package/esm/types/domain/Features.d.ts +24 -0
  175. package/esm/types/domain/Features.d.ts.map +1 -0
  176. package/esm/types/domain/ForwardOption.d.ts +27 -0
  177. package/esm/types/domain/ForwardOption.d.ts.map +1 -0
  178. package/esm/types/domain/IndirectTransfer.d.ts +31 -0
  179. package/esm/types/domain/IndirectTransfer.d.ts.map +1 -0
  180. package/esm/types/domain/Line.d.ts +46 -0
  181. package/esm/types/domain/Line.d.ts.map +1 -0
  182. package/esm/types/domain/Meeting.d.ts +45 -0
  183. package/esm/types/domain/Meeting.d.ts.map +1 -0
  184. package/esm/types/domain/MeetingAuthorization.d.ts +26 -0
  185. package/esm/types/domain/MeetingAuthorization.d.ts.map +1 -0
  186. package/esm/types/domain/MeetingStatus.d.ts +10 -0
  187. package/esm/types/domain/MeetingStatus.d.ts.map +1 -0
  188. package/esm/types/domain/NotificationOptions.d.ts +22 -0
  189. package/esm/types/domain/NotificationOptions.d.ts.map +1 -0
  190. package/esm/types/domain/Phone/CTIPhone.d.ts +76 -0
  191. package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -0
  192. package/esm/types/domain/Phone/Phone.d.ts +71 -0
  193. package/esm/types/domain/Phone/Phone.d.ts.map +1 -0
  194. package/esm/types/domain/Phone/WebRTCPhone.d.ts +179 -0
  195. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -0
  196. package/esm/types/domain/Profile.d.ts +151 -0
  197. package/esm/types/domain/Profile.d.ts.map +1 -0
  198. package/esm/types/domain/Recording.d.ts +26 -0
  199. package/esm/types/domain/Recording.d.ts.map +1 -0
  200. package/esm/types/domain/Relocation.d.ts +23 -0
  201. package/esm/types/domain/Relocation.d.ts.map +1 -0
  202. package/esm/types/domain/Room.d.ts +35 -0
  203. package/esm/types/domain/Room.d.ts.map +1 -0
  204. package/esm/types/domain/SFUNotAvailableError.d.ts +4 -0
  205. package/esm/types/domain/SFUNotAvailableError.d.ts.map +1 -0
  206. package/esm/types/domain/ServerError.d.ts +6 -0
  207. package/esm/types/domain/ServerError.d.ts.map +1 -0
  208. package/esm/types/domain/Session.d.ts +90 -0
  209. package/esm/types/domain/Session.d.ts.map +1 -0
  210. package/esm/types/domain/SipLine.d.ts +54 -0
  211. package/esm/types/domain/SipLine.d.ts.map +1 -0
  212. package/esm/types/domain/Subscription.d.ts +43 -0
  213. package/esm/types/domain/Subscription.d.ts.map +1 -0
  214. package/esm/types/domain/SwitchboardCall.d.ts +62 -0
  215. package/esm/types/domain/SwitchboardCall.d.ts.map +1 -0
  216. package/esm/types/domain/Voicemail.d.ts +50 -0
  217. package/esm/types/domain/Voicemail.d.ts.map +1 -0
  218. package/esm/types/domain/__tests__/Agent.test.d.ts +2 -0
  219. package/esm/types/domain/__tests__/Agent.test.d.ts.map +1 -0
  220. package/esm/types/domain/__tests__/Call.test.d.ts +2 -0
  221. package/esm/types/domain/__tests__/Call.test.d.ts.map +1 -0
  222. package/esm/types/domain/__tests__/CallLog.test.d.ts +2 -0
  223. package/esm/types/domain/__tests__/CallLog.test.d.ts.map +1 -0
  224. package/esm/types/domain/__tests__/CallSession.test.d.ts +2 -0
  225. package/esm/types/domain/__tests__/CallSession.test.d.ts.map +1 -0
  226. package/esm/types/domain/__tests__/Contact.test.d.ts +2 -0
  227. package/esm/types/domain/__tests__/Contact.test.d.ts.map +1 -0
  228. package/esm/types/domain/__tests__/IndirectTransfer.test.d.ts +2 -0
  229. package/esm/types/domain/__tests__/IndirectTransfer.test.d.ts.map +1 -0
  230. package/esm/types/domain/__tests__/Line.test.d.ts +2 -0
  231. package/esm/types/domain/__tests__/Line.test.d.ts.map +1 -0
  232. package/esm/types/domain/__tests__/Meeting.test.d.ts +2 -0
  233. package/esm/types/domain/__tests__/Meeting.test.d.ts.map +1 -0
  234. package/esm/types/domain/__tests__/MeetingAuthorization.test.d.ts +2 -0
  235. package/esm/types/domain/__tests__/MeetingAuthorization.test.d.ts.map +1 -0
  236. package/esm/types/domain/__tests__/Profile.test.d.ts +2 -0
  237. package/esm/types/domain/__tests__/Profile.test.d.ts.map +1 -0
  238. package/esm/types/domain/__tests__/Room.test.d.ts +2 -0
  239. package/esm/types/domain/__tests__/Room.test.d.ts.map +1 -0
  240. package/esm/types/domain/__tests__/Session.test.d.ts +2 -0
  241. package/esm/types/domain/__tests__/Session.test.d.ts.map +1 -0
  242. package/esm/types/domain/__tests__/SipLine.test.d.ts +2 -0
  243. package/esm/types/domain/__tests__/SipLine.test.d.ts.map +1 -0
  244. package/esm/types/domain/__tests__/Voicemail.test.d.ts +2 -0
  245. package/esm/types/domain/__tests__/Voicemail.test.d.ts.map +1 -0
  246. package/esm/types/domain/types.d.ts +217 -0
  247. package/esm/types/domain/types.d.ts.map +1 -0
  248. package/esm/types/index.d.ts +304 -0
  249. package/esm/types/index.d.ts.map +1 -0
  250. package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +30 -0
  251. package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -0
  252. package/esm/types/pubkey.d.ts +3 -0
  253. package/esm/types/pubkey.d.ts.map +1 -0
  254. package/esm/types/service/CallApi.d.ts +28 -0
  255. package/esm/types/service/CallApi.d.ts.map +1 -0
  256. package/esm/types/service/IssueReporter.d.ts +40 -0
  257. package/esm/types/service/IssueReporter.d.ts.map +1 -0
  258. package/esm/types/service/__tests__/IssueReporter.test.d.ts +2 -0
  259. package/esm/types/service/__tests__/IssueReporter.test.d.ts.map +1 -0
  260. package/esm/types/service/getApiClient.d.ts +16 -0
  261. package/esm/types/service/getApiClient.d.ts.map +1 -0
  262. package/esm/types/simple/Auth.d.ts +51 -0
  263. package/esm/types/simple/Auth.d.ts.map +1 -0
  264. package/esm/types/simple/Configuration.d.ts +3 -0
  265. package/esm/types/simple/Configuration.d.ts.map +1 -0
  266. package/esm/types/simple/Directory.d.ts +3 -0
  267. package/esm/types/simple/Directory.d.ts.map +1 -0
  268. package/esm/types/simple/Phone.d.ts +115 -0
  269. package/esm/types/simple/Phone.d.ts.map +1 -0
  270. package/esm/types/simple/Websocket.d.ts +19 -0
  271. package/esm/types/simple/Websocket.d.ts.map +1 -0
  272. package/esm/types/simple/index.d.ts +147 -0
  273. package/esm/types/simple/index.d.ts.map +1 -0
  274. package/esm/types/simple/room/LocalParticipant.d.ts +5 -0
  275. package/esm/types/simple/room/LocalParticipant.d.ts.map +1 -0
  276. package/esm/types/simple/room/Participant.d.ts +76 -0
  277. package/esm/types/simple/room/Participant.d.ts.map +1 -0
  278. package/esm/types/simple/room/RemoteParticipant.d.ts +7 -0
  279. package/esm/types/simple/room/RemoteParticipant.d.ts.map +1 -0
  280. package/esm/types/simple/room/Room.d.ts +116 -0
  281. package/esm/types/simple/room/Room.d.ts.map +1 -0
  282. package/esm/types/simple/room/SipRoom.d.ts +14 -0
  283. package/esm/types/simple/room/SipRoom.d.ts.map +1 -0
  284. package/esm/types/simple/room/Stream.d.ts +13 -0
  285. package/esm/types/simple/room/Stream.d.ts.map +1 -0
  286. package/esm/types/simple/room/__tests__/Participant.test.d.ts +2 -0
  287. package/esm/types/simple/room/__tests__/Participant.test.d.ts.map +1 -0
  288. package/esm/types/simple/room/__tests__/RemoteParticipant.test.d.ts +2 -0
  289. package/esm/types/simple/room/__tests__/RemoteParticipant.test.d.ts.map +1 -0
  290. package/esm/types/simple/utils.d.ts +3 -0
  291. package/esm/types/simple/utils.d.ts.map +1 -0
  292. package/esm/types/types/WebSocketMessage.d.ts +285 -0
  293. package/esm/types/types/WebSocketMessage.d.ts.map +1 -0
  294. package/esm/types/utils/Emitter.d.ts +18 -0
  295. package/esm/types/utils/Emitter.d.ts.map +1 -0
  296. package/esm/types/utils/Heartbeat.d.ts +21 -0
  297. package/esm/types/utils/Heartbeat.d.ts.map +1 -0
  298. package/esm/types/utils/PhoneNumberUtil.d.ts +8 -0
  299. package/esm/types/utils/PhoneNumberUtil.d.ts.map +1 -0
  300. package/esm/types/utils/__tests__/Heartbeat.test.d.ts +2 -0
  301. package/esm/types/utils/__tests__/Heartbeat.test.d.ts.map +1 -0
  302. package/esm/types/utils/__tests__/PhoneNumberUtil.test.d.ts +2 -0
  303. package/esm/types/utils/__tests__/PhoneNumberUtil.test.d.ts.map +1 -0
  304. package/esm/types/utils/__tests__/api-requester.test.d.ts +2 -0
  305. package/esm/types/utils/__tests__/api-requester.test.d.ts.map +1 -0
  306. package/esm/types/utils/__tests__/array.test.d.ts +2 -0
  307. package/esm/types/utils/__tests__/array.test.d.ts.map +1 -0
  308. package/esm/types/utils/__tests__/compare-version.test.d.ts +2 -0
  309. package/esm/types/utils/__tests__/compare-version.test.d.ts.map +1 -0
  310. package/esm/types/utils/__tests__/object.test.d.ts +2 -0
  311. package/esm/types/utils/__tests__/object.test.d.ts.map +1 -0
  312. package/esm/types/utils/__tests__/sdp.test.d.ts +2 -0
  313. package/esm/types/utils/__tests__/sdp.test.d.ts.map +1 -0
  314. package/esm/types/utils/__tests__/string.test.d.ts +2 -0
  315. package/esm/types/utils/__tests__/string.test.d.ts.map +1 -0
  316. package/esm/types/utils/api-requester.d.ts +45 -0
  317. package/esm/types/utils/api-requester.d.ts.map +1 -0
  318. package/esm/types/utils/array.d.ts +2 -0
  319. package/esm/types/utils/array.d.ts.map +1 -0
  320. package/esm/types/utils/compare-version.d.ts +3 -0
  321. package/esm/types/utils/compare-version.d.ts.map +1 -0
  322. package/esm/types/utils/isMobile.d.ts +3 -0
  323. package/esm/types/utils/isMobile.d.ts.map +1 -0
  324. package/esm/types/utils/new-from.d.ts +3 -0
  325. package/esm/types/utils/new-from.d.ts.map +1 -0
  326. package/esm/types/utils/object.d.ts +2 -0
  327. package/esm/types/utils/object.d.ts.map +1 -0
  328. package/esm/types/utils/once.d.ts +2 -0
  329. package/esm/types/utils/once.d.ts.map +1 -0
  330. package/esm/types/utils/sdp.d.ts +13 -0
  331. package/esm/types/utils/sdp.d.ts.map +1 -0
  332. package/esm/types/utils/string.d.ts +2 -0
  333. package/esm/types/utils/string.d.ts.map +1 -0
  334. package/esm/types/utils/update-from.d.ts +3 -0
  335. package/esm/types/utils/update-from.d.ts.map +1 -0
  336. package/esm/types/utils/webrtc.d.ts +15 -0
  337. package/esm/types/utils/webrtc.d.ts.map +1 -0
  338. package/esm/types/web-rtc-client.d.ts +220 -0
  339. package/esm/types/web-rtc-client.d.ts.map +1 -0
  340. package/esm/types/websocket-client.d.ts +134 -0
  341. package/esm/types/websocket-client.d.ts.map +1 -0
  342. package/esm/utils/Emitter.js +17 -27
  343. package/esm/utils/Heartbeat.js +60 -83
  344. package/esm/utils/PhoneNumberUtil.js +48 -63
  345. package/esm/utils/__tests__/Heartbeat.test.js +59 -168
  346. package/esm/utils/__tests__/PhoneNumberUtil.test.js +55 -125
  347. package/esm/utils/__tests__/api-requester.test.js +127 -780
  348. package/esm/utils/__tests__/array.test.js +16 -19
  349. package/esm/utils/__tests__/compare-version.test.js +8 -26
  350. package/esm/utils/__tests__/object.test.js +73 -54
  351. package/esm/utils/__tests__/sdp.test.js +87 -216
  352. package/esm/utils/__tests__/string.test.js +21 -27
  353. package/esm/utils/api-requester.js +197 -675
  354. package/esm/utils/array.js +7 -11
  355. package/esm/utils/compare-version.js +12 -15
  356. package/esm/utils/isMobile.js +0 -2
  357. package/esm/utils/new-from.js +7 -12
  358. package/esm/utils/object.js +9 -23
  359. package/esm/utils/once.js +12 -13
  360. package/esm/utils/sdp.js +87 -131
  361. package/esm/utils/string.js +5 -9
  362. package/esm/utils/update-from.js +9 -16
  363. package/esm/utils/webrtc.js +35 -36
  364. package/esm/web-rtc-client.js +2038 -7677
  365. package/esm/websocket-client.js +352 -944
  366. package/lib/__tests__/api-client.test.js +199 -5067
  367. package/lib/__tests__/web-rtc-client.test.js +191 -7941
  368. package/lib/api/agentd.js +27 -837
  369. package/lib/api/amid.js +18 -415
  370. package/lib/api/application.js +64 -834
  371. package/lib/api/auth.js +166 -1222
  372. package/lib/api/call-logd.js +28 -738
  373. package/lib/api/calld.js +126 -1473
  374. package/lib/api/chatd.js +65 -1316
  375. package/lib/api/confd.js +79 -1584
  376. package/lib/api/ctid-ng.js +96 -1348
  377. package/lib/api/dird.js +105 -1596
  378. package/lib/api/webhookd.js +11 -518
  379. package/lib/api-client.js +139 -4884
  380. package/lib/checker/Checker.js +61 -8739
  381. package/lib/checker/checks/aor.js +37 -4929
  382. package/lib/checker/checks/api.js +81 -4971
  383. package/lib/checker/checks/ice-ipv4.js +66 -118
  384. package/lib/checker/checks/index.js +13 -8687
  385. package/lib/checker/checks/symmetric-nat.js +56 -104
  386. package/lib/checker/checks/wazo-websocket.js +58 -1006
  387. package/lib/checker/checks/webrtc-transport.js +41 -7853
  388. package/lib/checker/checks/webrtc.js +42 -7858
  389. package/lib/domain/AdHocAPIConference.js +80 -5116
  390. package/lib/domain/Agent.js +23 -64
  391. package/lib/domain/BadResponse.js +17 -44
  392. package/lib/domain/Call.js +108 -215
  393. package/lib/domain/CallLog.js +117 -311
  394. package/lib/domain/CallSession.js +221 -424
  395. package/lib/domain/ChatMessage.js +49 -110
  396. package/lib/domain/ChatRoom.js +28 -60
  397. package/lib/domain/Contact.js +409 -742
  398. package/lib/domain/Country.js +19 -21
  399. package/lib/domain/Device/DebugDevice.js +34 -49
  400. package/lib/domain/Device/Device.js +2 -2
  401. package/lib/domain/DirectorySource.js +2 -2
  402. package/lib/domain/ExternalApp.js +24 -56
  403. package/lib/domain/Features.js +68 -5018
  404. package/lib/domain/ForwardOption.js +36 -71
  405. package/lib/domain/IndirectTransfer.js +39 -98
  406. package/lib/domain/Line.js +35 -88
  407. package/lib/domain/Meeting.js +51 -118
  408. package/lib/domain/MeetingAuthorization.js +35 -75
  409. package/lib/domain/MeetingStatus.js +13 -29
  410. package/lib/domain/NotificationOptions.js +45 -77
  411. package/lib/domain/Phone/CTIPhone.js +283 -5755
  412. package/lib/domain/Phone/Phone.js +2 -5
  413. package/lib/domain/Phone/WebRTCPhone.js +1457 -2716
  414. package/lib/domain/Profile.js +127 -406
  415. package/lib/domain/Recording.js +28 -57
  416. package/lib/domain/Relocation.js +15 -43
  417. package/lib/domain/Room.js +73 -134
  418. package/lib/domain/SFUNotAvailableError.js +7 -9
  419. package/lib/domain/ServerError.js +14 -63
  420. package/lib/domain/Session.js +118 -251
  421. package/lib/domain/SipLine.js +70 -155
  422. package/lib/domain/Subscription.js +32 -86
  423. package/lib/domain/SwitchboardCall.js +45 -145
  424. package/lib/domain/Voicemail.js +56 -127
  425. package/lib/domain/__tests__/Agent.test.js +36 -103
  426. package/lib/domain/__tests__/Call.test.js +28 -237
  427. package/lib/domain/__tests__/CallLog.test.js +65 -392
  428. package/lib/domain/__tests__/CallSession.test.js +78 -503
  429. package/lib/domain/__tests__/Contact.test.js +224 -903
  430. package/lib/domain/__tests__/IndirectTransfer.test.js +75 -546
  431. package/lib/domain/__tests__/Line.test.js +52 -157
  432. package/lib/domain/__tests__/Meeting.test.js +78 -232
  433. package/lib/domain/__tests__/MeetingAuthorization.test.js +50 -107
  434. package/lib/domain/__tests__/Profile.test.js +161 -496
  435. package/lib/domain/__tests__/Room.test.js +239 -719
  436. package/lib/domain/__tests__/Session.test.js +350 -1024
  437. package/lib/domain/__tests__/SipLine.test.js +28 -180
  438. package/lib/domain/__tests__/Voicemail.test.js +86 -205
  439. package/lib/domain/types.js +2 -2
  440. package/lib/index.js +105 -15010
  441. package/lib/lib/WazoSessionDescriptionHandler.js +409 -898
  442. package/lib/pubkey.js +12 -0
  443. package/lib/service/CallApi.js +88 -5015
  444. package/lib/service/IssueReporter.js +264 -366
  445. package/lib/service/__tests__/IssueReporter.test.js +97 -500
  446. package/lib/service/getApiClient.js +70 -4990
  447. package/lib/simple/Auth.js +272 -14777
  448. package/lib/simple/Configuration.js +23 -14805
  449. package/lib/simple/Directory.js +18 -4966
  450. package/lib/simple/Phone.js +345 -14746
  451. package/lib/simple/Websocket.js +98 -1117
  452. package/lib/simple/index.js +151 -14800
  453. package/lib/simple/room/LocalParticipant.js +7 -14808
  454. package/lib/simple/room/Participant.js +269 -14778
  455. package/lib/simple/room/RemoteParticipant.js +11 -14806
  456. package/lib/simple/room/Room.js +655 -14761
  457. package/lib/simple/room/SipRoom.js +136 -14805
  458. package/lib/simple/room/Stream.js +43 -14802
  459. package/lib/simple/room/__tests__/Participant.test.js +79 -14879
  460. package/lib/simple/room/__tests__/RemoteParticipant.test.js +14 -14814
  461. package/lib/simple/utils.js +22 -14808
  462. package/lib/types/WebSocketMessage.js +2 -4
  463. package/lib/types/__tests__/api-client.test.d.ts +2 -0
  464. package/lib/types/__tests__/api-client.test.d.ts.map +1 -0
  465. package/lib/types/__tests__/web-rtc-client.test.d.ts +2 -0
  466. package/lib/types/__tests__/web-rtc-client.test.d.ts.map +1 -0
  467. package/lib/types/api/agentd.d.ts +17 -0
  468. package/lib/types/api/agentd.d.ts.map +1 -0
  469. package/lib/types/api/amid.d.ts +8 -0
  470. package/lib/types/api/amid.d.ts.map +1 -0
  471. package/lib/types/api/application.d.ts +34 -0
  472. package/lib/types/api/application.d.ts.map +1 -0
  473. package/lib/types/api/auth.d.ts +64 -0
  474. package/lib/types/api/auth.d.ts.map +1 -0
  475. package/lib/types/api/call-logd.d.ts +12 -0
  476. package/lib/types/api/call-logd.d.ts.map +1 -0
  477. package/lib/types/api/calld.d.ts +51 -0
  478. package/lib/types/api/calld.d.ts.map +1 -0
  479. package/lib/types/api/chatd.d.ts +42 -0
  480. package/lib/types/api/chatd.d.ts.map +1 -0
  481. package/lib/types/api/confd.d.ts +39 -0
  482. package/lib/types/api/confd.d.ts.map +1 -0
  483. package/lib/types/api/ctid-ng.d.ts +36 -0
  484. package/lib/types/api/ctid-ng.d.ts.map +1 -0
  485. package/lib/types/api/dird.d.ts +38 -0
  486. package/lib/types/api/dird.d.ts.map +1 -0
  487. package/lib/types/api/webhookd.d.ts +24 -0
  488. package/lib/types/api/webhookd.d.ts.map +1 -0
  489. package/lib/types/api-client.d.ts +63 -0
  490. package/lib/types/api-client.d.ts.map +1 -0
  491. package/lib/types/checker/Checker.d.ts +13 -0
  492. package/lib/types/checker/Checker.d.ts.map +1 -0
  493. package/lib/types/checker/checks/aor.d.ts +6 -0
  494. package/lib/types/checker/checks/aor.d.ts.map +1 -0
  495. package/lib/types/checker/checks/api.d.ts +6 -0
  496. package/lib/types/checker/checks/api.d.ts.map +1 -0
  497. package/lib/types/checker/checks/ice-ipv4.d.ts +6 -0
  498. package/lib/types/checker/checks/ice-ipv4.d.ts.map +1 -0
  499. package/lib/types/checker/checks/index.d.ts +9 -0
  500. package/lib/types/checker/checks/index.d.ts.map +1 -0
  501. package/lib/types/checker/checks/symmetric-nat.d.ts +6 -0
  502. package/lib/types/checker/checks/symmetric-nat.d.ts.map +1 -0
  503. package/lib/types/checker/checks/wazo-websocket.d.ts +6 -0
  504. package/lib/types/checker/checks/wazo-websocket.d.ts.map +1 -0
  505. package/lib/types/checker/checks/webrtc-transport.d.ts +7 -0
  506. package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -0
  507. package/lib/types/checker/checks/webrtc.d.ts +6 -0
  508. package/lib/types/checker/checks/webrtc.d.ts.map +1 -0
  509. package/lib/types/domain/AdHocAPIConference.d.ts +54 -0
  510. package/lib/types/domain/AdHocAPIConference.d.ts.map +1 -0
  511. package/lib/types/domain/Agent.d.ts +31 -0
  512. package/lib/types/domain/Agent.d.ts.map +1 -0
  513. package/lib/types/domain/BadResponse.d.ts +11 -0
  514. package/lib/types/domain/BadResponse.d.ts.map +1 -0
  515. package/lib/types/domain/Call.d.ts +79 -0
  516. package/lib/types/domain/Call.d.ts.map +1 -0
  517. package/lib/types/domain/CallLog.d.ts +91 -0
  518. package/lib/types/domain/CallLog.d.ts.map +1 -0
  519. package/lib/types/domain/CallSession.d.ts +120 -0
  520. package/lib/types/domain/CallSession.d.ts.map +1 -0
  521. package/lib/types/domain/ChatMessage.d.ts +41 -0
  522. package/lib/types/domain/ChatMessage.d.ts.map +1 -0
  523. package/lib/types/domain/ChatRoom.d.ts +22 -0
  524. package/lib/types/domain/ChatRoom.d.ts.map +1 -0
  525. package/lib/types/domain/Contact.d.ts +316 -0
  526. package/lib/types/domain/Contact.d.ts.map +1 -0
  527. package/lib/types/domain/Country.d.ts +20 -0
  528. package/lib/types/domain/Country.d.ts.map +1 -0
  529. package/lib/types/domain/Device/DebugDevice.d.ts +14 -0
  530. package/lib/types/domain/Device/DebugDevice.d.ts.map +1 -0
  531. package/lib/types/domain/Device/Device.d.ts +13 -0
  532. package/lib/types/domain/Device/Device.d.ts.map +1 -0
  533. package/lib/types/domain/DirectorySource.d.ts +13 -0
  534. package/lib/types/domain/DirectorySource.d.ts.map +1 -0
  535. package/lib/types/domain/ExternalApp.d.ts +22 -0
  536. package/lib/types/domain/ExternalApp.d.ts.map +1 -0
  537. package/lib/types/domain/Features.d.ts +24 -0
  538. package/lib/types/domain/Features.d.ts.map +1 -0
  539. package/lib/types/domain/ForwardOption.d.ts +27 -0
  540. package/lib/types/domain/ForwardOption.d.ts.map +1 -0
  541. package/lib/types/domain/IndirectTransfer.d.ts +31 -0
  542. package/lib/types/domain/IndirectTransfer.d.ts.map +1 -0
  543. package/lib/types/domain/Line.d.ts +46 -0
  544. package/lib/types/domain/Line.d.ts.map +1 -0
  545. package/lib/types/domain/Meeting.d.ts +45 -0
  546. package/lib/types/domain/Meeting.d.ts.map +1 -0
  547. package/lib/types/domain/MeetingAuthorization.d.ts +26 -0
  548. package/lib/types/domain/MeetingAuthorization.d.ts.map +1 -0
  549. package/lib/types/domain/MeetingStatus.d.ts +10 -0
  550. package/lib/types/domain/MeetingStatus.d.ts.map +1 -0
  551. package/lib/types/domain/NotificationOptions.d.ts +22 -0
  552. package/lib/types/domain/NotificationOptions.d.ts.map +1 -0
  553. package/lib/types/domain/Phone/CTIPhone.d.ts +76 -0
  554. package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -0
  555. package/lib/types/domain/Phone/Phone.d.ts +71 -0
  556. package/lib/types/domain/Phone/Phone.d.ts.map +1 -0
  557. package/lib/types/domain/Phone/WebRTCPhone.d.ts +179 -0
  558. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -0
  559. package/lib/types/domain/Profile.d.ts +151 -0
  560. package/lib/types/domain/Profile.d.ts.map +1 -0
  561. package/lib/types/domain/Recording.d.ts +26 -0
  562. package/lib/types/domain/Recording.d.ts.map +1 -0
  563. package/lib/types/domain/Relocation.d.ts +23 -0
  564. package/lib/types/domain/Relocation.d.ts.map +1 -0
  565. package/lib/types/domain/Room.d.ts +35 -0
  566. package/lib/types/domain/Room.d.ts.map +1 -0
  567. package/lib/types/domain/SFUNotAvailableError.d.ts +4 -0
  568. package/lib/types/domain/SFUNotAvailableError.d.ts.map +1 -0
  569. package/lib/types/domain/ServerError.d.ts +6 -0
  570. package/lib/types/domain/ServerError.d.ts.map +1 -0
  571. package/lib/types/domain/Session.d.ts +90 -0
  572. package/lib/types/domain/Session.d.ts.map +1 -0
  573. package/lib/types/domain/SipLine.d.ts +54 -0
  574. package/lib/types/domain/SipLine.d.ts.map +1 -0
  575. package/lib/types/domain/Subscription.d.ts +43 -0
  576. package/lib/types/domain/Subscription.d.ts.map +1 -0
  577. package/lib/types/domain/SwitchboardCall.d.ts +62 -0
  578. package/lib/types/domain/SwitchboardCall.d.ts.map +1 -0
  579. package/lib/types/domain/Voicemail.d.ts +50 -0
  580. package/lib/types/domain/Voicemail.d.ts.map +1 -0
  581. package/lib/types/domain/__tests__/Agent.test.d.ts +2 -0
  582. package/lib/types/domain/__tests__/Agent.test.d.ts.map +1 -0
  583. package/lib/types/domain/__tests__/Call.test.d.ts +2 -0
  584. package/lib/types/domain/__tests__/Call.test.d.ts.map +1 -0
  585. package/lib/types/domain/__tests__/CallLog.test.d.ts +2 -0
  586. package/lib/types/domain/__tests__/CallLog.test.d.ts.map +1 -0
  587. package/lib/types/domain/__tests__/CallSession.test.d.ts +2 -0
  588. package/lib/types/domain/__tests__/CallSession.test.d.ts.map +1 -0
  589. package/lib/types/domain/__tests__/Contact.test.d.ts +2 -0
  590. package/lib/types/domain/__tests__/Contact.test.d.ts.map +1 -0
  591. package/lib/types/domain/__tests__/IndirectTransfer.test.d.ts +2 -0
  592. package/lib/types/domain/__tests__/IndirectTransfer.test.d.ts.map +1 -0
  593. package/lib/types/domain/__tests__/Line.test.d.ts +2 -0
  594. package/lib/types/domain/__tests__/Line.test.d.ts.map +1 -0
  595. package/lib/types/domain/__tests__/Meeting.test.d.ts +2 -0
  596. package/lib/types/domain/__tests__/Meeting.test.d.ts.map +1 -0
  597. package/lib/types/domain/__tests__/MeetingAuthorization.test.d.ts +2 -0
  598. package/lib/types/domain/__tests__/MeetingAuthorization.test.d.ts.map +1 -0
  599. package/lib/types/domain/__tests__/Profile.test.d.ts +2 -0
  600. package/lib/types/domain/__tests__/Profile.test.d.ts.map +1 -0
  601. package/lib/types/domain/__tests__/Room.test.d.ts +2 -0
  602. package/lib/types/domain/__tests__/Room.test.d.ts.map +1 -0
  603. package/lib/types/domain/__tests__/Session.test.d.ts +2 -0
  604. package/lib/types/domain/__tests__/Session.test.d.ts.map +1 -0
  605. package/lib/types/domain/__tests__/SipLine.test.d.ts +2 -0
  606. package/lib/types/domain/__tests__/SipLine.test.d.ts.map +1 -0
  607. package/lib/types/domain/__tests__/Voicemail.test.d.ts +2 -0
  608. package/lib/types/domain/__tests__/Voicemail.test.d.ts.map +1 -0
  609. package/lib/types/domain/types.d.ts +217 -0
  610. package/lib/types/domain/types.d.ts.map +1 -0
  611. package/lib/types/index.d.ts +304 -0
  612. package/lib/types/index.d.ts.map +1 -0
  613. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +30 -0
  614. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -0
  615. package/lib/types/pubkey.d.ts +3 -0
  616. package/lib/types/pubkey.d.ts.map +1 -0
  617. package/lib/types/service/CallApi.d.ts +28 -0
  618. package/lib/types/service/CallApi.d.ts.map +1 -0
  619. package/lib/types/service/IssueReporter.d.ts +40 -0
  620. package/lib/types/service/IssueReporter.d.ts.map +1 -0
  621. package/lib/types/service/__tests__/IssueReporter.test.d.ts +2 -0
  622. package/lib/types/service/__tests__/IssueReporter.test.d.ts.map +1 -0
  623. package/lib/types/service/getApiClient.d.ts +16 -0
  624. package/lib/types/service/getApiClient.d.ts.map +1 -0
  625. package/lib/types/simple/Auth.d.ts +51 -0
  626. package/lib/types/simple/Auth.d.ts.map +1 -0
  627. package/lib/types/simple/Configuration.d.ts +3 -0
  628. package/lib/types/simple/Configuration.d.ts.map +1 -0
  629. package/lib/types/simple/Directory.d.ts +3 -0
  630. package/lib/types/simple/Directory.d.ts.map +1 -0
  631. package/lib/types/simple/Phone.d.ts +115 -0
  632. package/lib/types/simple/Phone.d.ts.map +1 -0
  633. package/lib/types/simple/Websocket.d.ts +19 -0
  634. package/lib/types/simple/Websocket.d.ts.map +1 -0
  635. package/lib/types/simple/index.d.ts +147 -0
  636. package/lib/types/simple/index.d.ts.map +1 -0
  637. package/lib/types/simple/room/LocalParticipant.d.ts +5 -0
  638. package/lib/types/simple/room/LocalParticipant.d.ts.map +1 -0
  639. package/lib/types/simple/room/Participant.d.ts +76 -0
  640. package/lib/types/simple/room/Participant.d.ts.map +1 -0
  641. package/lib/types/simple/room/RemoteParticipant.d.ts +7 -0
  642. package/lib/types/simple/room/RemoteParticipant.d.ts.map +1 -0
  643. package/lib/types/simple/room/Room.d.ts +116 -0
  644. package/lib/types/simple/room/Room.d.ts.map +1 -0
  645. package/lib/types/simple/room/SipRoom.d.ts +14 -0
  646. package/lib/types/simple/room/SipRoom.d.ts.map +1 -0
  647. package/lib/types/simple/room/Stream.d.ts +13 -0
  648. package/lib/types/simple/room/Stream.d.ts.map +1 -0
  649. package/lib/types/simple/room/__tests__/Participant.test.d.ts +2 -0
  650. package/lib/types/simple/room/__tests__/Participant.test.d.ts.map +1 -0
  651. package/lib/types/simple/room/__tests__/RemoteParticipant.test.d.ts +2 -0
  652. package/lib/types/simple/room/__tests__/RemoteParticipant.test.d.ts.map +1 -0
  653. package/lib/types/simple/utils.d.ts +3 -0
  654. package/lib/types/simple/utils.d.ts.map +1 -0
  655. package/lib/types/types/WebSocketMessage.d.ts +285 -0
  656. package/lib/types/types/WebSocketMessage.d.ts.map +1 -0
  657. package/lib/types/utils/Emitter.d.ts +18 -0
  658. package/lib/types/utils/Emitter.d.ts.map +1 -0
  659. package/lib/types/utils/Heartbeat.d.ts +21 -0
  660. package/lib/types/utils/Heartbeat.d.ts.map +1 -0
  661. package/lib/types/utils/PhoneNumberUtil.d.ts +8 -0
  662. package/lib/types/utils/PhoneNumberUtil.d.ts.map +1 -0
  663. package/lib/types/utils/__tests__/Heartbeat.test.d.ts +2 -0
  664. package/lib/types/utils/__tests__/Heartbeat.test.d.ts.map +1 -0
  665. package/lib/types/utils/__tests__/PhoneNumberUtil.test.d.ts +2 -0
  666. package/lib/types/utils/__tests__/PhoneNumberUtil.test.d.ts.map +1 -0
  667. package/lib/types/utils/__tests__/api-requester.test.d.ts +2 -0
  668. package/lib/types/utils/__tests__/api-requester.test.d.ts.map +1 -0
  669. package/lib/types/utils/__tests__/array.test.d.ts +2 -0
  670. package/lib/types/utils/__tests__/array.test.d.ts.map +1 -0
  671. package/lib/types/utils/__tests__/compare-version.test.d.ts +2 -0
  672. package/lib/types/utils/__tests__/compare-version.test.d.ts.map +1 -0
  673. package/lib/types/utils/__tests__/object.test.d.ts +2 -0
  674. package/lib/types/utils/__tests__/object.test.d.ts.map +1 -0
  675. package/lib/types/utils/__tests__/sdp.test.d.ts +2 -0
  676. package/lib/types/utils/__tests__/sdp.test.d.ts.map +1 -0
  677. package/lib/types/utils/__tests__/string.test.d.ts +2 -0
  678. package/lib/types/utils/__tests__/string.test.d.ts.map +1 -0
  679. package/lib/types/utils/api-requester.d.ts +45 -0
  680. package/lib/types/utils/api-requester.d.ts.map +1 -0
  681. package/lib/types/utils/array.d.ts +2 -0
  682. package/lib/types/utils/array.d.ts.map +1 -0
  683. package/lib/types/utils/compare-version.d.ts +3 -0
  684. package/lib/types/utils/compare-version.d.ts.map +1 -0
  685. package/lib/types/utils/isMobile.d.ts +3 -0
  686. package/lib/types/utils/isMobile.d.ts.map +1 -0
  687. package/lib/types/utils/new-from.d.ts +3 -0
  688. package/lib/types/utils/new-from.d.ts.map +1 -0
  689. package/lib/types/utils/object.d.ts +2 -0
  690. package/lib/types/utils/object.d.ts.map +1 -0
  691. package/lib/types/utils/once.d.ts +2 -0
  692. package/lib/types/utils/once.d.ts.map +1 -0
  693. package/lib/types/utils/sdp.d.ts +13 -0
  694. package/lib/types/utils/sdp.d.ts.map +1 -0
  695. package/lib/types/utils/string.d.ts +2 -0
  696. package/lib/types/utils/string.d.ts.map +1 -0
  697. package/lib/types/utils/update-from.d.ts +3 -0
  698. package/lib/types/utils/update-from.d.ts.map +1 -0
  699. package/lib/types/utils/webrtc.d.ts +15 -0
  700. package/lib/types/utils/webrtc.d.ts.map +1 -0
  701. package/lib/types/web-rtc-client.d.ts +220 -0
  702. package/lib/types/web-rtc-client.d.ts.map +1 -0
  703. package/lib/types/websocket-client.d.ts +134 -0
  704. package/lib/types/websocket-client.d.ts.map +1 -0
  705. package/lib/utils/Emitter.js +22 -33
  706. package/lib/utils/Heartbeat.js +54 -86
  707. package/lib/utils/PhoneNumberUtil.js +60 -77
  708. package/lib/utils/__tests__/Heartbeat.test.js +73 -170
  709. package/lib/utils/__tests__/PhoneNumberUtil.test.js +57 -131
  710. package/lib/utils/__tests__/api-requester.test.js +139 -784
  711. package/lib/utils/__tests__/array.test.js +18 -21
  712. package/lib/utils/__tests__/compare-version.test.js +12 -27
  713. package/lib/utils/__tests__/object.test.js +75 -56
  714. package/lib/utils/__tests__/sdp.test.js +99 -220
  715. package/lib/utils/__tests__/string.test.js +23 -29
  716. package/lib/utils/api-requester.js +191 -685
  717. package/lib/utils/array.js +10 -14
  718. package/lib/utils/compare-version.js +15 -18
  719. package/lib/utils/isMobile.js +3 -5
  720. package/lib/utils/new-from.js +9 -14
  721. package/lib/utils/object.js +12 -26
  722. package/lib/utils/once.js +15 -15
  723. package/lib/utils/sdp.js +97 -150
  724. package/lib/utils/string.js +8 -12
  725. package/lib/utils/update-from.js +11 -18
  726. package/lib/utils/webrtc.js +38 -39
  727. package/lib/web-rtc-client.js +2070 -7694
  728. package/lib/websocket-client.js +357 -1021
  729. package/package.json +41 -34
  730. package/src/__tests__/{api-client.test.js → api-client.test.ts} +71 -29
  731. package/src/__tests__/{web-rtc-client.test.js → web-rtc-client.test.ts} +95 -35
  732. package/src/api/agentd.ts +37 -0
  733. package/src/api/amid.ts +16 -0
  734. package/src/api/application.ts +96 -0
  735. package/src/api/auth.ts +259 -0
  736. package/src/api/call-logd.ts +38 -0
  737. package/src/api/calld.ts +183 -0
  738. package/src/api/chatd.ts +101 -0
  739. package/src/api/confd.ts +110 -0
  740. package/src/api/ctid-ng.ts +152 -0
  741. package/src/api/dird.ts +146 -0
  742. package/src/api/webhookd.ts +30 -0
  743. package/src/{api-client.js → api-client.ts} +103 -67
  744. package/src/checker/{Checker.js → Checker.ts} +27 -20
  745. package/src/checker/checks/{aor.js → aor.ts} +10 -6
  746. package/src/checker/checks/{api.js → api.ts} +18 -17
  747. package/src/checker/checks/{ice-ipv4.js → ice-ipv4.ts} +23 -26
  748. package/src/checker/checks/{index.js → index.ts} +1 -9
  749. package/src/checker/checks/{symmetric-nat.js → symmetric-nat.ts} +14 -15
  750. package/src/checker/checks/{wazo-websocket.js → wazo-websocket.ts} +7 -5
  751. package/src/checker/checks/{webrtc-transport.js → webrtc-transport.ts} +3 -2
  752. package/src/checker/checks/{webrtc.js → webrtc.ts} +3 -4
  753. package/src/domain/{AdHocAPIConference.js → AdHocAPIConference.ts} +38 -54
  754. package/src/domain/{Agent.js → Agent.ts} +11 -7
  755. package/src/domain/BadResponse.ts +29 -0
  756. package/src/domain/{Call.js → Call.ts} +62 -46
  757. package/src/domain/{CallLog.js → CallLog.ts} +61 -63
  758. package/src/domain/{CallSession.js → CallSession.ts} +55 -52
  759. package/src/domain/{ChatMessage.js → ChatMessage.ts} +32 -21
  760. package/src/domain/{ChatRoom.js → ChatRoom.ts} +15 -11
  761. package/src/domain/{Contact.js → Contact.ts} +380 -262
  762. package/src/domain/Device/{DebugDevice.js → DebugDevice.ts} +3 -5
  763. package/src/domain/Device/{Device.js → Device.ts} +0 -11
  764. package/src/domain/DirectorySource.ts +13 -0
  765. package/src/domain/{ExternalApp.js → ExternalApp.ts} +14 -13
  766. package/src/domain/{Features.js → Features.ts} +43 -17
  767. package/src/domain/{ForwardOption.js → ForwardOption.ts} +16 -16
  768. package/src/domain/{IndirectTransfer.js → IndirectTransfer.ts} +21 -19
  769. package/src/domain/{Line.js → Line.ts} +39 -26
  770. package/src/domain/{Meeting.js → Meeting.ts} +36 -29
  771. package/src/domain/{MeetingAuthorization.js → MeetingAuthorization.ts} +13 -12
  772. package/src/domain/{MeetingStatus.js → MeetingStatus.ts} +2 -6
  773. package/src/domain/{NotificationOptions.js → NotificationOptions.ts} +14 -13
  774. package/src/domain/Phone/{CTIPhone.js → CTIPhone.ts} +90 -60
  775. package/src/domain/Phone/{Phone.js → Phone.ts} +27 -72
  776. package/src/domain/Phone/{WebRTCPhone.js → WebRTCPhone.ts} +456 -422
  777. package/src/domain/{Profile.js → Profile.ts} +117 -100
  778. package/src/domain/{Recording.js → Recording.ts} +25 -16
  779. package/src/domain/{Relocation.js → Relocation.ts} +15 -14
  780. package/src/domain/{Room.js → Room.ts} +58 -27
  781. package/src/domain/{SFUNotAvailableError.js → SFUNotAvailableError.ts} +2 -2
  782. package/src/domain/ServerError.ts +12 -0
  783. package/src/domain/{Session.js → Session.ts} +89 -67
  784. package/src/domain/{SipLine.js → SipLine.ts} +52 -45
  785. package/src/domain/{Subscription.js → Subscription.ts} +22 -13
  786. package/src/domain/{SwitchboardCall.js → SwitchboardCall.ts} +48 -43
  787. package/src/domain/{Voicemail.js → Voicemail.ts} +38 -34
  788. package/src/domain/__tests__/{Agent.test.js → Agent.test.ts} +11 -19
  789. package/src/domain/__tests__/{Call.test.js → Call.test.ts} +12 -9
  790. package/src/domain/__tests__/CallLog.test.ts +65 -0
  791. package/src/domain/__tests__/{CallSession.test.js → CallSession.test.ts} +15 -19
  792. package/src/domain/__tests__/Contact.test.ts +238 -0
  793. package/src/domain/__tests__/{IndirectTransfer.test.js → IndirectTransfer.test.ts} +38 -31
  794. package/src/domain/__tests__/Line.test.ts +53 -0
  795. package/src/domain/__tests__/{Meeting.test.js → Meeting.test.ts} +12 -38
  796. package/src/domain/__tests__/{MeetingAuthorization.test.js → MeetingAuthorization.test.ts} +13 -21
  797. package/src/domain/__tests__/Profile.test.ts +139 -0
  798. package/src/domain/__tests__/{Room.test.js → Room.test.ts} +114 -76
  799. package/src/domain/__tests__/{Session.test.js → Session.test.ts} +137 -162
  800. package/src/domain/__tests__/{SipLine.test.js → SipLine.test.ts} +7 -3
  801. package/src/domain/__tests__/{Voicemail.test.js → Voicemail.test.ts} +26 -20
  802. package/src/domain/types.ts +227 -0
  803. package/src/{index.js → index.ts} +4 -28
  804. package/src/lib/WazoSessionDescriptionHandler.ts +534 -0
  805. package/{config.js → src/pubkey.ts} +3 -3
  806. package/src/service/{CallApi.js → CallApi.ts} +14 -18
  807. package/src/service/{IssueReporter.js → IssueReporter.ts} +105 -56
  808. package/src/service/__tests__/{IssueReporter.test.js → IssueReporter.test.ts} +27 -23
  809. package/src/service/getApiClient.ts +94 -0
  810. package/src/simple/{Auth.js → Auth.ts} +130 -101
  811. package/src/simple/{Configuration.js → Configuration.ts} +2 -3
  812. package/src/simple/{Directory.js → Directory.ts} +2 -3
  813. package/src/simple/Phone.ts +623 -0
  814. package/src/simple/Websocket.ts +119 -0
  815. package/src/simple/{index.js → index.ts} +51 -21
  816. package/src/simple/room/{LocalParticipant.js → LocalParticipant.ts} +1 -3
  817. package/src/simple/room/{Participant.js → Participant.ts} +108 -46
  818. package/src/simple/room/{RemoteParticipant.js → RemoteParticipant.ts} +5 -4
  819. package/src/simple/room/{Room.js → Room.ts} +266 -183
  820. package/src/simple/room/{SipRoom.js → SipRoom.ts} +46 -29
  821. package/src/simple/room/{Stream.js → Stream.ts} +8 -6
  822. package/src/simple/room/__tests__/{Participant.test.js → Participant.test.ts} +9 -15
  823. package/src/simple/room/__tests__/{RemoteParticipant.test.js → RemoteParticipant.test.ts} +5 -1
  824. package/src/simple/utils.ts +12 -0
  825. package/src/types/WebSocketMessage.ts +335 -0
  826. package/src/types/global.d.ts +26 -0
  827. package/src/utils/Emitter.ts +34 -0
  828. package/src/utils/{Heartbeat.js → Heartbeat.ts} +17 -11
  829. package/src/utils/{PhoneNumberUtil.js → PhoneNumberUtil.ts} +12 -18
  830. package/src/utils/__tests__/{Heartbeat.test.js → Heartbeat.test.ts} +0 -15
  831. package/src/utils/__tests__/{PhoneNumberUtil.test.js → PhoneNumberUtil.test.ts} +6 -4
  832. package/src/utils/__tests__/{api-requester.test.js → api-requester.test.ts} +75 -24
  833. package/src/utils/__tests__/{array.test.js → array.test.ts} +10 -2
  834. package/src/utils/__tests__/object.test.ts +77 -0
  835. package/src/utils/__tests__/{sdp.test.js → sdp.test.ts} +15 -37
  836. package/src/utils/__tests__/{string.test.js → string.test.ts} +4 -2
  837. package/src/utils/{api-requester.js → api-requester.ts} +104 -83
  838. package/src/utils/{array.js → array.ts} +2 -2
  839. package/src/utils/{compare-version.js → compare-version.ts} +3 -2
  840. package/src/utils/{isMobile.js → isMobile.ts} +1 -1
  841. package/src/utils/{new-from.js → new-from.ts} +3 -6
  842. package/src/utils/{object.js → object.ts} +3 -6
  843. package/src/utils/{once.js → once.ts} +5 -5
  844. package/src/utils/sdp.ts +119 -0
  845. package/src/utils/{string.js → string.ts} +2 -3
  846. package/src/utils/update-from.ts +11 -0
  847. package/src/utils/{webrtc.js → webrtc.ts} +21 -3
  848. package/src/{web-rtc-client.js → web-rtc-client.ts} +879 -476
  849. package/src/{websocket-client.js → websocket-client.ts} +146 -144
  850. package/esm/simple/Softphone.js +0 -394
  851. package/lib/simple/Softphone.js +0 -396
  852. package/src/api/agentd.js +0 -74
  853. package/src/api/amid.js +0 -13
  854. package/src/api/application.js +0 -137
  855. package/src/api/auth.js +0 -279
  856. package/src/api/call-logd.js +0 -20
  857. package/src/api/calld.js +0 -214
  858. package/src/api/chatd.js +0 -80
  859. package/src/api/confd.js +0 -127
  860. package/src/api/ctid-ng.js +0 -153
  861. package/src/api/dird.js +0 -159
  862. package/src/api/webhookd.js +0 -31
  863. package/src/domain/BadResponse.js +0 -42
  864. package/src/domain/DirectorySource.js +0 -16
  865. package/src/domain/ServerError.js +0 -18
  866. package/src/domain/__tests__/CallLog.test.js +0 -75
  867. package/src/domain/__tests__/Contact.test.js +0 -170
  868. package/src/domain/__tests__/Line.test.js +0 -73
  869. package/src/domain/__tests__/Profile.test.js +0 -104
  870. package/src/domain/types.js +0 -248
  871. package/src/lib/WazoSessionDescriptionHandler.js +0 -467
  872. package/src/service/getApiClient.js +0 -122
  873. package/src/simple/Phone.js +0 -425
  874. package/src/simple/Softphone.js +0 -392
  875. package/src/simple/Websocket.js +0 -86
  876. package/src/simple/utils.js +0 -17
  877. package/src/types/WebSocketMessage.js +0 -232
  878. package/src/utils/Emitter.js +0 -26
  879. package/src/utils/__tests__/object.test.js +0 -35
  880. package/src/utils/sdp.js +0 -140
  881. package/src/utils/update-from.js +0 -15
  882. /package/src/domain/{Country.js → Country.ts} +0 -0
  883. /package/src/utils/__tests__/{compare-version.test.js → compare-version.test.ts} +0 -0
@@ -1,37 +1,36 @@
1
- // @flow
2
1
  /* eslint-disable class-methods-use-this, no-param-reassign, max-classes-per-file, no-underscore-dangle */
2
+
3
3
  /* global window, document, navigator */
4
4
  import 'webrtc-adapter';
5
- import type InviterInviteOptions from 'sip.js/lib/api/inviter-invite-options';
6
- import type Invitation from 'sip.js/lib/api/invitation';
5
+ import type { InviterInviteOptions } from 'sip.js/lib/api/inviter-invite-options';
7
6
  import type { IncomingResponse } from 'sip.js/lib/core/messages/incoming-response';
8
- import type { Session } from 'sip.js/lib/core/session';
7
+ import type { InvitationRejectOptions } from 'sip.js/lib/api/invitation-reject-options';
8
+ import type { InviterCancelOptions } from 'sip.js/lib/api/inviter-cancel-options';
9
+ import type { SessionByeOptions } from 'sip.js/lib/api/session-bye-options';
10
+ import type { InvitationAcceptOptions } from 'sip.js/lib/api/invitation-accept-options';
11
+
9
12
  import type { SessionDialog } from 'sip.js/lib/core/dialogs/session-dialog';
10
13
  import type { IncomingRequestMessage } from 'sip.js/lib/core/messages/incoming-request-message';
11
- import type { SessionDescriptionHandlerFactoryOptions }
12
- from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-factory-options';
13
- import type SessionDescriptionHandlerConfiguration
14
- from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-configuration';
15
- import type SessionDescriptionHandler
16
- from 'sip.js/lib/platform/web/session-description-handler/session-description-handler';
14
+ import type { SessionDescriptionHandlerFactoryOptions } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-factory-options';
15
+ import type { SessionDescriptionHandlerConfiguration } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-configuration';
16
+ import type { SessionDescriptionHandler } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler';
17
17
  import { UserAgentState } from 'sip.js/lib/api/user-agent-state';
18
18
  import { Parser } from 'sip.js/lib/core/messages/parser';
19
19
  import { C } from 'sip.js/lib/core/messages/methods/constants';
20
20
  import { URI } from 'sip.js/lib/grammar/uri';
21
21
  import { UserAgent } from 'sip.js/lib/api/user-agent';
22
22
  import { holdModifier, stripVideo } from 'sip.js/lib/platform/web/modifiers/modifiers';
23
- import { Registerer } from 'sip.js/lib/api/registerer';
24
- import { Inviter } from 'sip.js/lib/api/inviter';
23
+
25
24
  import { Messager } from 'sip.js/lib/api/messager';
26
25
  import { RegistererState } from 'sip.js/lib/api/registerer-state';
27
26
  import { SessionState } from 'sip.js/lib/api/session-state';
28
27
  import { TransportState } from 'sip.js/lib/api/transport-state';
29
- import { defaultPeerConnectionConfiguration }
30
- from 'sip.js/lib/platform/web/session-description-handler/peer-connection-configuration-default';
28
+ import { defaultPeerConnectionConfiguration } from 'sip.js/lib/platform/web/session-description-handler/peer-connection-configuration-default';
31
29
  import getStats from 'getstats';
32
30
 
31
+ import { OutgoingByeRequest, OutgoingInviteRequest, OutgoingRequest } from 'sip.js/lib/core';
32
+ import { Inviter, Invitation, Registerer } from 'sip.js/lib/api';
33
33
  import WazoSessionDescriptionHandler, { wazoMediaStreamFactory } from './lib/WazoSessionDescriptionHandler';
34
-
35
34
  import Emitter from './utils/Emitter';
36
35
  import ApiClient from './api-client';
37
36
  import IssueReporter from './service/IssueReporter';
@@ -40,19 +39,16 @@ import { getVideoDirection, hasAnActiveVideo } from './utils/sdp';
40
39
  import { lastIndexOf } from './utils/array';
41
40
 
42
41
  // We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
43
- export const replaceLocalIpModifier = (description: Object) => Promise.resolve({
44
- // description is immutable... so we have to clone it or the `type` attribute won't be returned.
42
+ export const replaceLocalIpModifier = (description: Record<string, any>) => Promise.resolve({ // description is immutable... so we have to clone it or the `type` attribute won't be returned.
45
43
  ...JSON.parse(JSON.stringify(description)),
46
44
  sdp: description.sdp.replace('c=IN IP4 0.0.0.0', 'c=IN IP4 127.0.0.1'),
47
45
  });
48
-
46
+ const SIP_ID_LENGTH = 36;
49
47
  const DEFAULT_ICE_TIMEOUT = 3000;
50
48
  const SEND_STATS_DELAY = 5000;
51
-
52
49
  const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
53
50
  const logger = IssueReporter ? IssueReporter.loggerFor('webrtc-client') : console;
54
51
  const statsLogger = IssueReporter ? IssueReporter.loggerFor('webrtc-stats') : console;
55
-
56
52
  // events
57
53
  const REGISTERED = 'registered';
58
54
  const UNREGISTERED = 'unregistered';
@@ -71,84 +67,121 @@ const ON_ERROR = 'onError';
71
67
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
72
68
  const ON_NETWORK_STATS = 'onNetworkStats';
73
69
  const ON_DISCONNECTED = 'onDisconnected';
74
-
75
70
  export const events = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
76
71
  export const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
77
72
  export class CanceledCallError extends Error {}
78
-
79
73
  const MAX_REGISTER_TRIES = 5;
80
-
81
74
  type MediaConfig = {
82
- audio: Object & boolean,
83
- video: Object & boolean,
84
- localVideo?: Object & boolean,
75
+ audio: Record<string, any> | boolean;
76
+ video?: Record<string, any> | boolean;
77
+ localVideo?: Record<string, any> | boolean;
85
78
  };
86
-
87
79
  type WebRtcConfig = {
88
- displayName: string,
89
- host: string,
90
- port?: number,
91
- websocketSip?: ?string,
92
- authorizationUser: ?string,
93
- password: ?string,
94
- uri: string,
95
- media: MediaConfig,
96
- iceCheckingTimeout: ?number,
97
- log?: Object,
98
- audioOutputDeviceId?: string,
80
+ displayName?: string;
81
+ host: string;
82
+ port?: number;
83
+ websocketSip?: string;
84
+ authorizationUser?: string;
85
+ password?: string;
86
+ uri?: string;
87
+ media?: MediaConfig;
88
+ iceCheckingTimeout?: number;
89
+ log?: Record<string, any>;
90
+ audioOutputDeviceId?: string;
99
91
  audioOutputVolume?: number;
100
- userAgentString?: string,
101
- heartbeatDelay: number,
102
- heartbeatTimeout: number,
103
- maxHeartbeats: number,
104
- skipRegister: boolean,
105
- };
92
+ userAgentString?: string;
93
+ heartbeatDelay?: number;
94
+ heartbeatTimeout?: number;
95
+ maxHeartbeats?: number;
96
+ skipRegister?: boolean;
97
+ }; // @see https://github.com/onsip/SIP.js/blob/master/src/Web/Simple.js
106
98
 
107
- // @see https://github.com/onsip/SIP.js/blob/master/src/Web/Simple.js
108
99
  export default class WebRTCClient extends Emitter {
100
+ clientId: number;
101
+
109
102
  config: WebRtcConfig;
110
- uaConfigOverrides: ?Object;
111
- userAgent: UserAgent;
112
- registerer: Registerer;
103
+
104
+ uaConfigOverrides: Record<string, any> | null | undefined;
105
+
106
+ userAgent: UserAgent | null;
107
+
108
+ registerer: Registerer | null;
109
+
113
110
  hasAudio: boolean;
114
- audio: Object | boolean;
115
- audioElements: { [string]: HTMLAudioElement };
116
- video: Object | boolean;
117
- audioStreams: Object;
118
- audioOutputDeviceId: ?string;
111
+
112
+ audio: MediaTrackConstraints | boolean | undefined;
113
+
114
+ audioElements: Record<string, HTMLAudioElement>;
115
+
116
+ video: MediaTrackConstraints | boolean | undefined;
117
+
118
+ audioStreams: Record<string, any>;
119
+
120
+ audioOutputDeviceId: string | null | undefined;
121
+
119
122
  audioOutputVolume: number;
120
- heldSessions: Object;
121
- connectionPromise: ?Promise<void>;
122
- _boundOnHeartbeat: Function;
123
+
124
+ heldSessions: Record<string, any>;
125
+
126
+ connectionPromise: Promise<void> | null | undefined;
127
+
128
+ _boundOnHeartbeat: (...args: Array<any>) => any;
129
+
123
130
  heartbeat: Heartbeat;
124
- heartbeatTimeoutCb: ?Function;
125
- heartbeatCb: ?Function;
126
- statsIntervals: Object;
127
- sipSessions: { [string]: Session };
128
- conferences: { [string]: boolean };
131
+
132
+ heartbeatTimeoutCb: ((...args: Array<any>) => any) | null | undefined;
133
+
134
+ heartbeatCb: ((...args: Array<any>) => any) | null | undefined;
135
+
136
+ statsIntervals: Record<string, any>;
137
+
138
+ sipSessions: Record<string, Invitation | Inviter>;
139
+
140
+ conferences: Record<string, boolean>;
141
+
129
142
  skipRegister: boolean;
130
- networkMonitoringInterval: { [string]: IntervalID };
131
- sessionNetworkStats: { [string]: Object };
143
+
144
+ networkMonitoringInterval: Record<string, any>;
145
+
146
+ sessionNetworkStats: Record<string, Record<string, any>>;
147
+
132
148
  forceClosed: boolean;
133
149
 
134
150
  // sugar
135
151
  ON_USER_AGENT: string;
152
+
136
153
  REGISTERED: string;
154
+
137
155
  UNREGISTERED: string;
156
+
138
157
  REGISTRATION_FAILED: string;
158
+
139
159
  INVITE: string;
160
+
140
161
  CONNECTED: string;
162
+
141
163
  DISCONNECTED: string;
164
+
142
165
  TRANSPORT_ERROR: string;
166
+
143
167
  MESSAGE: string;
168
+
144
169
  ACCEPTED: string;
170
+
145
171
  REJECTED: string;
172
+
146
173
  ON_TRACK: string;
174
+
147
175
  ON_REINVITE: string;
176
+
148
177
  ON_ERROR: string;
178
+
149
179
  ON_SCREEN_SHARING_REINVITE: string;
180
+
150
181
  ON_NETWORK_STATS: string;
182
+
151
183
  ON_EARLY_MEDIA: string;
184
+
152
185
  ON_DISCONNECTED: string;
153
186
 
154
187
  static isAPrivateIp(ip: string): boolean {
@@ -156,22 +189,28 @@ export default class WebRTCClient extends Emitter {
156
189
  return regex.exec(ip) == null;
157
190
  }
158
191
 
159
- static getIceServers(ip: string): Array<{ urls: Array<string> }> {
192
+ static getIceServers(ip: string): Array<{
193
+ urls: Array<string>;
194
+ }> {
160
195
  if (WebRTCClient.isAPrivateIp(ip)) {
161
- return [
162
- {
163
- urls: ['stun:stun.l.google.com:19302', 'stun:stun4.l.google.com:19302'],
164
- },
165
- ];
196
+ return [{
197
+ urls: ['stun:stun.l.google.com:19302', 'stun:stun4.l.google.com:19302'],
198
+ }];
166
199
  }
200
+
167
201
  return [];
168
202
  }
169
203
 
170
- constructor(config: WebRtcConfig, session: ?Session, uaConfigOverrides: ?Object) {
204
+ constructor(config: WebRtcConfig, session: Invitation | Inviter | null | undefined, uaConfigOverrides: Record<string, any> | null | undefined = undefined) {
171
205
  super();
206
+
207
+ // For debug purpose
208
+ this.clientId = Math.ceil(Math.random() * 1000);
209
+ logger.info('sdk webrtc constructor', { clientId: this.clientId });
210
+
172
211
  this.uaConfigOverrides = uaConfigOverrides;
173
212
  this.config = config;
174
- this.skipRegister = config.skipRegister;
213
+ this.skipRegister = config.skipRegister as boolean;
175
214
 
176
215
  this._buildConfig(config, session).then((newConfig: WebRtcConfig) => {
177
216
  this.config = newConfig;
@@ -183,7 +222,10 @@ export default class WebRTCClient extends Emitter {
183
222
 
184
223
  if (config.media) {
185
224
  this.configureMedia(config.media);
186
- this.setMediaConstraints({ audio: config.media.audio, video: config.media.video });
225
+ this.setMediaConstraints({
226
+ audio: config.media.audio,
227
+ video: config.media.video,
228
+ });
187
229
  }
188
230
 
189
231
  this.heldSessions = {};
@@ -194,12 +236,10 @@ export default class WebRTCClient extends Emitter {
194
236
  this.networkMonitoringInterval = {};
195
237
  this.sessionNetworkStats = {};
196
238
  this.forceClosed = false;
197
-
198
239
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
199
240
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
200
241
  this.heartbeat.setSendHeartbeat(this.pingServer.bind(this));
201
242
  this.heartbeat.setOnHeartbeatTimeout(this._onHeartbeatTimeout.bind(this));
202
-
203
243
  // sugar
204
244
  this.REGISTERED = REGISTERED;
205
245
  this.UNREGISTERED = UNREGISTERED;
@@ -231,36 +271,38 @@ export default class WebRTCClient extends Emitter {
231
271
  this.audio = media.audio;
232
272
  }
233
273
 
234
- createUserAgent(configOverrides: ?Object): UserAgent {
274
+ createUserAgent(configOverrides: Record<string, any> | null | undefined): UserAgent {
235
275
  const webRTCConfiguration = this._createWebRTCConfiguration(configOverrides);
236
- logger.info('sdk webrtc, creating UA', { webRTCConfiguration });
237
276
 
277
+ logger.info('sdk webrtc, creating UA', { webRTCConfiguration, clientId: this.clientId });
238
278
  webRTCConfiguration.delegate = {
239
279
  onConnect: this.onConnect.bind(this),
240
280
  onDisconnect: this.onDisconnect.bind(this),
241
281
  onInvite: (invitation: Invitation) => {
242
282
  logger.info('sdk webrtc on invite', {
243
283
  method: 'delegate.onInvite',
284
+ clientId: this.clientId,
244
285
  id: invitation.id,
286
+ // @ts-ignore
245
287
  remoteURI: invitation.remoteURI,
246
288
  });
289
+
247
290
  this._setupSession(invitation);
248
- const shouldAutoAnswer = !!invitation.request.getHeader('alert-info');
249
291
 
292
+ const shouldAutoAnswer = !!invitation.request.getHeader('alert-info');
250
293
  this.eventEmitter.emit(INVITE, invitation, this.sessionWantsToDoVideo(invitation), shouldAutoAnswer);
251
294
  },
252
295
  };
296
+ const ua: any = new UserAgent(webRTCConfiguration);
253
297
 
254
- const ua = new UserAgent(webRTCConfiguration);
255
298
  if (ua.transport && ua.transport.connectPromise) {
256
- ua.transport.connectPromise.catch((e => {
299
+ ua.transport.connectPromise.catch((e: any) => {
257
300
  logger.warn('Transport connect error', e);
258
- }));
301
+ });
259
302
  }
260
303
 
261
304
  ua.transport.onMessage = (rawMessage: string) => {
262
305
  const message = Parser.parseMessage(rawMessage, ua.transport.logger);
263
-
264
306
  // We have to re-sent the message to the UA ...
265
307
  ua.onTransportMessage(rawMessage);
266
308
  // And now do what we want with the message
@@ -268,7 +310,9 @@ export default class WebRTCClient extends Emitter {
268
310
 
269
311
  if (message && message.method === C.MESSAGE) {
270
312
  // We have to manually reply to MESSAGE with a 200 OK or Asterisk will hangup.
271
- ua.userAgentCore.replyStateless(message, { statusCode: 200 });
313
+ ua.userAgentCore.replyStateless(message, {
314
+ statusCode: 200,
315
+ });
272
316
  }
273
317
  };
274
318
 
@@ -276,51 +320,61 @@ export default class WebRTCClient extends Emitter {
276
320
  }
277
321
 
278
322
  isConnected(): boolean {
279
- return this.userAgent && this.userAgent.isConnected();
323
+ return Boolean(this.userAgent?.isConnected());
280
324
  }
281
325
 
282
326
  isConnecting(): boolean {
283
- return this.userAgent && this.userAgent.transport && this.userAgent.transport.state === TransportState.Connecting;
327
+ return this.userAgent?.transport?.state === TransportState.Connecting;
284
328
  }
285
329
 
286
330
  isRegistered(): boolean {
287
- return this.registerer && this.registerer.state === RegistererState.Registered;
331
+ return Boolean(this.registerer && this.registerer.state === RegistererState.Registered);
288
332
  }
289
333
 
290
334
  onConnect() {
291
- logger.info('sdk webrtc connected', { method: 'delegate.onConnect' });
335
+ logger.info('sdk webrtc connected', { method: 'delegate.onConnect', clientId: this.clientId });
292
336
  this.eventEmitter.emit(CONNECTED);
293
- if (!this.isRegistered() && this.registerer && this.registerer.waiting) {
337
+
338
+ // @ts-ignore
339
+ if (!this.isRegistered() && this.registerer?.waiting) {
340
+ // @ts-ignore
294
341
  this.registerer.waitingToggle(false);
295
342
  }
343
+
296
344
  return this.register();
297
345
  }
298
346
 
299
347
  async onDisconnect(error?: Error) {
300
- logger.info('sdk webrtc disconnected', { method: 'delegate.onConnect', error });
348
+ logger.info('sdk webrtc disconnected', { method: 'delegate.onConnect', clientId: this.clientId, error });
301
349
  this.connectionPromise = null;
302
350
  // The UA will attempt to reconnect automatically when an error occurred
303
351
  this.eventEmitter.emit(DISCONNECTED, error);
352
+
304
353
  if (this.isRegistered()) {
305
354
  await this.unregister();
306
- if (this.registerer && this.registerer.waiting) {
355
+
356
+ // @ts-ignore
357
+ if (this.registerer?.waiting) {
358
+ // @ts-ignore
307
359
  this.registerer.waitingToggle(false);
308
360
  }
361
+
309
362
  this.eventEmitter.emit(UNREGISTERED);
310
363
  }
311
364
  }
312
365
 
313
- register(tries: number = 0): Promise<any> {
366
+ async register(tries = 0): Promise<void> {
314
367
  const logInfo = {
368
+ clientId: this.clientId,
315
369
  userAgent: !!this.userAgent,
316
370
  registered: this.isRegistered(),
317
371
  connectionPromise: !!this.connectionPromise,
318
372
  registerer: !!this.registerer,
373
+ // @ts-ignore
319
374
  waiting: this.registerer && this.registerer.waiting,
320
375
  tries,
321
376
  skipRegister: this.skipRegister,
322
377
  };
323
-
324
378
  this.forceClosed = false;
325
379
 
326
380
  if (this.skipRegister) {
@@ -334,35 +388,44 @@ export default class WebRTCClient extends Emitter {
334
388
  logger.info('sdk webrtc recreating User Agent');
335
389
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
336
390
  }
391
+
337
392
  if (!this.userAgent || this.isRegistered()) {
338
393
  logger.info('sdk webrtc registering aborted, already registered or no UA can be created');
339
394
  return Promise.resolve();
340
395
  }
341
396
 
342
- if (this.connectionPromise || (this.registerer && this.registerer.waiting)) {
343
- logger.info('sdk webrtc registering aborted due to a registration in progress.');
397
+ // @ts-ignore
398
+ if (this.connectionPromise || this.registerer?.waiting) {
399
+ logger.info('sdk webrtc registering aborted due to a registration in progress.', { clientId: this.clientId });
344
400
  return Promise.resolve();
345
401
  }
346
402
 
347
- const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
403
+ const registerOptions = this._isWeb() ? {} : {
404
+ extraContactHeaderParams: ['mobility=mobile'],
405
+ };
348
406
 
349
407
  const onRegisterFailed = () => {
350
408
  logger.info('sdk webrtc registering failed', {
351
409
  tries,
410
+ clientId: this.clientId,
352
411
  registerer: !!this.registerer,
353
412
  forceClosed: this.forceClosed,
354
413
  });
414
+
355
415
  if (this.forceClosed) {
356
416
  return;
357
417
  }
358
418
 
359
419
  this.connectionPromise = null;
420
+
421
+ // @ts-ignore
360
422
  if (this.registerer && this.registerer.waiting) {
423
+ // @ts-ignore
361
424
  this.registerer.waitingToggle(false);
362
425
  }
363
426
 
364
427
  if (tries <= MAX_REGISTER_TRIES) {
365
- logger.info('sdk webrtc registering, retrying...', { tries });
428
+ logger.info('sdk webrtc registering, retrying...', { clientId: this.clientId, tries });
366
429
  setTimeout(() => this.register(tries + 1), 300);
367
430
  }
368
431
  };
@@ -375,36 +438,32 @@ export default class WebRTCClient extends Emitter {
375
438
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
376
439
  }
377
440
 
378
- logger.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent });
441
+ logger.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent, clientId: this.clientId });
379
442
  this.registerer = new Registerer(this.userAgent, registerOptions);
380
443
  this.connectionPromise = null;
444
+
381
445
  this._monkeyPatchRegisterer(this.registerer);
382
446
 
383
447
  // Bind registerer events
384
448
  this.registerer.stateChange.addListener(newState => {
385
- logger.info('sdk webrtc registering, state changed', { newState });
449
+ logger.info('sdk webrtc registering, state changed', { newState, clientId: this.clientId });
386
450
 
387
- if (newState === RegistererState.Registered && this.registerer
388
- && this.registerer.state === RegistererState.Registered) {
451
+ if (newState === RegistererState.Registered && this.registerer && this.registerer.state === RegistererState.Registered) {
389
452
  this.eventEmitter.emit(REGISTERED);
390
453
  } else if (newState === RegistererState.Unregistered) {
391
454
  this.eventEmitter.emit(UNREGISTERED);
392
455
  }
393
456
  });
394
-
395
457
  const options = {
396
458
  requestDelegate: {
397
- onReject: response => {
398
- logger.error('sdk webrtc registering, rejected', { response });
399
-
459
+ onReject: (response: any) => {
460
+ logger.error('sdk webrtc registering, rejected', { clientId: this.clientId, response });
400
461
  onRegisterFailed();
401
462
  },
402
463
  },
403
464
  };
404
-
405
- return this.registerer.register(options).catch((e) => {
465
+ return this.registerer.register(options).catch(e => {
406
466
  logger.error('sdk webrtc registering, error', e);
407
-
408
467
  this.eventEmitter.emit(REGISTRATION_FAILED);
409
468
  return e;
410
469
  });
@@ -415,52 +474,69 @@ export default class WebRTCClient extends Emitter {
415
474
  }
416
475
 
417
476
  // Monkey patching sip.js to avoid issues during register.onReject
418
- _monkeyPatchRegisterer(registerer: ?Registerer) {
477
+ _monkeyPatchRegisterer(registerer: Registerer | null | undefined): void {
419
478
  if (!registerer) {
420
479
  return;
421
480
  }
481
+
482
+ // @ts-ignore
422
483
  const oldWaitingToggle = registerer.waitingToggle.bind(registerer);
484
+ // @ts-ignore
423
485
  const oldUnregistered = registerer.unregistered.bind(registerer);
424
486
 
487
+ // @ts-ignore
425
488
  registerer.waitingToggle = (waiting: boolean) => {
489
+ // @ts-ignore
426
490
  if (!registerer || registerer.waiting === waiting) {
427
491
  return;
428
492
  }
493
+
429
494
  oldWaitingToggle(waiting);
430
495
  };
431
496
 
497
+ // @ts-ignore
432
498
  registerer.unregistered = () => {
433
499
  if (!registerer || registerer.state === RegistererState.Terminated) {
434
500
  return;
435
501
  }
502
+
436
503
  oldUnregistered();
437
504
  };
438
505
  }
439
506
 
440
- unregister() {
441
- logger.info('sdk webrtc unregistering..', { userAgent: !!this.userAgent, registerer: !!this.registerer });
507
+ async unregister(): Promise<void> {
508
+ logger.info('sdk webrtc unregistering..', {
509
+ clientId: this.clientId,
510
+ userAgent: !!this.userAgent,
511
+ registerer: !!this.registerer,
512
+ });
513
+
442
514
  if (!this.registerer) {
443
515
  return Promise.resolve();
444
516
  }
445
517
 
446
518
  try {
447
519
  return this.registerer.unregister().then(() => {
448
- logger.info('sdk webrtc unregistered');
520
+ logger.info('sdk webrtc unregistered', { clientId: this.clientId });
521
+
449
522
  this._cleanupRegister();
450
523
  }).catch(e => {
451
524
  logger.error('sdk webrtc unregistering, promise error', e);
525
+
452
526
  this._cleanupRegister();
453
527
  });
454
- } catch (e) {
528
+ } catch (e: any) {
455
529
  logger.error('sdk webrtc unregistering, error', e);
530
+
456
531
  // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
457
532
  // error when the registerer is in a bad state
458
533
  this._cleanupRegister();
459
534
  }
460
535
  }
461
536
 
462
- stop(): Promise<any> {
463
- logger.info('sdk webrtc stop', { userAgent: !!this.userAgent });
537
+ stop(): Promise<void> {
538
+ logger.info('sdk webrtc stop', { clientId: this.clientId, userAgent: !!this.userAgent });
539
+
464
540
  if (!this.userAgent) {
465
541
  return Promise.resolve();
466
542
  }
@@ -468,13 +544,22 @@ export default class WebRTCClient extends Emitter {
468
544
  return this.userAgent.stop().then(() => {
469
545
  return this._cleanupRegister();
470
546
  }).catch(e => {
471
- logger.warn('sdk webrtc stop, error', { message: e.message, stack: e.stack });
547
+ logger.warn('sdk webrtc stop, error', {
548
+ message: e.message,
549
+ stack: e.stack,
550
+ });
472
551
  });
473
552
  }
474
553
 
475
- call(number: string, enableVideo?: boolean, audioOnly: boolean = false, conference: boolean = false): Session {
476
- logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
477
- const inviterOptions: Object = {
554
+ call(number: string, enableVideo?: boolean, audioOnly = false, conference = false): Inviter | Invitation {
555
+ logger.info('sdk webrtc creating call', {
556
+ clientId: this.clientId,
557
+ number,
558
+ enableVideo,
559
+ audioOnly,
560
+ conference,
561
+ });
562
+ const inviterOptions: Record<string, any> = {
478
563
  sessionDescriptionHandlerOptionsReInvite: {
479
564
  conference,
480
565
  audioOnly,
@@ -486,11 +571,20 @@ export default class WebRTCClient extends Emitter {
486
571
  inviterOptions.sessionDescriptionHandlerModifiersReInvite = [stripVideo];
487
572
  }
488
573
 
489
- const session = new Inviter(this.userAgent, this._makeURI(number), inviterOptions);
574
+ const uri = this._makeURI(number);
575
+ let session: any;
490
576
 
491
- this.storeSipSession(session);
577
+ if (uri) {
578
+ session = this.userAgent ? new Inviter(this.userAgent, uri, inviterOptions) : null;
579
+ } else {
580
+ logger.error('Null URI');
581
+ }
492
582
 
493
- this._setupSession(session);
583
+ if (session) {
584
+ this.storeSipSession(session);
585
+
586
+ this._setupSession(session);
587
+ }
494
588
 
495
589
  if (conference) {
496
590
  this.conferences[this.getSipSessionId(session)] = true;
@@ -499,71 +593,93 @@ export default class WebRTCClient extends Emitter {
499
593
  const inviteOptions: InviterInviteOptions = {
500
594
  requestDelegate: {
501
595
  onAccept: (response: IncomingResponse) => {
502
- if (session.sessionDescriptionHandler.peerConnection) {
596
+ // @ts-ignore
597
+ if (session.sessionDescriptionHandler?.peerConnection) {
598
+ // @ts-ignore
503
599
  session.sessionDescriptionHandler.peerConnection.sfu = conference;
504
600
  }
601
+ // @ts-ignore
505
602
  this._onAccepted(session, response.session, true);
506
603
  },
507
- onProgress: (payload) => {
604
+ onProgress: payload => {
508
605
  if (payload.message.statusCode === 183) {
606
+ // @ts-ignore
509
607
  this._onEarlyProgress(payload.session);
510
608
  }
511
609
  },
512
610
  onReject: (response: IncomingResponse) => {
513
- logger.info('on call rejected', { id: session.id, fromTag: session.fromTag });
611
+ logger.info('on call rejected', {
612
+ id: session.id,
613
+ // @ts-ignore
614
+ fromTag: session.fromTag,
615
+ });
616
+
514
617
  this._stopSendingStats(session);
515
- this.stopNetworkMonitoring(session);
516
618
 
619
+ this.stopNetworkMonitoring(session);
517
620
  this.eventEmitter.emit(REJECTED, session, response);
518
621
  },
519
622
  },
520
623
  sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
521
624
  };
522
625
 
523
- inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
524
-
626
+ if (inviteOptions.sessionDescriptionHandlerOptions) {
627
+ // @ts-ignore
628
+ inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
629
+ }
525
630
  inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
631
+
526
632
  if (audioOnly) {
527
633
  inviteOptions.sessionDescriptionHandlerModifiers.push(stripVideo);
528
634
  }
529
635
 
530
636
  // Do not await invite here or we'll miss the Establishing state transition
531
- session.invitePromise = session.invite(inviteOptions);
637
+ session.invitePromise = session.invite(inviteOptions).catch((e: Error) => {
638
+ logger.warn('sdk webrtc creating call, error', e);
639
+ });
640
+
532
641
  return session;
533
642
  }
534
643
 
535
- answer(session: Invitation, enableVideo?: boolean) {
536
- logger.info('sdk webrtc answer call', { id: session.id, enableVideo });
644
+ answer(session: Invitation, enableVideo?: boolean): Promise<void> {
645
+ logger.info('sdk webrtc answer call', {
646
+ clientId: this.clientId,
647
+ id: session.id,
648
+ enableVideo,
649
+ });
537
650
 
538
651
  if (!session || !session.accept) {
539
652
  const error = 'No session to answer, or not an invitation';
540
653
  logger.warn(error);
541
654
  return Promise.reject(new Error(error));
542
655
  }
656
+
543
657
  const options = {
544
658
  sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false),
545
659
  };
546
-
547
- return session.accept(options).then(() => {
660
+ return this._accept(session, options).then(() => {
661
+ // @ts-ignore
548
662
  if (session.isCanceled) {
549
663
  const message = 'accepted a canceled session (or was canceled during the accept phase).';
550
- logger.error(message, { id: session.id });
664
+ logger.error(message, {
665
+ id: session.id,
666
+ });
551
667
  this.onCallEnded(session);
552
-
553
668
  throw new CanceledCallError(message);
554
669
  }
670
+
555
671
  logger.info('sdk webrtc answer, accepted.');
672
+
556
673
  this._onAccepted(session);
557
674
  }).catch(e => {
558
675
  logger.error(`answer call error for ${session ? session.id : 'n/a'}`, e);
559
-
560
676
  throw e;
561
677
  });
562
678
  }
563
679
 
564
- hangup(session: Session) {
565
- const { state, id } = session;
566
- logger.info('sdk webrtc hangup call', { id, state });
680
+ async hangup(session: Invitation | Inviter): Promise<OutgoingByeRequest | null> {
681
+ const { state, id }: any = session;
682
+ logger.info('sdk webrtc hangup call', { clientId: this.clientId, id, state });
567
683
 
568
684
  try {
569
685
  this._stopSendingStats(session);
@@ -571,35 +687,33 @@ export default class WebRTCClient extends Emitter {
571
687
  this._cleanupMedia(session);
572
688
 
573
689
  delete this.sipSessions[this.getSipSessionId(session)];
574
-
575
690
  // Check if Invitation or Inviter (Invitation = incoming call)
576
691
  const isInviter = session instanceof Inviter;
577
- const cancel = () => session.cancel();
578
- const reject = () => session.reject();
579
- const bye = () => session.bye && session.bye();
580
692
 
581
693
  // @see github.com/onsip/SIP.js/blob/f11dfd584bc9788ccfc94e03034020672b738975/src/platform/web/simple-user/simple-user.ts#L1004
582
- const actions = {
583
- [SessionState.Initial]: isInviter ? cancel : reject,
584
- [SessionState.Establishing]: isInviter ? cancel : reject,
585
- [SessionState.Established]: bye,
694
+ const actions: Record<string, any> = {
695
+ [SessionState.Initial]: isInviter ? this._cancel.bind(this, session) : this._reject.bind(this, session),
696
+ [SessionState.Establishing]: isInviter ? this._cancel.bind(this, session) : this._reject.bind(this, session),
697
+ [SessionState.Established]: this._bye.bind(this, session),
586
698
  };
587
699
 
588
700
  // Handle different session status
589
701
  if (actions[state]) {
590
- return actions[state]();
702
+ return await actions[state]();
591
703
  }
592
704
 
593
- return bye();
594
- } catch (error) {
705
+ return await this._bye(session);
706
+ } catch (error: any) {
595
707
  logger.warn('sdk webrtc hangup, error', error);
596
708
  }
597
709
 
598
- return null;
710
+ return Promise.resolve(null);
599
711
  }
600
712
 
601
- async getStats(session: Session): ?Object {
602
- const pc = session.sessionDescriptionHandler.peerConnection;
713
+ async getStats(session: Invitation | Inviter): Promise<RTCStatsReport | null> {
714
+ // @ts-ignore
715
+ const pc: RTCPeerConnection = session.sessionDescriptionHandler.peerConnection;
716
+
603
717
  if (!pc) {
604
718
  return null;
605
719
  }
@@ -608,101 +722,131 @@ export default class WebRTCClient extends Emitter {
608
722
  }
609
723
 
610
724
  // Fetch and emit an event at `interval` with session network stats
611
- startNetworkMonitoring(session: Session, interval: number = 1000): ?Object {
725
+ startNetworkMonitoring(session: Inviter | Invitation, interval = 1000): void {
612
726
  const sessionId = this.getSipSessionId(session);
613
- logger.info('starting network inspection', { id: sessionId });
614
-
727
+ logger.info('starting network inspection', {
728
+ id: sessionId,
729
+ clientId: this.clientId,
730
+ });
615
731
  this.sessionNetworkStats[sessionId] = [];
616
-
617
732
  this.networkMonitoringInterval[sessionId] = setInterval(() => this._fetchNetworkStats(sessionId), interval);
618
733
  }
619
734
 
620
- stopNetworkMonitoring(session: Session): ?Object {
735
+ stopNetworkMonitoring(session: Inviter | Invitation): void {
621
736
  const sessionId = this.getSipSessionId(session);
622
- const exists = sessionId in this.networkMonitoringInterval;
623
- logger.info('stopping network inspection', { id: sessionId, exists });
737
+ const exists = (sessionId in this.networkMonitoringInterval);
738
+ logger.info('stopping network inspection', {
739
+ clientId: this.clientId,
740
+ id: sessionId,
741
+ exists,
742
+ });
624
743
 
625
744
  if (exists) {
626
- clearInterval(this.networkMonitoringInterval[sessionId]);
745
+ clearInterval(this.networkMonitoringInterval[sessionId] as string);
627
746
  delete this.networkMonitoringInterval[sessionId];
628
747
  delete this.sessionNetworkStats[sessionId];
629
748
  }
630
749
  }
631
750
 
632
- reject(session: Inviter) {
633
- logger.info('sdk webrtc reject call', { id: session.id });
751
+ async reject(session: Invitation | Inviter): Promise<void> {
752
+ logger.info('sdk webrtc reject call', {
753
+ clientId: this.clientId,
754
+ id: session.id,
755
+ });
634
756
 
635
757
  try {
636
- return session.reject ? session.reject() : session.cancel();
637
- } catch (e) {
758
+ if (session instanceof Invitation) {
759
+ return this._reject(session);
760
+ }
761
+
762
+ if (session instanceof Inviter) {
763
+ return this._cancel(session);
764
+ }
765
+ } catch (e: any) {
638
766
  logger.warn('Error when rejecting call', e.message, e.stack);
639
767
  }
640
768
  }
641
769
 
642
- async close(force: boolean = false) {
643
- logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
770
+ async close(force = false): Promise<void> {
771
+ logger.info('sdk webrtc closing client', {
772
+ clientId: this.clientId,
773
+ userAgent: !!this.userAgent,
774
+ force,
775
+ });
644
776
  this.forceClosed = force;
777
+
645
778
  this._cleanupMedia();
646
- this.connectionPromise = null;
647
779
 
648
- (Object.values(this.audioElements): any).forEach((audioElement: HTMLAudioElement) => {
780
+ this.connectionPromise = null;
781
+ (Object.values(this.audioElements) as any).forEach((audioElement: HTMLAudioElement) => {
649
782
  // eslint-disable-next-line
650
783
  audioElement.srcObject = null;
651
784
  audioElement.pause();
652
785
  });
653
-
654
786
  this.audioElements = {};
787
+
655
788
  if (!this.userAgent) {
656
- return null;
789
+ return;
657
790
  }
658
791
 
659
792
  this.stopHeartbeat();
660
- this.userAgent.delegate = null;
793
+ if (this.userAgent) {
794
+ this.userAgent.delegate = undefined;
795
+ }
796
+ // @ts-ignore: this is odd, may want to validate
661
797
  this.userAgent.stateChange.removeAllListeners();
662
-
663
798
  await this._disconnectTransport(force);
664
799
 
665
800
  this._cleanupRegister();
666
801
 
667
802
  try {
803
+ // Prevent `Connect aborted.` error when disconnecting
804
+ // @ts-ignore
805
+ this.userAgent.transport.connectReject = () => {};
668
806
  // Don't wait here, It can take ~30s to stop ...
669
807
  this.userAgent.stop().catch(console.error);
670
- } catch (_) {
671
- // Avoid to raise exception when trying to close with hanged-up sessions remaining
808
+ } catch (_) { // Avoid to raise exception when trying to close with hanged-up sessions remaining
672
809
  // eg: "INVITE not rejectable in state Completed"
673
810
  }
811
+
674
812
  this.userAgent = null;
675
- logger.info('sdk webrtc client closed');
813
+ logger.info('sdk webrtc client closed', { clientId: this.clientId });
676
814
  }
677
815
 
678
- getNumber(session: Inviter): ?String {
816
+ getNumber(session: Inviter): string | null | undefined {
679
817
  if (!session) {
680
818
  return null;
681
819
  }
682
820
 
683
- // eslint-disable-next-line
821
+ // @ts-ignore
684
822
  return session.remoteIdentity.uri._normal.user;
685
823
  }
686
824
 
687
- mute(session: Inviter) {
688
- logger.info('sdk webrtc mute', { id: session.id });
825
+ mute(session: Inviter | Invitation): void {
826
+ logger.info('sdk webrtc mute', {
827
+ id: session.id,
828
+ });
689
829
 
690
830
  this._toggleAudio(session, true);
691
831
  }
692
832
 
693
- unmute(session: Inviter) {
694
- logger.info('sdk webrtc unmute', { id: session.id });
833
+ unmute(session: Inviter | Invitation): void {
834
+ logger.info('sdk webrtc unmute', {
835
+ id: session.id,
836
+ });
695
837
 
696
838
  this._toggleAudio(session, false);
697
839
  }
698
840
 
699
- isAudioMuted(session: Inviter): boolean {
841
+ isAudioMuted(session: Inviter | Invitation): boolean {
700
842
  if (!session || !session.sessionDescriptionHandler) {
701
843
  return false;
702
844
  }
703
845
 
704
846
  let muted = true;
847
+ // @ts-ignore
705
848
  const pc = session.sessionDescriptionHandler.peerConnection;
849
+
706
850
  if (!pc) {
707
851
  return false;
708
852
  }
@@ -711,7 +855,8 @@ export default class WebRTCClient extends Emitter {
711
855
  if (!pc.getSenders().length) {
712
856
  return false;
713
857
  }
714
- pc.getSenders().forEach(sender => {
858
+
859
+ pc.getSenders().forEach((sender: any) => {
715
860
  if (sender && sender.track && sender.track.kind === 'audio') {
716
861
  muted = muted && !sender.track.enabled;
717
862
  }
@@ -720,7 +865,8 @@ export default class WebRTCClient extends Emitter {
720
865
  if (!pc.getLocalStreams().length) {
721
866
  return false;
722
867
  }
723
- pc.getLocalStreams().forEach(stream => {
868
+
869
+ pc.getLocalStreams().forEach((stream: MediaStream) => {
724
870
  stream.getAudioTracks().forEach(track => {
725
871
  muted = muted && !track.enabled;
726
872
  });
@@ -730,25 +876,29 @@ export default class WebRTCClient extends Emitter {
730
876
  return muted;
731
877
  }
732
878
 
733
- toggleCameraOn(session: Inviter) {
734
- logger.info('sdk webrtc toggle camera on', { id: session.id });
879
+ toggleCameraOn(session: Inviter | Invitation): void {
880
+ logger.info('sdk webrtc toggle camera on', {
881
+ id: session.id,
882
+ });
735
883
 
736
884
  this._toggleVideo(session, false);
737
885
  }
738
886
 
739
- toggleCameraOff(session: Inviter) {
740
- logger.info('sdk webrtc toggle camera off', { id: session.id });
887
+ toggleCameraOff(session: Inviter | Invitation): void {
888
+ logger.info('sdk webrtc toggle camera off', {
889
+ id: session.id,
890
+ });
741
891
 
742
892
  this._toggleVideo(session, true);
743
893
  }
744
894
 
745
- hold(session: Inviter, isConference: boolean = false, hadVideo: boolean = false) {
895
+ hold(session: Inviter | Invitation, isConference = false, hadVideo = false): Promise<OutgoingInviteRequest | void> {
746
896
  const sessionId = this.getSipSessionId(session);
747
897
  const hasVideo = hadVideo || this.hasLocalVideo(sessionId);
748
-
749
898
  logger.info('sdk webrtc hold', {
750
899
  sessionId,
751
900
  keys: Object.keys(this.heldSessions),
901
+ // @ts-ignore
752
902
  pendingReinvite: !!session.pendingReinvite,
753
903
  isConference,
754
904
  hasVideo,
@@ -757,9 +907,12 @@ export default class WebRTCClient extends Emitter {
757
907
  if (sessionId in this.heldSessions) {
758
908
  return Promise.resolve();
759
909
  }
910
+
911
+ // @ts-ignore
760
912
  if (session.pendingReinvite) {
761
913
  return Promise.resolve();
762
914
  }
915
+
763
916
  this.heldSessions[sessionId] = {
764
917
  hasVideo,
765
918
  isConference,
@@ -770,14 +923,16 @@ export default class WebRTCClient extends Emitter {
770
923
  }
771
924
 
772
925
  session.sessionDescriptionHandlerOptionsReInvite = {
926
+ // @ts-ignore
773
927
  hold: true,
774
928
  conference: isConference,
775
929
  };
776
-
777
930
  const options = this.getMediaConfiguration(false, isConference);
931
+
778
932
  if (!this._isWeb()) {
779
933
  options.sessionDescriptionHandlerModifiers = [holdModifier];
780
934
  }
935
+
781
936
  options.sessionDescriptionHandlerOptions = {
782
937
  constraints: options.constraints,
783
938
  hold: true,
@@ -786,25 +941,29 @@ export default class WebRTCClient extends Emitter {
786
941
 
787
942
  // Avoid sdh to create a new stream
788
943
  if (session.sessionDescriptionHandler) {
944
+ // @ts-ignore
789
945
  session.sessionDescriptionHandler.localMediaStreamConstraints = options.constraints;
790
946
  }
791
947
 
792
948
  // Send re-INVITE
793
- return session.invite(options);
949
+ return session.invite(options).catch((e: Error) => {
950
+ logger.warn('sdk webrtc re-invite during hold, error', e);
951
+ });
794
952
  }
795
953
 
796
- unhold(session: Inviter, isConference: boolean = false) {
954
+ unhold(session: Inviter | Invitation, isConference = false): Promise<OutgoingInviteRequest | void> {
797
955
  const sessionId = this.getSipSessionId(session);
798
956
  const hasVideo = sessionId in this.heldSessions && this.heldSessions[sessionId].hasVideo;
799
-
800
957
  logger.info('sdk webrtc unhold', {
801
958
  sessionId,
802
959
  keys: Object.keys(this.heldSessions),
960
+ // @ts-ignore
803
961
  pendingReinvite: !!session.pendingReinvite,
804
962
  isConference,
805
963
  hasVideo,
806
964
  });
807
965
 
966
+ // @ts-ignore
808
967
  if (session.pendingReinvite) {
809
968
  return Promise.resolve();
810
969
  }
@@ -815,111 +974,119 @@ export default class WebRTCClient extends Emitter {
815
974
 
816
975
  delete this.heldSessions[this.getSipSessionId(session)];
817
976
  session.sessionDescriptionHandlerOptionsReInvite = {
977
+ // @ts-ignore
818
978
  hold: false,
819
979
  conference: isConference,
820
980
  };
821
-
822
981
  const options = this.getMediaConfiguration(false, isConference);
982
+
823
983
  if (!this._isWeb()) {
824
984
  // We should sent an empty `sessionDescriptionHandlerModifiers` or sip.js will take the last sent modifiers
825
985
  // (eg: holdModifier)
826
986
  options.sessionDescriptionHandlerModifiers = [];
827
987
  }
988
+
828
989
  options.sessionDescriptionHandlerOptions = {
829
990
  constraints: options.constraints,
830
991
  hold: false,
831
992
  conference: isConference,
832
993
  };
833
-
834
994
  // Send re-INVITE
835
- return session.invite(options);
995
+ return session.invite(options).catch((e: Error) => {
996
+ logger.warn('sdk webrtc re-invite during resume, error', e);
997
+ });
836
998
  }
837
999
 
838
1000
  // Returns true if a re-INVITE is required
839
- async upgradeToVideo(session: Session, constraints: ?Object, isConference: boolean): Promise<?Object> {
1001
+ async upgradeToVideo(session: Inviter | Invitation, constraints: Record<string, any>, isConference: boolean): Promise<MediaStream | undefined> {
1002
+ // @ts-ignore
840
1003
  const pc = session.sessionDescriptionHandler.peerConnection;
841
-
842
1004
  // Check if a video sender already exists
843
1005
  let videoSender;
1006
+
844
1007
  if (isConference) {
845
1008
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
846
1009
  const transceivers = pc.getTransceivers();
847
- const transceiverIdx = lastIndexOf(transceivers, transceiver =>
848
- transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
849
-
1010
+ const transceiverIdx = lastIndexOf(transceivers, transceiver => transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
850
1011
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
851
1012
  } else {
852
- videoSender = pc && pc.getSenders && pc.getSenders().find(sender => sender.track === null);
1013
+ videoSender = pc && pc.getSenders && pc.getSenders().find((sender: any) => sender.track === null);
853
1014
  }
854
1015
 
855
1016
  if (!videoSender) {
856
1017
  // When no video sender found, it means that we're in the first video upgrade in 1:1
857
- return null;
1018
+ return;
858
1019
  }
859
1020
 
860
1021
  // Reuse bidirectional video stream
861
1022
  const newStream = await this.getStreamFromConstraints(constraints);
1023
+
862
1024
  if (!newStream) {
863
1025
  console.warn(`Can't create media stream with: ${JSON.stringify(constraints || {})}`);
864
- return false;
1026
+ return;
865
1027
  }
866
1028
 
867
1029
  // Add previous local audio track
868
1030
  if (constraints && !constraints.audio) {
869
- const localVideoStream = session.sessionDescriptionHandler.localMediaStream;
1031
+ // @ts-ignore
1032
+ const localVideoStream: MediaStream = session.sessionDescriptionHandler.localMediaStream;
870
1033
  const localAudioTrack = localVideoStream.getTracks().find(track => track.kind === 'audio');
1034
+
871
1035
  if (localAudioTrack) {
872
1036
  newStream.addTrack(localAudioTrack);
873
1037
  }
874
1038
  }
875
1039
 
876
1040
  const videoTrack = newStream.getVideoTracks()[0];
1041
+
877
1042
  if (videoTrack) {
878
1043
  videoSender.replaceTrack(videoTrack);
879
1044
  }
880
1045
 
881
1046
  this.setLocalMediaStream(this.getSipSessionId(session), newStream);
882
-
883
1047
  return newStream;
884
1048
  }
885
1049
 
886
- downgradeToAudio(session: Session) {
1050
+ downgradeToAudio(session: Invitation | Inviter): void {
887
1051
  // Release local video stream when downgrading to audio
1052
+ // @ts-ignore
888
1053
  const localStream = session.sessionDescriptionHandler.localMediaStream;
1054
+ // @ts-ignore
889
1055
  const pc = session.sessionDescriptionHandler.peerConnection;
890
1056
  const videoTracks = localStream.getVideoTracks();
891
1057
 
892
1058
  // Remove video senders
893
1059
  if (pc.getSenders) {
894
- pc.getSenders().filter(sender => sender.track && sender.track.kind === 'video').forEach(videoSender => {
1060
+ pc.getSenders().filter((sender: any) => sender.track && sender.track.kind === 'video').forEach((videoSender: any) => {
895
1061
  videoSender.replaceTrack(null);
896
1062
  });
897
1063
  }
898
1064
 
899
- videoTracks.forEach(videoTrack => {
1065
+ videoTracks.forEach((videoTrack: MediaStreamTrack) => {
900
1066
  videoTrack.enabled = false;
901
1067
  videoTrack.stop();
902
1068
  localStream.removeTrack(videoTrack);
903
1069
  });
904
1070
  }
905
1071
 
906
- async getStreamFromConstraints(constraints: Object, conference: boolean = false): Promise<?MediaStream> {
1072
+ async getStreamFromConstraints(constraints: Record<string, any>, conference = false): Promise<MediaStream | null | undefined> {
907
1073
  const video = constraints && constraints.video;
908
- // $FlowFixMe
909
- const { constraints: newConstraints } = this.getMediaConfiguration(video, conference, constraints);
910
-
1074
+ const {
1075
+ constraints: newConstraints,
1076
+ } = this.getMediaConfiguration(video, conference, constraints);
911
1077
  let newStream;
1078
+
912
1079
  try {
913
1080
  newStream = await wazoMediaStreamFactory(newConstraints);
914
- } catch (e) {
915
- // Nothing to do when the user cancel the screensharing prompt
1081
+ } catch (e: any) { // Nothing to do when the user cancel the screensharing prompt
916
1082
  }
1083
+
917
1084
  if (!newStream) {
918
1085
  return null;
919
1086
  }
920
- // $FlowFixMe
921
- newStream.local = true;
922
1087
 
1088
+ // @ts-ignore
1089
+ newStream.local = true;
923
1090
  return newStream;
924
1091
  }
925
1092
 
@@ -927,26 +1094,27 @@ export default class WebRTCClient extends Emitter {
927
1094
  return this.heldSessions[sessionId];
928
1095
  }
929
1096
 
930
- isCallHeld(session: Inviter) {
1097
+ isCallHeld(session: Inviter | Invitation): boolean {
931
1098
  return this.getSipSessionId(session) in this.heldSessions;
932
1099
  }
933
1100
 
934
- isVideoRemotelyHeld(sessionId: string) {
1101
+ isVideoRemotelyHeld(sessionId: string): boolean {
935
1102
  const pc = this.getPeerConnection(sessionId);
936
1103
  const sdp = pc && pc.remoteDescription ? pc.remoteDescription.sdp : null;
1104
+
937
1105
  if (!sdp) {
938
1106
  return false;
939
1107
  }
940
1108
 
941
1109
  const videoDirection = getVideoDirection(sdp);
942
-
943
1110
  return videoDirection === 'sendonly';
944
1111
  }
945
1112
 
946
- sendDTMF(session: Inviter, tone: string) {
1113
+ sendDTMF(session: Inviter | Invitation, tone: string): boolean {
947
1114
  if (!session.sessionDescriptionHandler) {
948
- return;
1115
+ return false;
949
1116
  }
1117
+
950
1118
  logger.info('Sending DTMF', {
951
1119
  id: this.getSipSessionId(session),
952
1120
  tone,
@@ -954,20 +1122,22 @@ export default class WebRTCClient extends Emitter {
954
1122
  return session.sessionDescriptionHandler.sendDtmf(tone);
955
1123
  }
956
1124
 
957
- message(destination: string, message: string) {
958
- const messager = new Messager(this.userAgent, this._makeURI(destination), message);
959
-
960
- return messager.message();
1125
+ message(destination: string, message: string): void {
1126
+ const uri = this._makeURI(destination);
1127
+ if (!this.userAgent || !uri) {
1128
+ logger.warn('Null value on message', { uri, userAgent: this.userAgent });
1129
+ return;
1130
+ }
1131
+ const messager = new Messager(this.userAgent, uri, message);
1132
+ messager.message();
961
1133
  }
962
1134
 
963
- transfer(session: Inviter, target: string) {
1135
+ transfer(session: Inviter | Invitation, target: string): void {
964
1136
  this.hold(session);
965
-
966
1137
  logger.info('Transfering a session', {
967
1138
  id: this.getSipSessionId(session),
968
1139
  target,
969
1140
  });
970
-
971
1141
  const options = {
972
1142
  requestDelegate: {
973
1143
  onAccept: () => {
@@ -975,23 +1145,29 @@ export default class WebRTCClient extends Emitter {
975
1145
  },
976
1146
  },
977
1147
  };
978
-
979
1148
  setTimeout(() => {
980
- session.refer(this._makeURI(target), options);
1149
+ const uri = this._makeURI(target);
1150
+ if (!uri) {
1151
+ logger.warn('transfer timeout: null URI');
1152
+ return;
1153
+ }
1154
+ session.refer(uri, options);
981
1155
  }, 50);
982
1156
  }
983
1157
 
984
1158
  // check https://sipjs.com/api/0.12.0/refer/referClientContext/
985
- atxfer(session: Inviter) {
1159
+ atxfer(session: Inviter | Invitation): Record<string, any> {
986
1160
  this.hold(session);
987
-
988
- logger.info('webrtc transfer started', { id: this.getSipSessionId(session) });
989
-
990
- const result: Object = {
1161
+ logger.info('webrtc transfer started', {
1162
+ id: this.getSipSessionId(session),
1163
+ });
1164
+ const result: Record<string, any> = {
991
1165
  newSession: null,
992
1166
  init: async (target: string) => {
993
- logger.info('webrtc transfer initialized', { id: this.getSipSessionId(session), target });
994
-
1167
+ logger.info('webrtc transfer initialized', {
1168
+ id: this.getSipSessionId(session),
1169
+ target,
1170
+ });
995
1171
  result.newSession = await this.call(target);
996
1172
  },
997
1173
  complete: () => {
@@ -999,7 +1175,6 @@ export default class WebRTCClient extends Emitter {
999
1175
  id: this.getSipSessionId(session),
1000
1176
  referId: this.getSipSessionId(result.newSession),
1001
1177
  });
1002
-
1003
1178
  session.refer(result.newSession);
1004
1179
  },
1005
1180
  cancel: () => {
@@ -1007,16 +1182,19 @@ export default class WebRTCClient extends Emitter {
1007
1182
  this.unhold(session);
1008
1183
  },
1009
1184
  };
1010
-
1011
1185
  return result;
1012
1186
  }
1013
1187
 
1014
- sendMessage(sipSession: Session = null, body: string, contentType: string = 'text/plain') {
1188
+ // eslint-disable-next-line @typescript-eslint/default-param-last
1189
+ sendMessage(sipSession: Inviter | Invitation | null = null, body: string, contentType = 'text/plain'): void {
1015
1190
  if (!sipSession) {
1016
1191
  return;
1017
1192
  }
1018
1193
 
1019
- logger.info('send WebRTC message', { sipId: sipSession.id, contentType });
1194
+ logger.info('send WebRTC message', {
1195
+ sipId: sipSession.id,
1196
+ contentType,
1197
+ });
1020
1198
 
1021
1199
  try {
1022
1200
  sipSession.message({
@@ -1024,32 +1202,44 @@ export default class WebRTCClient extends Emitter {
1024
1202
  body: {
1025
1203
  content: body,
1026
1204
  contentType,
1205
+ // @HEADSUP: contentDisposition is a required string, setting it to '' arbitrarily
1206
+ contentDisposition: '',
1027
1207
  },
1028
1208
  },
1029
1209
  });
1030
- } catch (e) {
1210
+ } catch (e: any) {
1031
1211
  console.warn(e);
1032
1212
  }
1033
1213
  }
1034
1214
 
1035
- pingServer() {
1215
+ pingServer(): OutgoingRequest | void {
1036
1216
  if (!this.isConnected()) {
1037
1217
  return;
1038
1218
  }
1039
1219
 
1040
- const core = this.userAgent.userAgentCore;
1220
+ const core = this.userAgent?.userAgentCore;
1221
+
1041
1222
  const fromURI = this._makeURI(this.config.authorizationUser || '');
1223
+
1042
1224
  const toURI = new URI('sip', '', this.config.host);
1043
- const message = core.makeOutgoingRequestMessage('OPTIONS', toURI, fromURI, toURI, {});
1225
+ if (fromURI) {
1226
+ const message = core?.makeOutgoingRequestMessage('OPTIONS', toURI, fromURI, toURI, {});
1044
1227
 
1045
- return core.request(message);
1228
+ if (message) {
1229
+ return core?.request(message);
1230
+ }
1231
+
1232
+ logger.warn('pingServer: null message');
1233
+ }
1234
+ logger.warn('pingServer: null fromURI');
1046
1235
  }
1047
1236
 
1048
- getState() {
1237
+ getState(): UserAgentState {
1238
+ // @ts-ignore
1049
1239
  return this.userAgent ? states[this.userAgent.state] : UserAgentState.Stopped;
1050
1240
  }
1051
1241
 
1052
- getContactIdentifier() {
1242
+ getContactIdentifier(): string | null {
1053
1243
  return this.userAgent ? `${this.userAgent.configuration.contactName}/${this.userAgent.contact.uri}` : null;
1054
1244
  }
1055
1245
 
@@ -1057,9 +1247,10 @@ export default class WebRTCClient extends Emitter {
1057
1247
  return this._isWeb() && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
1058
1248
  }
1059
1249
 
1060
- changeAudioOutputVolume(volume: number) {
1061
- logger.info('Changing audio output volume', { volume });
1062
-
1250
+ changeAudioOutputVolume(volume: number): void {
1251
+ logger.info('Changing audio output volume', {
1252
+ volume,
1253
+ });
1063
1254
  Object.values(this.audioElements).forEach(audioElement => {
1064
1255
  if (audioElement instanceof HTMLAudioElement) {
1065
1256
  // eslint-disable-next-line no-param-reassign
@@ -1070,25 +1261,30 @@ export default class WebRTCClient extends Emitter {
1070
1261
  }
1071
1262
 
1072
1263
  changeAudioOutputDevice(id: string) {
1073
- logger.info('Changing audio output device', { id });
1264
+ logger.info('Changing audio output device', {
1265
+ id,
1266
+ });
1074
1267
  this.audioOutputDeviceId = id;
1075
-
1076
1268
  Object.values(this.audioElements).forEach(audioElement => {
1077
1269
  // `setSinkId` method is not included in any flow type definitions for HTMLAudioElements but is a valid method
1078
1270
  // audioElement is an array of HTMLAudioElements, and HTMLAudioElement inherits the method from HTMLMediaElement
1079
1271
  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement
1080
1272
  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/setSinkId
1081
-
1082
- // $FlowFixMe
1273
+ // @ts-ignore
1083
1274
  if (audioElement.setSinkId) {
1275
+ // @ts-ignore
1084
1276
  audioElement.setSinkId(id);
1085
1277
  }
1086
1278
  });
1087
1279
  }
1088
1280
 
1089
- async changeAudioInputDevice(id: string, session: ?Inviter, force: ?boolean) {
1281
+ async changeAudioInputDevice(id: string, session: Inviter | Invitation | null | undefined, force: boolean | null | undefined): Promise<MediaStream | null> {
1090
1282
  const currentId = this.getAudioDeviceId();
1091
- logger.info('setting audio input device', { id, currentId, session: !!session });
1283
+ logger.info('setting audio input device', {
1284
+ id,
1285
+ currentId,
1286
+ session: !!session,
1287
+ });
1092
1288
 
1093
1289
  if (!force && id === currentId) {
1094
1290
  return null;
@@ -1097,14 +1293,18 @@ export default class WebRTCClient extends Emitter {
1097
1293
  // in order to handle an audio track change for default devices
1098
1294
  // we need the actual id of the device (not 'default')
1099
1295
  let deviceId = id;
1296
+
1100
1297
  if (id === 'default' && navigator.mediaDevices) {
1101
1298
  const devices = await navigator.mediaDevices.enumerateDevices();
1102
1299
  const defaultDevice = devices.find(device => device.deviceId === 'default');
1300
+
1103
1301
  if (defaultDevice) {
1104
1302
  const deviceLabel = defaultDevice.label.replace('Default - ', '');
1105
1303
  const targetDevice = devices.find(device => device.label === deviceLabel);
1304
+
1106
1305
  if (targetDevice) {
1107
1306
  deviceId = targetDevice.deviceId;
1307
+
1108
1308
  if (!force && deviceId === currentId) {
1109
1309
  return null;
1110
1310
  }
@@ -1123,26 +1323,34 @@ export default class WebRTCClient extends Emitter {
1123
1323
 
1124
1324
  if (session && navigator.mediaDevices) {
1125
1325
  const sdh = session.sessionDescriptionHandler;
1326
+ // @ts-ignore
1126
1327
  const pc = sdh.peerConnection;
1127
-
1128
- const constraints = { audio: { deviceId: { exact: deviceId } } };
1328
+ const constraints = {
1329
+ audio: {
1330
+ deviceId: {
1331
+ exact: deviceId,
1332
+ },
1333
+ },
1334
+ };
1129
1335
  const stream = await navigator.mediaDevices.getUserMedia(constraints);
1130
1336
  const audioTrack = stream.getAudioTracks()[0];
1131
- const sender = pc && pc.getSenders
1132
- && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
1337
+ const sender = pc && pc.getSenders && pc.getSenders().find((s: any) => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
1133
1338
 
1134
1339
  if (sender) {
1135
1340
  if (sender.track) {
1136
1341
  audioTrack.enabled = sender.track.enabled;
1137
1342
  }
1343
+
1138
1344
  sender.replaceTrack(audioTrack);
1139
1345
  }
1140
1346
 
1141
1347
  return stream;
1142
1348
  }
1349
+
1350
+ return null;
1143
1351
  }
1144
1352
 
1145
- changeVideoInputDevice(id: ?string, session: ?Inviter) {
1353
+ async changeVideoInputDevice(id: string, session?: Inviter | Invitation): Promise<MediaStream | void> {
1146
1354
  this.setVideoInputDevice(id);
1147
1355
 
1148
1356
  if (session) {
@@ -1150,9 +1358,12 @@ export default class WebRTCClient extends Emitter {
1150
1358
  }
1151
1359
  }
1152
1360
 
1153
- setVideoInputDevice(id: ?string) {
1361
+ setVideoInputDevice(id: string) {
1154
1362
  const currentId = this.getVideoDeviceId();
1155
- logger.info('setting video input device', { id, currentId });
1363
+ logger.info('setting video input device', {
1364
+ id,
1365
+ currentId,
1366
+ });
1156
1367
 
1157
1368
  if (id === currentId) {
1158
1369
  return null;
@@ -1160,24 +1371,27 @@ export default class WebRTCClient extends Emitter {
1160
1371
 
1161
1372
  // let's make sure we don't lose other video constraints settings -- width, height, frameRate...
1162
1373
  const videoObject = typeof this.video === 'object' ? this.video : {};
1163
- this.video = {
1164
- ...videoObject,
1374
+ this.video = { ...videoObject,
1165
1375
  deviceId: {
1166
1376
  exact: id,
1167
1377
  },
1168
1378
  };
1169
1379
  }
1170
1380
 
1171
- changeSessionVideoInputDevice(id: ?string, session: Inviter) {
1381
+ changeSessionVideoInputDevice(id: string | null | undefined, session: Inviter | Invitation): Promise<MediaStream | void> {
1172
1382
  if (!this.sessionWantsToDoVideo(session)) {
1173
- return;
1383
+ return Promise.resolve();
1174
1384
  }
1385
+
1175
1386
  const sdh = session.sessionDescriptionHandler;
1387
+ // @ts-ignore
1176
1388
  const pc = sdh.peerConnection;
1177
1389
  const sessionId = this.getSipSessionId(session);
1178
1390
  const localStream = this.getLocalStream(sessionId);
1179
-
1180
- logger.info('changing video input device', { id, sessionId });
1391
+ logger.info('changing video input device', {
1392
+ id,
1393
+ sessionId,
1394
+ });
1181
1395
 
1182
1396
  // Release old video stream
1183
1397
  if (localStream) {
@@ -1187,16 +1401,19 @@ export default class WebRTCClient extends Emitter {
1187
1401
  }
1188
1402
 
1189
1403
  const constraints = {
1190
- video: id ? { deviceId: { exact: id } } : true,
1404
+ video: id ? {
1405
+ deviceId: {
1406
+ exact: id,
1407
+ },
1408
+ } : true,
1191
1409
  };
1192
- // $FlowFixMe
1193
1410
  return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
1194
1411
  const videoTrack = stream.getVideoTracks()[0];
1195
- let sender = pc && pc.getSenders
1196
- && pc.getSenders().find(s => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
1412
+ let sender = pc && pc.getSenders && pc.getSenders().find((s: any) => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
1197
1413
  let wasTrackEnabled = false;
1414
+
1198
1415
  if (!sender) {
1199
- sender = pc && pc.getSenders && pc.getSenders().find(s => !s.track);
1416
+ sender = pc && pc.getSenders && pc.getSenders().find((s: any) => !s.track);
1200
1417
  }
1201
1418
 
1202
1419
  if (sender) {
@@ -1214,39 +1431,36 @@ export default class WebRTCClient extends Emitter {
1214
1431
  // let's update the local stream
1215
1432
  this.eventEmitter.emit('onVideoInputChange', stream);
1216
1433
  this.setLocalMediaStream(sessionId, stream);
1217
-
1218
1434
  return stream;
1219
1435
  });
1220
1436
  }
1221
1437
 
1222
- getAudioDeviceId(): ?string {
1223
- // $FlowFixMe
1224
- return this.audio && typeof this.audio === 'object' && 'deviceId' in this.audio
1225
- ? this.audio.deviceId.exact : undefined;
1438
+ getAudioDeviceId(): string | null | undefined {
1439
+ // @ts-ignore
1440
+ return this.audio && typeof this.audio === 'object' && 'deviceId' in this.audio ? this.audio.deviceId.exact : undefined;
1226
1441
  }
1227
1442
 
1228
- getVideoDeviceId(): ?string {
1229
- // $FlowFixMe
1230
- return this.video && typeof this.video === 'object' && 'deviceId' in this.video
1231
- ? this.video.deviceId.exact : undefined;
1443
+ getVideoDeviceId(): string | null {
1444
+ // @ts-ignore
1445
+ return this.video && typeof this.video === 'object' && 'deviceId' in this.video ? this.video.deviceId.exact : undefined;
1232
1446
  }
1233
1447
 
1234
- reinvite(sipSession: Session, newConstraints: ?Object = null, conference: boolean = false,
1235
- audioOnly: boolean = false, iceRestart: boolean = false) {
1448
+ reinvite(sipSession: Inviter | Invitation, newConstraints: Record<string, any> | null | undefined = null, conference = false, audioOnly = false, iceRestart = false): Promise<OutgoingInviteRequest | void> {
1236
1449
  if (!sipSession) {
1237
- return false;
1450
+ return Promise.resolve();
1238
1451
  }
1239
1452
 
1453
+ // @ts-ignore
1240
1454
  if (sipSession.pendingReinvite) {
1241
- return false;
1455
+ return Promise.resolve();
1242
1456
  }
1243
1457
 
1244
1458
  const wasMuted = this.isAudioMuted(sipSession);
1245
1459
  const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
1246
1460
  const shouldDoScreenSharing = newConstraints && newConstraints.screen;
1247
1461
  const desktop = newConstraints && newConstraints.desktop;
1248
-
1249
1462
  logger.info('Sending reinvite', {
1463
+ clientId: this.clientId,
1250
1464
  id: this.getSipSessionId(sipSession),
1251
1465
  newConstraints,
1252
1466
  conference,
@@ -1260,27 +1474,28 @@ export default class WebRTCClient extends Emitter {
1260
1474
  // When upgrading to video, remove the `stripVideo` modifiers
1261
1475
  if (newConstraints && newConstraints.video) {
1262
1476
  const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
1263
- sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier =>
1264
- modifier !== stripVideo);
1477
+ sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier => modifier !== stripVideo);
1265
1478
  }
1266
1479
 
1267
- sipSession.sessionDescriptionHandlerOptionsReInvite = {
1268
- ...sipSession.sessionDescriptionHandlerOptionsReInvite,
1480
+ sipSession.sessionDescriptionHandlerOptionsReInvite = { ...sipSession.sessionDescriptionHandlerOptionsReInvite,
1481
+ // @ts-ignore
1269
1482
  conference,
1270
1483
  audioOnly,
1271
1484
  };
1272
-
1273
- // $FlowFixMe
1274
- const { constraints } = this.getMediaConfiguration(shouldDoVideo, conference, newConstraints);
1275
-
1485
+ const {
1486
+ constraints,
1487
+ } = this.getMediaConfiguration(shouldDoVideo, conference, newConstraints);
1276
1488
  return sipSession.invite({
1277
1489
  requestDelegate: {
1278
1490
  onAccept: (response: IncomingResponse) => {
1279
1491
  // Update the SDP body to be able to call sessionWantsToDoVideo correctly in `_setup[Local|Remote]Media`.
1280
1492
  // Can't set directly sipSession.body because it's a getter.
1281
- if (sipSession instanceof Inviter) {
1493
+ // @ts-ignore
1494
+ if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage.body) {
1495
+ // @ts-ignore
1282
1496
  sipSession.outgoingRequestMessage.body.body = response.message.body;
1283
- } else {
1497
+ } else if (sipSession instanceof Invitation) {
1498
+ // @ts-ignore
1284
1499
  sipSession.incomingInviteRequest.message.body = response.message.body;
1285
1500
  }
1286
1501
 
@@ -1289,13 +1504,13 @@ export default class WebRTCClient extends Emitter {
1289
1504
  wasMuted,
1290
1505
  shouldDoScreenSharing,
1291
1506
  });
1292
-
1293
1507
  this.updateRemoteStream(this.getSipSessionId(sipSession));
1294
1508
 
1295
1509
  if (wasMuted) {
1296
1510
  this.mute(sipSession);
1297
1511
  }
1298
1512
 
1513
+ // @ts-ignore
1299
1514
  this._onAccepted(sipSession, response.session, false);
1300
1515
 
1301
1516
  if (shouldDoScreenSharing) {
@@ -1311,6 +1526,7 @@ export default class WebRTCClient extends Emitter {
1311
1526
  },
1312
1527
  sessionDescriptionHandlerOptions: {
1313
1528
  constraints,
1529
+ // @ts-ignore
1314
1530
  conference,
1315
1531
  audioOnly,
1316
1532
  offerOptions: {
@@ -1320,35 +1536,35 @@ export default class WebRTCClient extends Emitter {
1320
1536
  });
1321
1537
  }
1322
1538
 
1323
- async getUserMedia(constraints: Object) {
1539
+ async getUserMedia(constraints: Record<string, any>): Promise<MediaStream> {
1324
1540
  const newConstraints = {
1325
1541
  audio: this._getAudioConstraints(),
1326
1542
  video: this._getVideoConstraints(constraints.video),
1327
1543
  };
1328
-
1329
- // $FlowFixMe
1330
1544
  return navigator.mediaDevices.getUserMedia(newConstraints);
1331
1545
  }
1332
1546
 
1333
1547
  getPeerConnection(sessionId: string) {
1334
1548
  const sipSession = this.sipSessions[sessionId];
1549
+
1335
1550
  if (!sipSession) {
1336
1551
  return null;
1337
1552
  }
1338
1553
 
1554
+ // @ts-ignore
1339
1555
  return sipSession.sessionDescriptionHandler ? sipSession.sessionDescriptionHandler.peerConnection : null;
1340
1556
  }
1341
1557
 
1342
1558
  // Local streams
1343
- getLocalStream(sessionId: string): ?MediaStream {
1559
+ getLocalStream(sessionId: string): MediaStream | null {
1344
1560
  const sipSession = this.sipSessions[sessionId];
1345
-
1346
- return sipSession && sipSession.sessionDescriptionHandler
1347
- ? sipSession.sessionDescriptionHandler.localMediaStream : null;
1561
+ // @ts-ignore
1562
+ return sipSession?.sessionDescriptionHandler?.localMediaStream || null;
1348
1563
  }
1349
1564
 
1350
1565
  getLocalTracks(sessionId: string): MediaStreamTrack[] {
1351
1566
  const localStream = this.getLocalStream(sessionId);
1567
+
1352
1568
  if (!localStream) {
1353
1569
  return [];
1354
1570
  }
@@ -1365,20 +1581,20 @@ export default class WebRTCClient extends Emitter {
1365
1581
  return this.getLocalTracks(sessionId).some(track => track.kind === 'video');
1366
1582
  }
1367
1583
 
1368
- getLocalVideoStream(sessionId: string): ?MediaStream {
1584
+ getLocalVideoStream(sessionId: string): MediaStream | null | undefined {
1369
1585
  return this.hasLocalVideo(sessionId) ? this.getLocalStream(sessionId) : null;
1370
1586
  }
1371
1587
 
1372
1588
  // Remote streams
1373
- getRemoteStream(sessionId: string): ?MediaStream {
1589
+ getRemoteStream(sessionId: string): MediaStream | null {
1374
1590
  const sipSession = this.sipSessions[sessionId];
1375
-
1376
- return sipSession && sipSession.sessionDescriptionHandler
1377
- ? sipSession.sessionDescriptionHandler.remoteMediaStream : null;
1591
+ // @ts-ignore
1592
+ return sipSession?.sessionDescriptionHandler?.remoteMediaStream || null;
1378
1593
  }
1379
1594
 
1380
1595
  getRemoteTracks(sessionId: string): MediaStreamTrack[] {
1381
1596
  const remoteStream = this.getRemoteStream(sessionId);
1597
+
1382
1598
  if (!remoteStream) {
1383
1599
  return [];
1384
1600
  }
@@ -1395,7 +1611,7 @@ export default class WebRTCClient extends Emitter {
1395
1611
  return this.getRemoteTracks(sessionId).some(track => track.kind === 'video');
1396
1612
  }
1397
1613
 
1398
- getRemoteVideoStream(sessionId: string): ?MediaStream {
1614
+ getRemoteVideoStream(sessionId: string): MediaStream | null | undefined {
1399
1615
  if (this.isVideoRemotelyHeld(sessionId)) {
1400
1616
  return null;
1401
1617
  }
@@ -1404,13 +1620,14 @@ export default class WebRTCClient extends Emitter {
1404
1620
  }
1405
1621
 
1406
1622
  // Useful in a react-native environment when remoteMediaStream is not updated
1407
- getRemoteVideoStreamFromPc(sessionId: string): ?MediaStream {
1623
+ getRemoteVideoStreamFromPc(sessionId: string): MediaStream | null | undefined {
1408
1624
  const pc = this.getPeerConnection(sessionId);
1625
+
1409
1626
  if (!pc) {
1410
1627
  return null;
1411
1628
  }
1412
1629
 
1413
- return pc.getRemoteStreams().find(stream => !!stream.getVideoTracks().length);
1630
+ return pc.getRemoteStreams().find((stream: MediaStream) => !!stream.getVideoTracks().length);
1414
1631
  }
1415
1632
 
1416
1633
  hasVideo(sessionId: string): boolean {
@@ -1421,45 +1638,53 @@ export default class WebRTCClient extends Emitter {
1421
1638
  return this.hasALocalVideoTrack(sessionId) || this.hasARemoteVideoTrack(sessionId);
1422
1639
  }
1423
1640
 
1424
- getSipSessionId(sipSession: ?Inviter): string {
1641
+ getSipSessionId(sipSession: Inviter | Invitation | null | undefined): string {
1425
1642
  if (!sipSession) {
1426
1643
  return '';
1427
1644
  }
1428
- if (sipSession.message && sipSession.message.callId) {
1429
- return sipSession.message.callId;
1645
+
1646
+ // @ts-ignore
1647
+ if (sipSession.message?.callId) {
1648
+ // @ts-ignore
1649
+ return sipSession.message.callId.substring(0, SIP_ID_LENGTH);
1430
1650
  }
1431
1651
 
1432
1652
  // For Inviter
1433
- if (sipSession.outgoingRequestMessage) {
1434
- return sipSession.outgoingRequestMessage.callId;
1653
+ // @ts-ignore
1654
+ if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
1655
+ // @ts-ignore
1656
+ return sipSession.outgoingRequestMessage.callId.substring(0, SIP_ID_LENGTH);
1435
1657
  }
1436
1658
 
1437
1659
  // For Invitation
1438
- return (sipSession.id || '').substr(0, 36);
1660
+ return (sipSession.id || '').substring(0, SIP_ID_LENGTH);
1439
1661
  }
1440
1662
 
1441
- async waitForRegister() {
1663
+ async waitForRegister(): Promise<void> {
1442
1664
  return new Promise(resolve => this.on(REGISTERED, resolve));
1443
1665
  }
1444
1666
 
1445
1667
  // eslint-disable-next-line no-unused-vars
1446
- sessionWantsToDoVideo(session: Inviter) {
1668
+ sessionWantsToDoVideo(session: Inviter | Invitation): boolean {
1447
1669
  if (!session) {
1448
1670
  return false;
1449
1671
  }
1450
- const { body } = session.request || session;
1672
+
1673
+ const {
1674
+ body,
1675
+ } = session.request || session;
1451
1676
  // Sometimes with InviteClientContext the body is in the body attribute ...
1452
1677
  const sdp = typeof body === 'object' && body ? body.body : body;
1453
-
1454
1678
  return hasAnActiveVideo(sdp);
1455
1679
  }
1456
1680
 
1457
- hasHeartbeat() {
1681
+ hasHeartbeat(): boolean {
1458
1682
  return this.heartbeat.hasHeartbeat;
1459
1683
  }
1460
1684
 
1461
- startHeartbeat() {
1462
- logger.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent });
1685
+ startHeartbeat(): void {
1686
+ logger.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent, clientId: this.clientId });
1687
+
1463
1688
  if (!this.userAgent) {
1464
1689
  this.heartbeat.stop();
1465
1690
  return;
@@ -1467,53 +1692,61 @@ export default class WebRTCClient extends Emitter {
1467
1692
 
1468
1693
  this.eventEmitter.off(MESSAGE, this._boundOnHeartbeat);
1469
1694
  this.eventEmitter.on(MESSAGE, this._boundOnHeartbeat);
1470
-
1471
1695
  this.heartbeat.start();
1472
1696
  }
1473
1697
 
1474
- stopHeartbeat() {
1475
- logger.info('sdk webrtc stop heartbeat');
1698
+ stopHeartbeat(): void {
1699
+ logger.info('sdk webrtc stop heartbeat', { clientId: this.clientId });
1476
1700
  this.heartbeat.stop();
1477
1701
  }
1478
1702
 
1479
- setOnHeartbeatTimeout(cb: Function) {
1703
+ setOnHeartbeatTimeout(cb: (...args: Array<any>) => any): void {
1480
1704
  this.heartbeatTimeoutCb = cb;
1481
1705
  }
1482
1706
 
1483
- setOnHeartbeatCallback(cb: Function) {
1707
+ setOnHeartbeatCallback(cb: (...args: Array<any>) => any): void {
1484
1708
  this.heartbeatCb = cb;
1485
1709
  }
1486
1710
 
1487
- onCallEnded(session: Session) {
1711
+ onCallEnded(session: Inviter | Invitation): void {
1488
1712
  this._cleanupMedia(session);
1713
+
1489
1714
  delete this.sipSessions[this.getSipSessionId(session)];
1490
1715
 
1491
1716
  this._stopSendingStats(session);
1717
+
1492
1718
  this.stopNetworkMonitoring(session);
1493
1719
  }
1494
1720
 
1495
1721
  attemptReconnection(): void {
1496
- logger.info('attempt reconnection', { userAgent: !!this.userAgent });
1722
+ logger.info('attempt reconnection', { clientId: this.clientId, userAgent: !!this.userAgent });
1723
+
1497
1724
  if (!this.userAgent) {
1498
1725
  return;
1499
1726
  }
1727
+
1728
+ // @ts-ignore
1500
1729
  this.userAgent.attemptReconnection();
1501
1730
  }
1502
1731
 
1503
- storeSipSession(session: Session) {
1504
- this.sipSessions[this.getSipSessionId(session)] = session;
1732
+ storeSipSession(session: Invitation | Inviter): void {
1733
+ const id = this.getSipSessionId(session);
1734
+ logger.info('storing sip session', { id, clientId: this.clientId });
1735
+
1736
+ this.sipSessions[id] = session;
1505
1737
  }
1506
1738
 
1507
- getSipSession(id: string): ?Session {
1508
- return id in this.sipSessions ? this.sipSessions[id] : null;
1739
+ getSipSession(id: string): Invitation | Inviter | null | undefined {
1740
+ return id in this.sipSessions ? this.sipSessions[id.substring(0, SIP_ID_LENGTH)] : null;
1509
1741
  }
1510
1742
 
1511
1743
  getSipSessionIds(): string[] {
1512
1744
  return Object.keys(this.sipSessions);
1513
1745
  }
1514
1746
 
1515
- setLocalMediaStream(sipSessionId: string, newStream: MediaStream) {
1747
+ setLocalMediaStream(sipSessionId: string, newStream: MediaStream): void {
1516
1748
  const sipSession = this.sipSessions[sipSessionId];
1749
+
1517
1750
  if (!sipSession) {
1518
1751
  return;
1519
1752
  }
@@ -1522,19 +1755,21 @@ export default class WebRTCClient extends Emitter {
1522
1755
  sipSessionId,
1523
1756
  tracks: newStream ? newStream.getTracks() : null,
1524
1757
  });
1525
-
1526
- // eslint-disable-next-line no-underscore-dangle
1527
- sipSession.sessionDescriptionHandler._localMediaStream = newStream;
1758
+ if (sipSession.sessionDescriptionHandler) {
1759
+ // eslint-disable-next-line no-underscore-dangle
1760
+ // @ts-ignore
1761
+ sipSession.sessionDescriptionHandler._localMediaStream = newStream;
1762
+ }
1528
1763
  }
1529
1764
 
1530
- updateLocalStream(sipSessionId: string, newStream: MediaStream) {
1765
+ updateLocalStream(sipSessionId: string, newStream: MediaStream): void {
1531
1766
  const sipSession = this.sipSessions[sipSessionId];
1767
+
1532
1768
  if (!sipSession) {
1533
1769
  return;
1534
1770
  }
1535
1771
 
1536
1772
  const oldStream = this.getLocalStream(sipSessionId);
1537
-
1538
1773
  logger.info('updating local stream', {
1539
1774
  sipSessionId,
1540
1775
  oldStream: !!oldStream,
@@ -1551,14 +1786,13 @@ export default class WebRTCClient extends Emitter {
1551
1786
  this._setupMedias(sipSession, newStream);
1552
1787
  }
1553
1788
 
1554
- updateRemoteStream(sessionId: string) {
1789
+ updateRemoteStream(sessionId: string): void {
1555
1790
  const remoteStream = this.getRemoteStream(sessionId);
1556
1791
  const pc = this.getPeerConnection(sessionId);
1557
-
1558
1792
  logger.info('Updating remote stream', {
1559
1793
  sessionId,
1560
1794
  tracks: remoteStream ? remoteStream.getTracks() : null,
1561
- receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map(receiver => receiver.track) : null,
1795
+ receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map((receiver: any) => receiver.track) : null,
1562
1796
  });
1563
1797
 
1564
1798
  if (!pc || !remoteStream) {
@@ -1570,27 +1804,36 @@ export default class WebRTCClient extends Emitter {
1570
1804
  });
1571
1805
 
1572
1806
  if (pc.getReceivers) {
1573
- pc.getReceivers().forEach(receiver => {
1807
+ pc.getReceivers().forEach((receiver: any) => {
1574
1808
  remoteStream.addTrack(receiver.track);
1575
1809
  });
1576
1810
  }
1577
1811
  }
1578
1812
 
1579
- getMediaConfiguration(enableVideo: boolean, conference: boolean = false, constraints: ?Object = null): Object {
1813
+ getMediaConfiguration(enableVideo: boolean, conference = false, constraints: Record<string, any> | null | undefined = null): Record<string, any> {
1580
1814
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
1581
1815
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
1582
1816
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
1583
1817
  const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
1584
-
1585
- logger.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
1586
-
1818
+ logger.info('Retrieving media a configuration', {
1819
+ enableVideo,
1820
+ screenSharing,
1821
+ isDesktop,
1822
+ withAudio,
1823
+ constraints,
1824
+ });
1587
1825
  return {
1588
1826
  constraints: {
1589
1827
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
1590
- audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
1591
- video: screenSharing ? (isDesktop
1592
- ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
1593
- : this._getVideoConstraints(enableVideo),
1828
+ audio: screenSharing ? !isDesktop : withAudio ? this._getAudioConstraints() : false,
1829
+ video: screenSharing ? isDesktop ? {
1830
+ mandatory: {
1831
+ chromeMediaSource: 'desktop',
1832
+ ...(mandatoryVideo || {}),
1833
+ },
1834
+ } : {
1835
+ cursor: 'always',
1836
+ } : this._getVideoConstraints(enableVideo),
1594
1837
  screen: screenSharing,
1595
1838
  desktop: isDesktop,
1596
1839
  conference,
@@ -1608,42 +1851,44 @@ export default class WebRTCClient extends Emitter {
1608
1851
  };
1609
1852
  }
1610
1853
 
1611
- isConference(sessionId: string) {
1854
+ isConference(sessionId: string): boolean {
1612
1855
  return sessionId in this.conferences;
1613
1856
  }
1614
1857
 
1615
- createAudioElementFor(sessionId: string) {
1616
- const audio: any = document.createElement('audio');
1858
+ createAudioElementFor(sessionId: string): HTMLAudioElement {
1859
+ const audio: HTMLAudioElement = document.createElement('audio');
1617
1860
  audio.setAttribute('id', `audio-${sessionId}`);
1618
1861
 
1619
- if (audio.setSinkId && this.audioOutputDeviceId) {
1620
- audio.setSinkId(this.audioOutputDeviceId);
1862
+ if ((audio as any).setSinkId && this.audioOutputDeviceId) {
1863
+ (audio as any).setSinkId(this.audioOutputDeviceId);
1621
1864
  }
1622
1865
 
1623
1866
  if (document.body) {
1624
1867
  document.body.appendChild(audio);
1625
1868
  }
1626
- this.audioElements[sessionId] = audio;
1627
1869
 
1870
+ this.audioElements[sessionId] = audio;
1628
1871
  audio.volume = this.audioOutputVolume;
1629
1872
  audio.autoplay = true;
1630
-
1631
1873
  return audio;
1632
1874
  }
1633
1875
 
1634
- _onTransportError() {
1876
+ _onTransportError(): void {
1635
1877
  logger.error('on transport error');
1636
1878
  this.eventEmitter.emit(TRANSPORT_ERROR);
1637
1879
  this.attemptReconnection();
1638
1880
  }
1639
1881
 
1640
- _onHeartbeat(message: string | Object) {
1882
+ _onHeartbeat(message: string | Record<string, any>): void {
1641
1883
  const body = message && typeof message === 'object' ? message.data : message;
1884
+
1642
1885
  if (body && body.indexOf('200 OK') !== -1) {
1643
1886
  if (this.hasHeartbeat()) {
1644
- logger.info('on heartbeat received from Asterisk', { hasHeartbeat: this.hasHeartbeat() });
1645
-
1887
+ logger.info('on heartbeat received from Asterisk', {
1888
+ hasHeartbeat: this.hasHeartbeat(),
1889
+ });
1646
1890
  this.heartbeat.onHeartbeat();
1891
+
1647
1892
  if (this.heartbeatCb) {
1648
1893
  this.heartbeatCb();
1649
1894
  }
@@ -1651,8 +1896,11 @@ export default class WebRTCClient extends Emitter {
1651
1896
  }
1652
1897
  }
1653
1898
 
1654
- async _onHeartbeatTimeout() {
1655
- logger.warn('sdk webrtc heartbeat timed out', { userAgent: !!this.userAgent, cb: !!this.heartbeatTimeoutCb });
1899
+ async _onHeartbeatTimeout(): Promise<void> {
1900
+ logger.warn('sdk webrtc heartbeat timed out', {
1901
+ userAgent: !!this.userAgent,
1902
+ cb: !!this.heartbeatTimeoutCb,
1903
+ });
1656
1904
 
1657
1905
  if (this.heartbeatTimeoutCb) {
1658
1906
  this.heartbeatTimeoutCb();
@@ -1660,10 +1908,11 @@ export default class WebRTCClient extends Emitter {
1660
1908
 
1661
1909
  if (this.userAgent && this.userAgent.transport) {
1662
1910
  // Disconnect from WS and triggers events, but do not trigger disconnect if already disconnecting...
1911
+ // @ts-ignore
1663
1912
  if (!this.userAgent.transport.transitioningState && !this.userAgent.transport.disconnectPromise) {
1664
1913
  try {
1665
1914
  await this.userAgent.transport.disconnect();
1666
- } catch (e) {
1915
+ } catch (e: any) {
1667
1916
  logger.error('Transport disconnection after heartbeat timeout, error', e);
1668
1917
  }
1669
1918
  }
@@ -1673,31 +1922,35 @@ export default class WebRTCClient extends Emitter {
1673
1922
  }
1674
1923
  }
1675
1924
 
1676
- _isWeb() {
1925
+ _isWeb(): boolean {
1677
1926
  return typeof window === 'object' && typeof document === 'object';
1678
1927
  }
1679
1928
 
1680
- _isVideoTrack(track: MediaStreamTrack) {
1929
+ _isVideoTrack(track: MediaStreamTrack): boolean {
1681
1930
  return track.kind === 'video' && track.readyState === 'live';
1682
1931
  }
1683
1932
 
1684
- _hasAudio() {
1933
+ _hasAudio(): boolean {
1685
1934
  return this.hasAudio;
1686
1935
  }
1687
1936
 
1688
- _getAudioConstraints() {
1689
- return this.audio && this.audio.deviceId && this.audio.deviceId.exact ? this.audio : true;
1937
+ _getAudioConstraints(): MediaTrackConstraints | boolean {
1938
+ // @ts-ignore
1939
+ return this.audio?.deviceId?.exact ? this.audio : true;
1690
1940
  }
1691
1941
 
1692
- _getVideoConstraints(video: boolean = false) {
1942
+ _getVideoConstraints(video = false): MediaTrackConstraints | boolean {
1693
1943
  if (!video) {
1694
1944
  return false;
1695
1945
  }
1696
- return this.video && this.video.deviceId && this.video.deviceId.exact ? this.video : true;
1946
+
1947
+ // @ts-ignore
1948
+ return this.video?.deviceId?.exact ? this.video : true;
1697
1949
  }
1698
1950
 
1699
- _connectIfNeeded(): Promise<void> {
1700
- logger.info('connect if needed, checking', { connected: this.isConnected() });
1951
+ _connectIfNeeded(): Promise<any> {
1952
+ logger.info('connect if needed, checking', { connected: this.isConnected(), clientId: this.clientId });
1953
+
1701
1954
  if (!this.userAgent) {
1702
1955
  logger.info('need to recreate User Agent');
1703
1956
  this.userAgent = this.createUserAgent(this.uaConfigOverrides);
@@ -1710,14 +1963,13 @@ export default class WebRTCClient extends Emitter {
1710
1963
 
1711
1964
  if (this.isConnecting()) {
1712
1965
  logger.info('webrtc sdk, already connecting...');
1713
-
1966
+ // @ts-ignore
1714
1967
  this.connectionPromise = this.userAgent.transport.connectPromise;
1715
- return this.connectionPromise;
1968
+ return Promise.resolve(this.connectionPromise);
1716
1969
  }
1717
1970
 
1718
1971
  if (this.connectionPromise) {
1719
1972
  logger.info('webrtc sdk, connection promise connecting...');
1720
- // $FlowFixMe
1721
1973
  return this.connectionPromise;
1722
1974
  }
1723
1975
 
@@ -1725,26 +1977,34 @@ export default class WebRTCClient extends Emitter {
1725
1977
 
1726
1978
  // Force UA to reconnect
1727
1979
  if (this.userAgent && this.userAgent.state !== UserAgentState.Stopped) {
1980
+ // @ts-ignore
1728
1981
  this.userAgent.transitionState(UserAgentState.Stopped);
1729
1982
  }
1983
+
1730
1984
  if (this.userAgent.transport && this.userAgent.transport.state !== TransportState.Disconnected) {
1985
+ // @ts-ignore
1731
1986
  this.userAgent.transport.transitionState(TransportState.Disconnected);
1732
1987
  }
1733
- this.connectionPromise = this.userAgent.start().catch(console.error);
1734
1988
 
1989
+ this.connectionPromise = this.userAgent.start().catch(console.error);
1735
1990
  return this.connectionPromise;
1736
1991
  }
1737
1992
 
1738
- _buildConfig(config: WebRtcConfig, session: ?Session): Promise<WebRtcConfig> {
1993
+ _buildConfig(config: WebRtcConfig, session: Invitation | Inviter | null | undefined): Promise<WebRtcConfig> {
1739
1994
  // If no session provided, return the configuration directly
1740
1995
  if (!session) {
1741
1996
  return new Promise(resolve => resolve(config));
1742
1997
  }
1743
1998
 
1744
- const client = new ApiClient({ server: config.host });
1999
+ const client = new ApiClient({
2000
+ server: config.host,
2001
+ });
2002
+ // @ts-ignore
1745
2003
  client.setToken(session.token);
2004
+ // @ts-ignore
1746
2005
  client.setRefreshToken(session.refreshToken);
1747
2006
 
2007
+ // @ts-ignore
1748
2008
  return client.confd.getUserLineSipFromToken(session.uuid).then(sipLine => ({
1749
2009
  authorizationUser: sipLine.username,
1750
2010
  password: sipLine.secret,
@@ -1753,15 +2013,19 @@ export default class WebRTCClient extends Emitter {
1753
2013
  }));
1754
2014
  }
1755
2015
 
1756
- _createWebRTCConfiguration(configOverrides: Object = {}) {
1757
- let { host } = this.config;
1758
- let port = this.config.port || 443;
2016
+ _createWebRTCConfiguration(configOverrides: Record<string, any> | null = {}): Record<string, any> {
2017
+ let {
2018
+ host,
2019
+ } = this.config;
2020
+ let port: number = this.config.port || 443;
1759
2021
 
1760
2022
  if (this.config.websocketSip) {
1761
- [host, port = 443] = this.config.websocketSip.split(':');
2023
+ const webSocketSip = this.config.websocketSip.split(':');
2024
+ [host] = webSocketSip;
2025
+ port = Number(webSocketSip[1]);
1762
2026
  }
1763
2027
 
1764
- const config: Object = {
2028
+ const config: Record<string, any> = {
1765
2029
  authorizationUsername: this.config.authorizationUser,
1766
2030
  authorizationPassword: this.config.password,
1767
2031
  displayName: this.config.displayName,
@@ -1777,25 +2041,23 @@ export default class WebRTCClient extends Emitter {
1777
2041
  userAgentString: this.config.userAgentString || 'wazo-sdk',
1778
2042
  reconnectionAttempts: 10000,
1779
2043
  reconnectionDelay: 5,
1780
- sessionDescriptionHandlerFactory: (session: Session, options: SessionDescriptionHandlerFactoryOptions = {}) => {
2044
+ sessionDescriptionHandlerFactory: (session: Inviter | Invitation, options: SessionDescriptionHandlerFactoryOptions = {}) => {
1781
2045
  const uaLogger = session.userAgent.getLogger('sip.WazoSessionDescriptionHandler');
2046
+
1782
2047
  const isWeb = this._isWeb();
1783
- const iceGatheringTimeout = 'peerConnectionOptions' in options
1784
- ? options.peerConnectionOptions.iceGatheringTimeout || DEFAULT_ICE_TIMEOUT : DEFAULT_ICE_TIMEOUT;
1785
2048
 
1786
- const sdhOptions: SessionDescriptionHandlerConfiguration = {
1787
- ...options,
2049
+ // @ts-ignore
2050
+ const iceGatheringTimeout = 'peerConnectionOptions' in options ? options.peerConnectionOptions.iceGatheringTimeout || DEFAULT_ICE_TIMEOUT : DEFAULT_ICE_TIMEOUT;
2051
+ const sdhOptions: SessionDescriptionHandlerConfiguration = { ...options,
1788
2052
  iceGatheringTimeout,
1789
- peerConnectionConfiguration: {
1790
- ...defaultPeerConnectionConfiguration(),
2053
+ peerConnectionConfiguration: { ...defaultPeerConnectionConfiguration(),
1791
2054
  ...(options.peerConnectionConfiguration || {}),
1792
2055
  },
1793
2056
  };
1794
-
1795
2057
  return new WazoSessionDescriptionHandler(uaLogger, wazoMediaStreamFactory, sdhOptions, isWeb, session);
1796
2058
  },
1797
2059
  transportOptions: {
1798
- traceSip: configOverrides.traceSip || false,
2060
+ traceSip: configOverrides?.traceSip || false,
1799
2061
  wsServers: `wss://${host}:${port}/api/asterisk/ws`,
1800
2062
  },
1801
2063
  sessionDescriptionHandlerFactoryOptions: {
@@ -1812,19 +2074,20 @@ export default class WebRTCClient extends Emitter {
1812
2074
  rtcpMuxPolicy: 'require',
1813
2075
  iceServers: WebRTCClient.getIceServers(this.config.host),
1814
2076
  ...this._getRtcOptions(),
1815
- ...configOverrides.peerConnectionOptions || {},
2077
+ ...(configOverrides?.peerConnectionOptions || {}),
1816
2078
  },
1817
2079
  },
1818
2080
  // Configuration used in SDH to create the PeerConnection
1819
2081
  peerConnectionConfiguration: {
1820
2082
  rtcpMuxPolicy: 'require',
1821
2083
  iceServers: WebRTCClient.getIceServers(this.config.host),
1822
- ...configOverrides.peerConnectionOptions || {},
2084
+ ...(configOverrides?.peerConnectionOptions || {}),
1823
2085
  },
1824
2086
  },
1825
2087
  };
1826
-
1827
- return { ...config, ...configOverrides };
2088
+ return { ...config,
2089
+ ...configOverrides,
2090
+ };
1828
2091
  }
1829
2092
 
1830
2093
  // eslint-disable-next-line no-unused-vars
@@ -1838,7 +2101,7 @@ export default class WebRTCClient extends Emitter {
1838
2101
  }
1839
2102
 
1840
2103
  // Invitation and Inviter extends Session
1841
- _setupSession(session: Session) {
2104
+ _setupSession(session: Inviter | Invitation): void {
1842
2105
  const sipSessionId = this.getSipSessionId(session);
1843
2106
 
1844
2107
  // When receiving an Invitation, the delegate is not defined.
@@ -1847,12 +2110,12 @@ export default class WebRTCClient extends Emitter {
1847
2110
  }
1848
2111
 
1849
2112
  session.delegate.onSessionDescriptionHandler = (sdh: SessionDescriptionHandler) => {
2113
+ // @ts-ignore
1850
2114
  sdh.on('error', e => {
1851
2115
  this.eventEmitter.emit(ON_ERROR, e);
1852
2116
  });
1853
-
1854
2117
  sdh.peerConnectionDelegate = {
1855
- onicecandidateerror: (error: Object) => {
2118
+ onicecandidateerror: (error: Record<string, any>) => {
1856
2119
  logger.error('on icecandidate error', {
1857
2120
  address: error.address,
1858
2121
  port: error.port,
@@ -1864,33 +2127,43 @@ export default class WebRTCClient extends Emitter {
1864
2127
  };
1865
2128
  };
1866
2129
 
2130
+ // @ts-ignore
1867
2131
  const oldInviteRequest = session.onInviteRequest.bind(session);
1868
2132
  let hadRemoteVideo = false;
1869
2133
 
1870
2134
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
1871
2135
  // Because when `onInvite` is called we already got the video track
1872
- session.onInviteRequest = (request) => {
2136
+ // @ts-ignore
2137
+ session.onInviteRequest = request => {
1873
2138
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
1874
-
1875
2139
  oldInviteRequest(request);
1876
2140
  };
1877
2141
 
1878
2142
  session.delegate.onInvite = (request: IncomingRequestMessage) => {
1879
- let updatedCalleeName = null;
2143
+ let updatedCalleeName: string | null = null;
1880
2144
  let updatedNumber = null;
2145
+
1881
2146
  if (session.assertedIdentity) {
2147
+ // @ts-ignore
1882
2148
  updatedNumber = session.assertedIdentity.uri.normal.user;
1883
2149
  updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
1884
2150
  }
1885
- logger.info('re-invite received', { updatedCalleeName, updatedNumber, hadRemoteVideo });
1886
2151
 
1887
- // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
2152
+ logger.info('re-invite received', {
2153
+ updatedCalleeName,
2154
+ updatedNumber,
2155
+ hadRemoteVideo,
2156
+ });
1888
2157
 
2158
+ // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
1889
2159
  // Update SDP
1890
2160
  // Remote video is handled by the `track` event. Here we're dealing with video stream removal.
1891
- if (session.incomingInviteRequest) {
2161
+ if (session instanceof Invitation) {
2162
+ // @ts-ignore
1892
2163
  session.incomingInviteRequest.message.body = request.body;
1893
- } else {
2164
+ // @ts-ignore
2165
+ } else if (session instanceof Inviter && session.outgoingInviteRequest.message.body) {
2166
+ // @ts-ignore
1894
2167
  session.outgoingInviteRequest.message.body.body = request.body;
1895
2168
  }
1896
2169
 
@@ -1902,31 +2175,50 @@ export default class WebRTCClient extends Emitter {
1902
2175
  };
1903
2176
  }
1904
2177
 
1905
- _onEarlyProgress(session: SessionDialog) {
2178
+ _onEarlyProgress(session: any): void {
1906
2179
  this._setupMedias(session);
1907
2180
 
1908
2181
  const sessionId = this.getSipSessionId(session).substr(0, 20);
1909
2182
  this.updateRemoteStream(sessionId);
1910
-
1911
- logger.info('Early media progress progress received', { sessionId });
1912
-
2183
+ logger.info('Early media progress progress received', {
2184
+ sessionId,
2185
+ });
1913
2186
  this.eventEmitter.emit(ON_EARLY_MEDIA, session);
1914
2187
  }
1915
2188
 
1916
- _onAccepted(session: Session, sessionDialog?: SessionDialog, withEvent: boolean = true) {
1917
- logger.info('on call accepted', { id: session.id, remoteTag: session.remoteTag });
1918
-
2189
+ _onAccepted(session: Inviter | Invitation, sessionDialog?: SessionDialog, withEvent = true): void {
2190
+ logger.info('on call accepted', {
2191
+ id: session.id,
2192
+ clientId: this.clientId,
2193
+ // @ts-ignore
2194
+ remoteTag: session.remoteTag,
2195
+ });
1919
2196
  this.storeSipSession(session);
1920
2197
 
1921
2198
  this._setupMedias(session);
1922
2199
 
1923
2200
  this.updateRemoteStream(this.getSipSessionId(session));
2201
+ // @ts-ignore
2202
+ const pc = session.sessionDescriptionHandler?.peerConnection;
1924
2203
 
1925
- const pc = session.sessionDescriptionHandler.peerConnection;
1926
2204
  const onTrack = (event: any) => {
1927
2205
  const isAudioOnly = this._isAudioOnly(session);
1928
- const { kind, label, readyState, id, muted } = event.track;
1929
- logger.info('on track event', { isAudioOnly, kind, label, readyState, id, muted });
2206
+
2207
+ const {
2208
+ kind,
2209
+ label,
2210
+ readyState,
2211
+ id,
2212
+ muted,
2213
+ } = event.track;
2214
+ logger.info('on track event', {
2215
+ isAudioOnly,
2216
+ kind,
2217
+ label,
2218
+ readyState,
2219
+ id,
2220
+ muted,
2221
+ });
1930
2222
 
1931
2223
  // Stop video track in audio only mode
1932
2224
  if (isAudioOnly && kind === 'video') {
@@ -1936,15 +2228,21 @@ export default class WebRTCClient extends Emitter {
1936
2228
  this.eventEmitter.emit(ON_TRACK, session, event);
1937
2229
  };
1938
2230
 
2231
+ // @ts-ignore
1939
2232
  if (session.sessionDescriptionHandler.peerConnection) {
2233
+ // @ts-ignore
1940
2234
  session.sessionDescriptionHandler.peerConnection.addEventListener('track', onTrack);
1941
2235
  }
1942
2236
 
2237
+ // @ts-ignore
1943
2238
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
1944
2239
 
1945
2240
  if (pc) {
1946
2241
  pc.oniceconnectionstatechange = () => {
1947
- logger.info('on ice connection state changed', { state: pc.iceConnectionState });
2242
+ logger.info('on ice connection state changed', {
2243
+ state: pc.iceConnectionState,
2244
+ });
2245
+
1948
2246
  if (pc.iceConnectionState === 'disconnected') {
1949
2247
  this.eventEmitter.emit(ON_DISCONNECTED);
1950
2248
  }
@@ -1958,17 +2256,19 @@ export default class WebRTCClient extends Emitter {
1958
2256
  this._startSendingStats(session);
1959
2257
  }
1960
2258
 
1961
- _isAudioOnly(session: Session): boolean {
1962
- return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === stripVideo);
2259
+ _isAudioOnly(session: Inviter | Invitation): boolean {
2260
+ return Boolean(session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === stripVideo));
1963
2261
  }
1964
2262
 
1965
- _setupMedias(session: Session, newStream: ?MediaStream) {
2263
+ _setupMedias(session: Inviter | Invitation, newStream: MediaStream | null | undefined = null): void {
1966
2264
  // Safari hack, because you cannot call .play() from a non user action
1967
2265
  const sessionId = this.getSipSessionId(session);
1968
2266
  const isConference = this.isConference(sessionId);
1969
2267
 
1970
2268
  if (sessionId in this.audioElements) {
1971
- logger.info('html element already exists for session', { sessionId });
2269
+ logger.info('html element already exists for session', {
2270
+ sessionId,
2271
+ });
1972
2272
  return;
1973
2273
  }
1974
2274
 
@@ -1977,10 +2277,11 @@ export default class WebRTCClient extends Emitter {
1977
2277
  }
1978
2278
 
1979
2279
  const audioElement = this.audioElements[sessionId];
2280
+ // @ts-ignore
1980
2281
  const sipSession = this.sipSessions[session.callId];
1981
2282
  const removeStream = this.getRemoteStream(sessionId);
1982
- const earlyStream = sipSession && sipSession.sessionDescriptionHandler
1983
- ? sipSession.sessionDescriptionHandler.remoteMediaStream : null;
2283
+ // @ts-ignore
2284
+ const earlyStream = sipSession && sipSession.sessionDescriptionHandler ? sipSession.sessionDescriptionHandler.remoteMediaStream : null;
1984
2285
  const stream = newStream || removeStream || earlyStream;
1985
2286
 
1986
2287
  if (!this._isWeb() || !stream) {
@@ -1995,30 +2296,34 @@ export default class WebRTCClient extends Emitter {
1995
2296
  if (audioElement.currentTime > 0 && !audioElement.paused && !audioElement.ended && audioElement.readyState > 2) {
1996
2297
  audioElement.pause();
1997
2298
  }
2299
+
1998
2300
  audioElement.srcObject = stream;
1999
2301
  audioElement.volume = this.audioOutputVolume;
2000
2302
  audioElement.play().catch(() => {});
2001
2303
  }
2002
2304
 
2003
- _cleanupMedia(session: Session) {
2305
+ _cleanupMedia(session?: Inviter | Invitation): void {
2004
2306
  const sessionId = this.getSipSessionId(session);
2005
2307
  const localStream = this.getLocalStream(sessionId);
2308
+
2006
2309
  if (localStream) {
2007
2310
  this._cleanupStream(localStream);
2008
2311
  }
2009
2312
 
2010
- const cleanLocalElement = id => {
2313
+ const cleanLocalElement = (id: string) => {
2011
2314
  const element = this.audioElements[id];
2315
+
2012
2316
  if (!element) {
2013
2317
  return;
2014
2318
  }
2015
2319
 
2016
2320
  element.pause();
2321
+
2017
2322
  if (element.parentNode) {
2018
2323
  element.parentNode.removeChild(element);
2019
2324
  }
2020
- element.srcObject = null;
2021
2325
 
2326
+ element.srcObject = null;
2022
2327
  delete this.audioElements[id];
2023
2328
  };
2024
2329
 
@@ -2031,25 +2336,27 @@ export default class WebRTCClient extends Emitter {
2031
2336
  }
2032
2337
  }
2033
2338
 
2034
- _cleanupStream(stream: MediaStream) {
2339
+ _cleanupStream(stream: MediaStream): void {
2035
2340
  stream.getTracks().forEach(track => track.stop());
2036
2341
  }
2037
2342
 
2038
- _toggleAudio(session: Inviter, muteAudio: boolean) {
2343
+ _toggleAudio(session: Inviter | Invitation, muteAudio: boolean): void {
2344
+ // @ts-ignore
2039
2345
  const pc = session.sessionDescriptionHandler ? session.sessionDescriptionHandler.peerConnection : null;
2346
+
2040
2347
  if (!pc) {
2041
2348
  return;
2042
2349
  }
2043
2350
 
2044
2351
  if (pc.getSenders) {
2045
- pc.getSenders().forEach(sender => {
2352
+ pc.getSenders().forEach((sender: any) => {
2046
2353
  if (sender && sender.track && sender.track.kind === 'audio') {
2047
2354
  // eslint-disable-next-line
2048
2355
  sender.track.enabled = !muteAudio;
2049
2356
  }
2050
2357
  });
2051
2358
  } else {
2052
- pc.getLocalStreams().forEach(stream => {
2359
+ pc.getLocalStreams().forEach((stream: MediaStream) => {
2053
2360
  stream.getAudioTracks().forEach(track => {
2054
2361
  // eslint-disable-next-line
2055
2362
  track.enabled = !muteAudio;
@@ -2058,18 +2365,19 @@ export default class WebRTCClient extends Emitter {
2058
2365
  }
2059
2366
  }
2060
2367
 
2061
- _toggleVideo(session: Inviter, muteCamera: boolean) {
2062
- const pc = session.sessionDescriptionHandler.peerConnection;
2368
+ _toggleVideo(session: Inviter | Invitation, muteCamera: boolean): void {
2369
+ // @ts-ignore
2370
+ const pc = session.sessionDescriptionHandler?.peerConnection;
2063
2371
 
2064
2372
  if (pc.getSenders) {
2065
- pc.getSenders().forEach(sender => {
2373
+ pc.getSenders().forEach((sender: any) => {
2066
2374
  if (sender && sender.track && sender.track.kind === 'video') {
2067
2375
  // eslint-disable-next-line
2068
2376
  sender.track.enabled = !muteCamera;
2069
2377
  }
2070
2378
  });
2071
2379
  } else {
2072
- pc.getLocalStreams().forEach(stream => {
2380
+ pc.getLocalStreams().forEach((stream: MediaStream) => {
2073
2381
  stream.getVideoTracks().forEach(track => {
2074
2382
  // eslint-disable-next-line
2075
2383
  track.enabled = !muteCamera;
@@ -2081,15 +2389,18 @@ export default class WebRTCClient extends Emitter {
2081
2389
  /**
2082
2390
  * @param pc RTCPeerConnection
2083
2391
  */
2084
- _getRemoteStream(pc: any) {
2085
- let remoteStream;
2392
+ _getRemoteStream(pc: any): MediaStream | null {
2393
+ let remoteStream: MediaStream | null = null;
2086
2394
 
2087
2395
  if (pc && pc.getReceivers) {
2088
- remoteStream = typeof global !== 'undefined' && global.window && global.window.MediaStream
2089
- ? new global.window.MediaStream() : new window.MediaStream();
2090
- pc.getReceivers().forEach(receiver => {
2091
- const { track } = receiver;
2092
- if (track) {
2396
+ remoteStream = typeof global !== 'undefined' && global.window && global.window.MediaStream ? new global.window.MediaStream() : new window.MediaStream();
2397
+
2398
+ pc.getReceivers().forEach((receiver: any) => {
2399
+ const {
2400
+ track,
2401
+ } = receiver;
2402
+
2403
+ if (track && remoteStream) {
2093
2404
  remoteStream.addTrack(track);
2094
2405
  }
2095
2406
  });
@@ -2100,24 +2411,31 @@ export default class WebRTCClient extends Emitter {
2100
2411
  return remoteStream;
2101
2412
  }
2102
2413
 
2103
- _cleanupRegister() {
2414
+ _cleanupRegister(): void {
2104
2415
  if (this.registerer) {
2416
+ // @ts-ignore
2105
2417
  this.registerer.stateChange.removeAllListeners();
2106
2418
  this.registerer = null;
2107
2419
  }
2108
2420
  }
2109
2421
 
2110
- _startSendingStats(session: Session) {
2422
+ _startSendingStats(session: Inviter | Invitation): void {
2423
+ // @ts-ignore
2111
2424
  const pc = session.sessionDescriptionHandler.peerConnection;
2425
+
2112
2426
  if (!pc) {
2113
2427
  return;
2114
2428
  }
2115
- const sessionId = this.getSipSessionId(session);
2116
2429
 
2117
- getStats(pc, (result: Object) => {
2118
- const { results, internal, nomore, ...stats } = result;
2430
+ const sessionId = this.getSipSessionId(session);
2431
+ getStats(pc, (result: Record<string, any>) => {
2432
+ const {
2433
+ results,
2434
+ internal,
2435
+ nomore,
2436
+ ...stats
2437
+ } = result;
2119
2438
  this.statsIntervals[sessionId] = nomore;
2120
-
2121
2439
  statsLogger.trace('stats', {
2122
2440
  sessionId,
2123
2441
  ...stats,
@@ -2125,27 +2443,35 @@ export default class WebRTCClient extends Emitter {
2125
2443
  }, SEND_STATS_DELAY);
2126
2444
  }
2127
2445
 
2128
- _stopSendingStats(session: Session) {
2446
+ _stopSendingStats(session: Invitation | Inviter): void {
2129
2447
  const sessionId = this.getSipSessionId(session);
2130
- logger.trace('Check for stopping stats', { sessionId, ids: Object.keys(this.statsIntervals) });
2448
+ logger.trace('Check for stopping stats', {
2449
+ sessionId,
2450
+ ids: Object.keys(this.statsIntervals),
2451
+ });
2131
2452
 
2132
2453
  if (sessionId in this.statsIntervals) {
2133
- logger.trace('Stop sending stats for call', { sessionId });
2454
+ logger.trace('Stop sending stats for call', {
2455
+ sessionId,
2456
+ });
2134
2457
  this.statsIntervals[sessionId]();
2135
2458
  delete this.statsIntervals[sessionId];
2136
2459
  }
2137
2460
  }
2138
2461
 
2139
- _makeURI(target: string): URI {
2462
+ _makeURI(target: string): URI | undefined {
2140
2463
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
2141
2464
  }
2142
2465
 
2143
- async _disconnectTransport(force: boolean = false) {
2466
+ async _disconnectTransport(force = false) {
2144
2467
  if (force && this.userAgent && this.userAgent.transport) {
2145
2468
  // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
2469
+ // @ts-ignore
2146
2470
  this.userAgent.transport.disconnectResolve = () => {};
2147
2471
 
2472
+ // @ts-ignore
2148
2473
  if (this.userAgent.transport._ws) {
2474
+ // @ts-ignore
2149
2475
  this.userAgent.transport._ws.close(1000);
2150
2476
  }
2151
2477
 
@@ -2153,24 +2479,25 @@ export default class WebRTCClient extends Emitter {
2153
2479
  }
2154
2480
 
2155
2481
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
2482
+ // @ts-ignore
2156
2483
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
2157
2484
  try {
2158
2485
  await this.userAgent.transport.disconnect();
2159
- } catch (e) {
2486
+ } catch (e: any) {
2160
2487
  logger.error('WebRTC transport disconnect, error', e);
2161
2488
  }
2162
2489
  }
2163
2490
  }
2164
2491
 
2165
- async _fetchNetworkStats(sessionId: string) {
2492
+ async _fetchNetworkStats(sessionId: string): Promise<Record<string, any> | null | undefined> {
2166
2493
  const session = this.getSipSession(sessionId);
2167
-
2168
2494
  const stats = session ? await this.getStats(session) : null;
2495
+
2169
2496
  if (!stats || !(sessionId in this.sessionNetworkStats)) {
2170
- return;
2497
+ return Promise.resolve(null);
2171
2498
  }
2172
2499
 
2173
- const networkStats: Object = {
2500
+ const networkStats: Record<string, any> = {
2174
2501
  audioBytesSent: 0,
2175
2502
  videoBytesSent: 0,
2176
2503
  videoBytesReceived: 0,
@@ -2187,70 +2514,77 @@ export default class WebRTCClient extends Emitter {
2187
2514
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
2188
2515
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
2189
2516
  let audioBytesSent = 0; // content + header
2517
+
2190
2518
  let audioBytesReceived = 0; // content + header
2519
+
2191
2520
  let audioContentSent = 0; // useful to detect blank call
2521
+
2192
2522
  let audioContentReceived = 0;
2193
2523
  let videoBytesSent = 0;
2194
2524
  let videoBytesReceived = 0;
2195
2525
  let transportSent = 0;
2196
2526
  let transportReceived = 0;
2197
2527
  let packetsLost = 0;
2198
-
2199
2528
  stats.forEach(report => {
2200
2529
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
2201
2530
  audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
2202
2531
  audioContentSent += Number(report.bytesSent);
2203
2532
  }
2533
+
2204
2534
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
2205
2535
  audioBytesSent += Number(report.bytesSent);
2206
2536
  }
2537
+
2207
2538
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
2208
2539
  videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
2209
2540
  }
2541
+
2210
2542
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
2211
2543
  packetsLost += Number(report.packetsLost);
2212
2544
  networkStats.packetsReceived = Number(report.packetsReceived);
2213
2545
  audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
2214
2546
  audioContentReceived += Number(report.bytesReceived);
2215
2547
  }
2548
+
2216
2549
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
2217
2550
  videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
2218
2551
  }
2552
+
2219
2553
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
2220
2554
  if ('framesPerSecond' in report) {
2221
2555
  networkStats.framesPerSecond = Number(report.framesPerSecond);
2222
2556
  }
2557
+
2223
2558
  if ('framerateMean' in report) {
2224
2559
  // framerateMean is only available in FF
2225
2560
  networkStats.framesPerSecond = Math.round(report.framerateMean);
2226
2561
  }
2227
2562
  }
2563
+
2228
2564
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
2229
2565
  packetsLost += Number(report.packetsLost);
2230
2566
  networkStats.roundTripTime = Number(report.roundTripTime);
2231
2567
  networkStats.jitter = Number(report.jitter);
2232
2568
  }
2569
+
2233
2570
  if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
2234
2571
  packetsLost += Number(report.packetsLost);
2235
2572
  }
2573
+
2236
2574
  if (report.type === 'transport') {
2237
2575
  transportSent += Number(report.bytesSent);
2238
2576
  transportReceived += Number(report.bytesReceived);
2239
2577
  }
2240
2578
  });
2241
-
2242
2579
  networkStats.packetsLost = packetsLost;
2243
-
2244
2580
  networkStats.totalAudioBytesSent = audioBytesSent;
2245
2581
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
2246
2582
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
2247
2583
  networkStats.audioBytesReceived = audioBytesReceived;
2248
-
2249
2584
  networkStats.totalAudioContentSent = audioContentSent;
2250
2585
  networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
2251
2586
  networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
2252
2587
  networkStats.audioContentReceived = audioContentReceived;
2253
-
2254
2588
  networkStats.totalVideoBytesSent = videoBytesSent;
2255
2589
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
2256
2590
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -2259,13 +2593,82 @@ export default class WebRTCClient extends Emitter {
2259
2593
  networkStats.transportSent = transportSent;
2260
2594
  networkStats.totalTransportReceived = transportReceived;
2261
2595
  networkStats.transportReceived = transportReceived - lastTransportReceived;
2262
-
2263
- networkStats.bandwidth = networkStats.audioBytesSent + networkStats.audioBytesReceived
2264
- + networkStats.videoBytesSent + networkStats.videoBytesReceived + networkStats.transportReceived
2265
- + networkStats.transportSent;
2266
-
2596
+ networkStats.bandwidth = networkStats.audioBytesSent + networkStats.audioBytesReceived + networkStats.videoBytesSent + networkStats.videoBytesReceived + networkStats.transportReceived + networkStats.transportSent;
2267
2597
  this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
2268
2598
  this.sessionNetworkStats[sessionId].push(networkStats);
2269
2599
  }
2270
2600
 
2601
+ async _accept(session: Invitation, options: InvitationAcceptOptions = {}) {
2602
+ if (session.state === SessionState.Terminated || session.state === SessionState.Terminating) {
2603
+ const error = 'Trying to accept a terminated sipSession.';
2604
+ logger.warn(error, { state: session.state, sessionId: session.id });
2605
+ throw new Error(error);
2606
+ }
2607
+
2608
+ if (session.state !== SessionState.Initial) {
2609
+ const error = 'Trying to accept a non Initial sipSession.';
2610
+ logger.warn(error, { state: session.state, sessionId: session.id });
2611
+ throw new Error(error);
2612
+ }
2613
+
2614
+ // @ts-ignore
2615
+ if (!session.incomingInviteRequest.acceptable) {
2616
+ const error = 'Trying to reject a non `acceptable` session';
2617
+ logger.warn(error, { state: session.state, sessionId: session.id });
2618
+ throw new Error(error);
2619
+ }
2620
+
2621
+ try {
2622
+ return await session.accept(options);
2623
+ } catch (e) {
2624
+ logger.warn('Session accept, error', e);
2625
+ }
2626
+ }
2627
+
2628
+ async _reject(session: Invitation, options: InvitationRejectOptions = {}) {
2629
+ if (session.state !== SessionState.Initial && session.state !== SessionState.Establishing) {
2630
+ logger.warn('Trying to reject a session in a wrong state', { state: session.state, sessionId: session.id });
2631
+ return;
2632
+ }
2633
+
2634
+ // @ts-ignore
2635
+ if (!session.incomingInviteRequest.rejectable) {
2636
+ logger.warn('Trying to reject a non `rejectable` session', { state: session.state, sessionId: session.id });
2637
+ return;
2638
+ }
2639
+
2640
+ try {
2641
+ return await session.reject(options);
2642
+ } catch (e) {
2643
+ logger.warn('Session reject, error', e);
2644
+ }
2645
+ }
2646
+
2647
+ async _cancel(session: Inviter, options: InviterCancelOptions = {}) {
2648
+ if (session.state !== SessionState.Initial && session.state !== SessionState.Establishing) {
2649
+ logger.warn('Trying to cancel a session in a wrong state', { state: session.state, sessionId: session.id });
2650
+ return;
2651
+ }
2652
+
2653
+ try {
2654
+ return await session.cancel(options);
2655
+ } catch (e) {
2656
+ logger.warn('Session cancel, error', e);
2657
+ }
2658
+ }
2659
+
2660
+ async _bye(session: Invitation | Inviter, options: SessionByeOptions = {}) {
2661
+ if (session.state !== SessionState.Established) {
2662
+ logger.warn('Trying to end a session in a wrong state', { state: session.state, sessionId: session.id });
2663
+ return null;
2664
+ }
2665
+
2666
+ try {
2667
+ return await session.bye(options);
2668
+ } catch (e) {
2669
+ logger.warn('Session bye, error', e);
2670
+ }
2671
+
2672
+ return null;
2673
+ }
2271
2674
  }