@wazo/sdk 0.37.21 → 0.37.25

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 (118) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +36 -5
  3. package/esm/__tests__/web-rtc-client.test.js +77 -66
  4. package/esm/api/call-logd.js +7 -0
  5. package/esm/api/calld.js +10 -0
  6. package/esm/api/chatd.js +7 -0
  7. package/esm/api/confd.js +13 -5
  8. package/esm/api/ctid-ng.js +10 -0
  9. package/esm/api/dird.js +3 -0
  10. package/esm/api-client.js +36 -5
  11. package/esm/checker/Checker.js +77 -66
  12. package/esm/checker/checks/aor.js +36 -5
  13. package/esm/checker/checks/api.js +36 -5
  14. package/esm/checker/checks/index.js +77 -66
  15. package/esm/checker/checks/webrtc-transport.js +77 -66
  16. package/esm/checker/checks/webrtc.js +77 -66
  17. package/esm/domain/AdHocAPIConference.js +36 -5
  18. package/esm/domain/Call.js +3 -0
  19. package/esm/domain/CallLog.js +7 -0
  20. package/esm/domain/ChatMessage.js +4 -0
  21. package/esm/domain/ChatRoom.js +3 -0
  22. package/esm/domain/Contact.js +3 -0
  23. package/esm/domain/Features.js +36 -5
  24. package/esm/domain/Meeting.js +15 -5
  25. package/esm/domain/Phone/CTIPhone.js +40 -5
  26. package/esm/domain/Phone/WebRTCPhone.js +45 -16
  27. package/esm/domain/Recording.js +3 -0
  28. package/esm/domain/Voicemail.js +3 -0
  29. package/esm/domain/__tests__/Call.test.js +3 -0
  30. package/esm/domain/__tests__/CallLog.test.js +7 -0
  31. package/esm/domain/__tests__/Contact.test.js +3 -0
  32. package/esm/domain/__tests__/Meeting.test.js +144 -0
  33. package/esm/domain/__tests__/Voicemail.test.js +3 -0
  34. package/esm/index.js +125 -81
  35. package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
  36. package/esm/service/CallApi.js +36 -5
  37. package/esm/service/getApiClient.js +36 -5
  38. package/esm/simple/Auth.js +125 -81
  39. package/esm/simple/Configuration.js +125 -81
  40. package/esm/simple/Directory.js +36 -5
  41. package/esm/simple/Phone.js +125 -81
  42. package/esm/simple/index.js +125 -81
  43. package/esm/simple/room/LocalParticipant.js +125 -81
  44. package/esm/simple/room/Participant.js +125 -81
  45. package/esm/simple/room/RemoteParticipant.js +125 -81
  46. package/esm/simple/room/Room.js +125 -81
  47. package/esm/simple/room/SipRoom.js +125 -81
  48. package/esm/simple/room/Stream.js +125 -81
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +125 -81
  50. package/esm/simple/utils.js +125 -81
  51. package/esm/types/WebSocketMessage.js +1 -1
  52. package/esm/web-rtc-client.js +77 -66
  53. package/lib/__tests__/api-client.test.js +36 -5
  54. package/lib/__tests__/web-rtc-client.test.js +77 -66
  55. package/lib/api/call-logd.js +7 -0
  56. package/lib/api/calld.js +10 -0
  57. package/lib/api/chatd.js +7 -0
  58. package/lib/api/confd.js +13 -5
  59. package/lib/api/ctid-ng.js +10 -0
  60. package/lib/api/dird.js +3 -0
  61. package/lib/api-client.js +36 -5
  62. package/lib/checker/Checker.js +77 -66
  63. package/lib/checker/checks/aor.js +36 -5
  64. package/lib/checker/checks/api.js +36 -5
  65. package/lib/checker/checks/index.js +77 -66
  66. package/lib/checker/checks/webrtc-transport.js +77 -66
  67. package/lib/checker/checks/webrtc.js +77 -66
  68. package/lib/domain/AdHocAPIConference.js +36 -5
  69. package/lib/domain/Call.js +3 -0
  70. package/lib/domain/CallLog.js +7 -0
  71. package/lib/domain/ChatMessage.js +4 -0
  72. package/lib/domain/ChatRoom.js +3 -0
  73. package/lib/domain/Contact.js +3 -0
  74. package/lib/domain/Features.js +36 -5
  75. package/lib/domain/Meeting.js +19 -5
  76. package/lib/domain/Phone/CTIPhone.js +40 -5
  77. package/lib/domain/Phone/WebRTCPhone.js +45 -16
  78. package/lib/domain/Recording.js +3 -0
  79. package/lib/domain/Voicemail.js +3 -0
  80. package/lib/domain/__tests__/Call.test.js +3 -0
  81. package/lib/domain/__tests__/CallLog.test.js +7 -0
  82. package/lib/domain/__tests__/Contact.test.js +3 -0
  83. package/lib/domain/__tests__/Meeting.test.js +150 -0
  84. package/lib/domain/__tests__/Voicemail.test.js +3 -0
  85. package/lib/index.js +125 -81
  86. package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
  87. package/lib/service/CallApi.js +36 -5
  88. package/lib/service/getApiClient.js +36 -5
  89. package/lib/simple/Auth.js +125 -81
  90. package/lib/simple/Configuration.js +125 -81
  91. package/lib/simple/Directory.js +36 -5
  92. package/lib/simple/Phone.js +125 -81
  93. package/lib/simple/index.js +125 -81
  94. package/lib/simple/room/LocalParticipant.js +125 -81
  95. package/lib/simple/room/Participant.js +125 -81
  96. package/lib/simple/room/RemoteParticipant.js +125 -81
  97. package/lib/simple/room/Room.js +125 -81
  98. package/lib/simple/room/SipRoom.js +125 -81
  99. package/lib/simple/room/Stream.js +125 -81
  100. package/lib/simple/room/__tests__/RemoteParticipant.test.js +125 -81
  101. package/lib/simple/utils.js +125 -81
  102. package/lib/types/WebSocketMessage.js +2 -0
  103. package/lib/web-rtc-client.js +77 -66
  104. package/package.json +1 -1
  105. package/src/domain/Call.js +3 -0
  106. package/src/domain/CallLog.js +4 -0
  107. package/src/domain/ChatMessage.js +4 -0
  108. package/src/domain/ChatRoom.js +3 -0
  109. package/src/domain/Contact.js +3 -0
  110. package/src/domain/Meeting.js +15 -5
  111. package/src/domain/Phone/CTIPhone.js +4 -0
  112. package/src/domain/Phone/Phone.js +2 -0
  113. package/src/domain/Phone/WebRTCPhone.js +45 -16
  114. package/src/domain/Recording.js +3 -0
  115. package/src/domain/Voicemail.js +3 -0
  116. package/src/domain/__tests__/Meeting.test.js +50 -0
  117. package/src/lib/WazoSessionDescriptionHandler.js +1 -35
  118. package/src/web-rtc-client.js +41 -23
package/lib/index.js CHANGED
@@ -1562,6 +1562,9 @@ class Contact {
1562
1562
  }
1563
1563
 
1564
1564
  static parseMany(response ) {
1565
+ if (!response || !response.results) {
1566
+ return [];
1567
+ }
1565
1568
  return response.results.map(r => Contact.parse(r, response.column_types));
1566
1569
  }
1567
1570
 
@@ -2639,8 +2642,9 @@ class ExternalApp {
2639
2642
 
2640
2643
 
2641
2644
 
2642
-
2645
+
2643
2646
 
2647
+
2644
2648
 
2645
2649
 
2646
2650
  class Meeting {
@@ -2651,9 +2655,10 @@ class Meeting {
2651
2655
 
2652
2656
 
2653
2657
 
2654
-
2658
+
2655
2659
 
2656
2660
 
2661
+
2657
2662
 
2658
2663
  static parse(plain ) {
2659
2664
  return new Meeting({
@@ -2663,12 +2668,16 @@ class Meeting {
2663
2668
  ownerUuids: plain.owner_uuids,
2664
2669
  port: plain.port,
2665
2670
  uuid: plain.uuid,
2666
- number: plain.number,
2671
+ extension: plain.exten,
2667
2672
  persistent: plain.persistent,
2673
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
2668
2674
  });
2669
2675
  }
2670
2676
 
2671
2677
  static parseMany(items ) {
2678
+ if (!items) {
2679
+ return [];
2680
+ }
2672
2681
  return items.map(plain => Meeting.parse(plain));
2673
2682
  }
2674
2683
 
@@ -2683,8 +2692,9 @@ class Meeting {
2683
2692
  ownerUuids,
2684
2693
  port,
2685
2694
  uri,
2686
- number,
2695
+ extension,
2687
2696
  persistent,
2697
+ creationTime,
2688
2698
  } = {}) {
2689
2699
  this.guestSipAuthorization = guestSipAuthorization;
2690
2700
  this.uri = uri;
@@ -2692,8 +2702,9 @@ class Meeting {
2692
2702
  this.ownerUuids = ownerUuids;
2693
2703
  this.port = port;
2694
2704
  this.uuid = uuid;
2695
- this.number = number;
2705
+ this.extension = extension;
2696
2706
  this.persistent = persistent;
2707
+ this.creationTime = creationTime;
2697
2708
 
2698
2709
  // Useful to compare instead of instanceof with minified code
2699
2710
  this.type = 'Meeting';
@@ -2871,6 +2882,10 @@ class ChatMessage {
2871
2882
 
2872
2883
 
2873
2884
  static parseMany(plain ) {
2885
+ if (!plain || !plain.items) {
2886
+ return [];
2887
+ }
2888
+
2874
2889
  return plain.items.map(item => ChatMessage.parse(item));
2875
2890
  }
2876
2891
 
@@ -2980,6 +2995,9 @@ class Voicemail {
2980
2995
  }
2981
2996
 
2982
2997
  static parseMany(plain ) {
2998
+ if (!plain) {
2999
+ return [];
3000
+ }
2983
3001
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2984
3002
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2985
3003
 
@@ -3089,6 +3107,9 @@ class Call {
3089
3107
 
3090
3108
 
3091
3109
  static parseMany(plain ) {
3110
+ if (!plain) {
3111
+ return [];
3112
+ }
3092
3113
  return plain.map((plainCall ) => Call.parse(plainCall));
3093
3114
  }
3094
3115
 
@@ -3632,6 +3653,9 @@ class Recording {
3632
3653
 
3633
3654
 
3634
3655
  static parseMany(recordings = []) {
3656
+ if (!recordings) {
3657
+ return [];
3658
+ }
3635
3659
  return recordings.map(item => Recording.parse(item));
3636
3660
  }
3637
3661
 
@@ -3733,6 +3757,10 @@ class CallLog {
3733
3757
  }
3734
3758
 
3735
3759
  static parseMany(plain ) {
3760
+ if (!plain || !plain.items) {
3761
+ return [];
3762
+ }
3763
+
3736
3764
  return plain.items.map(item => CallLog.parse(item));
3737
3765
  }
3738
3766
 
@@ -4385,6 +4413,10 @@ class CTIPhone extends Emitter {
4385
4413
  return false;
4386
4414
  }
4387
4415
 
4416
+ hasAVideoTrack() {
4417
+ return false;
4418
+ }
4419
+
4388
4420
  getLocalStreamForCall() {
4389
4421
  return null;
4390
4422
  }
@@ -4778,6 +4810,9 @@ class ChatRoom {
4778
4810
 
4779
4811
 
4780
4812
  static parseMany(plain ) {
4813
+ if (!plain || !plain.items) {
4814
+ return [];
4815
+ }
4781
4816
  return plain.items.map(item => ChatRoom.parse(item));
4782
4817
  }
4783
4818
 
@@ -5501,10 +5536,6 @@ const getSrflxOrRelay = (candidates ) =>
5501
5536
  candidates
5502
5537
  .filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
5503
5538
 
5504
- const areCandidateValid = (candidates ) =>
5505
- getSrflxOrRelay(candidates)
5506
- .length > 0;
5507
-
5508
5539
  const getVideoDirection = (sdp ) => {
5509
5540
  const parsedSdp = sdpParser__default['default'].parse(sdp);
5510
5541
  const videoMedia = parsedSdp.media.find(media => media.type === 'video');
@@ -5557,8 +5588,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
5557
5588
  /* global RTCSessionDescriptionInit, navigator */
5558
5589
 
5559
5590
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
5560
- const MAX_WAIT_FOR_ICE_TRIES = 20;
5561
- const WAIT_FOR_ICE_TIMEOUT = 500;
5562
5591
 
5563
5592
  // Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
5564
5593
  const wazoMediaStreamFactory = (constraints ) => {
@@ -5748,38 +5777,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
5748
5777
  this._peerConnection = undefined;
5749
5778
  }
5750
5779
 
5751
- async _waitForValidGatheredIce() {
5752
- let tries = 0;
5753
-
5754
- while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
5755
- wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
5756
- tries,
5757
- max: MAX_WAIT_FOR_ICE_TRIES,
5758
- });
5759
-
5760
- tries++;
5761
-
5762
- // eslint-disable-next-line no-await-in-loop
5763
- await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
5764
- }
5765
-
5766
- if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
5767
- const errorMsg = 'No valid candidates found, can\'t answer the call';
5768
- const error = new Error(errorMsg);
5769
- wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
5770
-
5771
- // Emit an error, because sip.js catches the exception and switch to status Terminated.
5772
- this.eventEmitter.emit('error', error);
5773
-
5774
- wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5775
- }
5776
-
5777
- // eslint-disable-next-line
5778
- wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5779
-
5780
- return this.getLocalSessionDescription();
5781
- }
5782
-
5783
5780
  // Overridden to send `inactive` in conference
5784
5781
  updateDirection(options , isConference = false,
5785
5782
  audioOnly = false) {
@@ -6547,7 +6544,7 @@ class WebRTCClient extends Emitter {
6547
6544
  }
6548
6545
 
6549
6546
  call(number , enableVideo , audioOnly = false, conference = false) {
6550
- logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6547
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6551
6548
  const inviterOptions = {
6552
6549
  sessionDescriptionHandlerOptionsReInvite: {
6553
6550
  conference,
@@ -7623,6 +7620,7 @@ class WebRTCClient extends Emitter {
7623
7620
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
7624
7621
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
7625
7622
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
7623
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
7626
7624
 
7627
7625
  logger$9.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
7628
7626
 
@@ -7630,7 +7628,8 @@ class WebRTCClient extends Emitter {
7630
7628
  constraints: {
7631
7629
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
7632
7630
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
7633
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
7631
+ video: screenSharing ? (isDesktop
7632
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
7634
7633
  : this._getVideoConstraints(enableVideo),
7635
7634
  screen: screenSharing,
7636
7635
  desktop: isDesktop,
@@ -7965,11 +7964,14 @@ class WebRTCClient extends Emitter {
7965
7964
 
7966
7965
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7967
7966
 
7968
- pc.oniceconnectionstatechange = () => {
7969
- if (pc.iceConnectionState === 'disconnected') {
7970
- this.eventEmitter.emit(ON_DISCONNECTED$1);
7971
- }
7972
- };
7967
+ if (pc) {
7968
+ pc.oniceconnectionstatechange = () => {
7969
+ logger$9.info('on ice connection state changed', { state: pc.iceConnectionState });
7970
+ if (pc.iceConnectionState === 'disconnected') {
7971
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
7972
+ }
7973
+ };
7974
+ }
7973
7975
 
7974
7976
  if (withEvent) {
7975
7977
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8179,13 +8181,17 @@ class WebRTCClient extends Emitter {
8179
8181
  const nbStats = this.sessionNetworkStats[sessionId].length;
8180
8182
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8181
8183
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8184
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8182
8185
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8183
8186
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8187
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8184
8188
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8185
8189
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8186
8190
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8187
- let audioBytesSent = 0;
8188
- let audioBytesReceived = 0;
8191
+ let audioBytesSent = 0; // content + header
8192
+ let audioBytesReceived = 0; // content + header
8193
+ let audioContentSent = 0; // useful to detect blank call
8194
+ let audioContentReceived = 0;
8189
8195
  let videoBytesSent = 0;
8190
8196
  let videoBytesReceived = 0;
8191
8197
  let transportSent = 0;
@@ -8194,25 +8200,27 @@ class WebRTCClient extends Emitter {
8194
8200
 
8195
8201
  stats.forEach(report => {
8196
8202
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8197
- audioBytesSent += report.bytesSent + report.headerBytesSent;
8203
+ audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8204
+ audioContentSent += Number(report.bytesSent);
8198
8205
  }
8199
8206
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8200
- audioBytesSent += report.bytesSent;
8207
+ audioBytesSent += Number(report.bytesSent);
8201
8208
  }
8202
8209
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8203
- videoBytesSent += report.bytesSent + report.headerBytesSent;
8210
+ videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8204
8211
  }
8205
8212
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8206
- packetsLost += report.packetsLost;
8207
- networkStats.packetsReceived = report.packetsReceived;
8208
- audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8213
+ packetsLost += Number(report.packetsLost);
8214
+ networkStats.packetsReceived = Number(report.packetsReceived);
8215
+ audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8216
+ audioContentReceived += Number(report.bytesReceived);
8209
8217
  }
8210
8218
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8211
- videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8219
+ videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8212
8220
  }
8213
8221
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8214
8222
  if ('framesPerSecond' in report) {
8215
- networkStats.framesPerSecond = report.framesPerSecond;
8223
+ networkStats.framesPerSecond = Number(report.framesPerSecond);
8216
8224
  }
8217
8225
  if ('framerateMean' in report) {
8218
8226
  // framerateMean is only available in FF
@@ -8220,24 +8228,31 @@ class WebRTCClient extends Emitter {
8220
8228
  }
8221
8229
  }
8222
8230
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8223
- packetsLost += report.packetsLost;
8224
- networkStats.roundTripTime = report.roundTripTime;
8225
- networkStats.jitter = report.jitter;
8231
+ packetsLost += Number(report.packetsLost);
8232
+ networkStats.roundTripTime = Number(report.roundTripTime);
8233
+ networkStats.jitter = Number(report.jitter);
8226
8234
  }
8227
8235
  if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
8228
- packetsLost += report.packetsLost;
8236
+ packetsLost += Number(report.packetsLost);
8229
8237
  }
8230
8238
  if (report.type === 'transport') {
8231
- transportSent += report.bytesSent;
8232
- transportReceived += report.bytesReceived;
8239
+ transportSent += Number(report.bytesSent);
8240
+ transportReceived += Number(report.bytesReceived);
8233
8241
  }
8234
8242
  });
8235
8243
 
8236
8244
  networkStats.packetsLost = packetsLost;
8245
+
8237
8246
  networkStats.totalAudioBytesSent = audioBytesSent;
8238
8247
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8239
8248
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8240
8249
  networkStats.audioBytesReceived = audioBytesReceived;
8250
+
8251
+ networkStats.totalAudioContentSent = audioContentSent;
8252
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8253
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8254
+ networkStats.audioContentReceived = audioContentReceived;
8255
+
8241
8256
  networkStats.totalVideoBytesSent = videoBytesSent;
8242
8257
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8243
8258
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -9342,6 +9357,7 @@ class WebRTCPhone extends Emitter {
9342
9357
  constraints,
9343
9358
  audioOnly,
9344
9359
  conference,
9360
+ iceRestart,
9345
9361
  });
9346
9362
 
9347
9363
  if (!sipSession) {
@@ -9445,6 +9461,11 @@ class WebRTCPhone extends Emitter {
9445
9461
 
9446
9462
  this.client.downgradeToAudio(sipSession);
9447
9463
 
9464
+ if (callSession) {
9465
+ callSession.cameraEnabled = false;
9466
+ this._updateCallSession(callSession);
9467
+ }
9468
+
9448
9469
  if (withMessage) {
9449
9470
  this._sendReinviteMessage(callSession, false);
9450
9471
  }
@@ -9472,6 +9493,11 @@ class WebRTCPhone extends Emitter {
9472
9493
 
9473
9494
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
9474
9495
 
9496
+ if (callSession) {
9497
+ callSession.cameraEnabled = true;
9498
+ this._updateCallSession(callSession);
9499
+ }
9500
+
9475
9501
  // If no stream is returned, it means we have to reinvite
9476
9502
  if (!newStream) {
9477
9503
  return true;
@@ -9524,7 +9550,10 @@ class WebRTCPhone extends Emitter {
9524
9550
 
9525
9551
  onCancel(message);
9526
9552
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
9527
- this.eventEmitter.emit(ON_CALL_CANCELED, this._createCallSession(sipSession), elsewhere);
9553
+ const callSession = this._createCallSession(sipSession);
9554
+ delete this.callSessions[callSession.getId()];
9555
+
9556
+ this.eventEmitter.emit(ON_CALL_CANCELED, callSession, elsewhere);
9528
9557
  };
9529
9558
  } else if (sipSession instanceof invitation.Invitation) {
9530
9559
  console.warn('sipSession._onCancel not found, please update the wazo SDK accordingly');
@@ -9705,18 +9734,20 @@ class WebRTCPhone extends Emitter {
9705
9734
  screenTrack,
9706
9735
  });
9707
9736
 
9708
- screenTrack.onended = () => {
9709
- logger$7.info('WebRTC phone - on screenshare ended', {
9710
- hadVideo,
9711
- id: this.getSipSessionId(sipSession),
9712
- screenTrack,
9713
- });
9737
+ if (screenTrack) {
9738
+ screenTrack.onended = () => {
9739
+ logger$7.info('WebRTC phone - on screenshare ended', {
9740
+ hadVideo,
9741
+ id: this.getSipSessionId(sipSession),
9742
+ screenTrack,
9743
+ });
9714
9744
 
9715
- this.eventEmitter.emit(
9716
- ON_SHARE_SCREEN_ENDING,
9717
- this._createCallSession(sipSession, callSession),
9718
- );
9719
- };
9745
+ this.eventEmitter.emit(
9746
+ ON_SHARE_SCREEN_ENDING,
9747
+ this._createCallSession(sipSession, callSession),
9748
+ );
9749
+ };
9750
+ }
9720
9751
 
9721
9752
  this.currentScreenShare = {
9722
9753
  stream: screenStream,
@@ -9736,7 +9767,7 @@ class WebRTCPhone extends Emitter {
9736
9767
  }
9737
9768
 
9738
9769
  _onCallAccepted(sipSession , cameraEnabled ) {
9739
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9770
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9740
9771
 
9741
9772
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9742
9773
  this.currentSipSession = sipSession;
@@ -10248,7 +10279,7 @@ class WebRTCPhone extends Emitter {
10248
10279
  // @TODO: line is not used here
10249
10280
  async makeCall(number , line , cameraEnabled ,
10250
10281
  audioOnly = false, conference = false) {
10251
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
10282
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
10252
10283
  if (!number) {
10253
10284
  return Promise.resolve(null);
10254
10285
  }
@@ -10609,9 +10640,13 @@ class WebRTCPhone extends Emitter {
10609
10640
  if (this.shouldSendReinvite && this.currentSipSession
10610
10641
  && this.currentSipSession.state === sessionState.SessionState.Established) {
10611
10642
  this.shouldSendReinvite = false;
10643
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
10644
+ const isConference = pc ? pc.sfu : false;
10645
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
10646
+
10612
10647
  try {
10613
10648
  // Send reinvite with iceRestart
10614
- this.sendReinvite(this.currentCallSession, null, false, false, true);
10649
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
10615
10650
  } catch (e) {
10616
10651
  logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
10617
10652
  }
@@ -10695,6 +10730,15 @@ class WebRTCPhone extends Emitter {
10695
10730
  return this.client.getSipSessionId(sipSession);
10696
10731
  }
10697
10732
 
10733
+ _updateCallSession(callSession ) {
10734
+ const sipSession = this.findSipSession(callSession);
10735
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10736
+
10737
+ if (sipSessionId) {
10738
+ this.callSessions[sipSessionId] = callSession;
10739
+ }
10740
+ }
10741
+
10698
10742
  _onMessage(message ) {
10699
10743
  if (!message || message.method !== 'MESSAGE') {
10700
10744
  return;
@@ -419,10 +419,6 @@ const getSrflxOrRelay = (candidates ) =>
419
419
  candidates
420
420
  .filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
421
421
 
422
- const areCandidateValid = (candidates ) =>
423
- getSrflxOrRelay(candidates)
424
- .length > 0;
425
-
426
422
  const fixSdp = (sdp , candidates , forcePort = true) => {
427
423
  const parsedSdp = sdpParser__default['default'].parse(sdp);
428
424
  const mainCandidate = getSrflxOrRelay(candidates)[0];
@@ -454,8 +450,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
454
450
  /* global RTCSessionDescriptionInit, navigator */
455
451
 
456
452
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
457
- const MAX_WAIT_FOR_ICE_TRIES = 20;
458
- const WAIT_FOR_ICE_TIMEOUT = 500;
459
453
 
460
454
  // Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
461
455
  const wazoMediaStreamFactory = (constraints ) => {
@@ -645,38 +639,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
645
639
  this._peerConnection = undefined;
646
640
  }
647
641
 
648
- async _waitForValidGatheredIce() {
649
- let tries = 0;
650
-
651
- while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
652
- wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
653
- tries,
654
- max: MAX_WAIT_FOR_ICE_TRIES,
655
- });
656
-
657
- tries++;
658
-
659
- // eslint-disable-next-line no-await-in-loop
660
- await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
661
- }
662
-
663
- if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
664
- const errorMsg = 'No valid candidates found, can\'t answer the call';
665
- const error = new Error(errorMsg);
666
- wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
667
-
668
- // Emit an error, because sip.js catches the exception and switch to status Terminated.
669
- this.eventEmitter.emit('error', error);
670
-
671
- wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
672
- }
673
-
674
- // eslint-disable-next-line
675
- wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
676
-
677
- return this.getLocalSessionDescription();
678
- }
679
-
680
642
  // Overridden to send `inactive` in conference
681
643
  updateDirection(options , isConference = false,
682
644
  audioOnly = false) {
@@ -82,6 +82,9 @@ class Call {
82
82
 
83
83
 
84
84
  static parseMany(plain ) {
85
+ if (!plain) {
86
+ return [];
87
+ }
85
88
  return plain.map((plainCall ) => Call.parse(plainCall));
86
89
  }
87
90
 
@@ -1040,6 +1043,9 @@ class Contact {
1040
1043
  }
1041
1044
 
1042
1045
  static parseMany(response ) {
1046
+ if (!response || !response.results) {
1047
+ return [];
1048
+ }
1043
1049
  return response.results.map(r => Contact.parse(r, response.column_types));
1044
1050
  }
1045
1051
 
@@ -1712,6 +1718,9 @@ class Recording {
1712
1718
 
1713
1719
 
1714
1720
  static parseMany(recordings = []) {
1721
+ if (!recordings) {
1722
+ return [];
1723
+ }
1715
1724
  return recordings.map(item => Recording.parse(item));
1716
1725
  }
1717
1726
 
@@ -1813,6 +1822,10 @@ class CallLog {
1813
1822
  }
1814
1823
 
1815
1824
  static parseMany(plain ) {
1825
+ if (!plain || !plain.items) {
1826
+ return [];
1827
+ }
1828
+
1816
1829
  return plain.items.map(item => CallLog.parse(item));
1817
1830
  }
1818
1831
 
@@ -3138,8 +3151,9 @@ class ExternalApp {
3138
3151
 
3139
3152
 
3140
3153
 
3141
-
3154
+
3142
3155
 
3156
+
3143
3157
 
3144
3158
 
3145
3159
  class Meeting {
@@ -3150,9 +3164,10 @@ class Meeting {
3150
3164
 
3151
3165
 
3152
3166
 
3153
-
3167
+
3154
3168
 
3155
3169
 
3170
+
3156
3171
 
3157
3172
  static parse(plain ) {
3158
3173
  return new Meeting({
@@ -3162,12 +3177,16 @@ class Meeting {
3162
3177
  ownerUuids: plain.owner_uuids,
3163
3178
  port: plain.port,
3164
3179
  uuid: plain.uuid,
3165
- number: plain.number,
3180
+ extension: plain.exten,
3166
3181
  persistent: plain.persistent,
3182
+ creationTime: moment__default['default'](plain.creation_time).toDate(),
3167
3183
  });
3168
3184
  }
3169
3185
 
3170
3186
  static parseMany(items ) {
3187
+ if (!items) {
3188
+ return [];
3189
+ }
3171
3190
  return items.map(plain => Meeting.parse(plain));
3172
3191
  }
3173
3192
 
@@ -3182,8 +3201,9 @@ class Meeting {
3182
3201
  ownerUuids,
3183
3202
  port,
3184
3203
  uri,
3185
- number,
3204
+ extension,
3186
3205
  persistent,
3206
+ creationTime,
3187
3207
  } = {}) {
3188
3208
  this.guestSipAuthorization = guestSipAuthorization;
3189
3209
  this.uri = uri;
@@ -3191,8 +3211,9 @@ class Meeting {
3191
3211
  this.ownerUuids = ownerUuids;
3192
3212
  this.port = port;
3193
3213
  this.uuid = uuid;
3194
- this.number = number;
3214
+ this.extension = extension;
3195
3215
  this.persistent = persistent;
3216
+ this.creationTime = creationTime;
3196
3217
 
3197
3218
  // Useful to compare instead of instanceof with minified code
3198
3219
  this.type = 'Meeting';
@@ -3327,6 +3348,10 @@ class ChatMessage {
3327
3348
 
3328
3349
 
3329
3350
  static parseMany(plain ) {
3351
+ if (!plain || !plain.items) {
3352
+ return [];
3353
+ }
3354
+
3330
3355
  return plain.items.map(item => ChatMessage.parse(item));
3331
3356
  }
3332
3357
 
@@ -3436,6 +3461,9 @@ class Voicemail {
3436
3461
  }
3437
3462
 
3438
3463
  static parseMany(plain ) {
3464
+ if (!plain) {
3465
+ return [];
3466
+ }
3439
3467
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
3440
3468
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
3441
3469
 
@@ -3826,6 +3854,9 @@ class ChatRoom {
3826
3854
 
3827
3855
 
3828
3856
  static parseMany(plain ) {
3857
+ if (!plain || !plain.items) {
3858
+ return [];
3859
+ }
3829
3860
  return plain.items.map(item => ChatRoom.parse(item));
3830
3861
  }
3831
3862