@wazo/sdk 0.37.22 → 0.37.26

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 +37 -6
  3. package/esm/__tests__/web-rtc-client.test.js +78 -68
  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 +4 -1
  10. package/esm/api-client.js +37 -6
  11. package/esm/checker/Checker.js +78 -68
  12. package/esm/checker/checks/aor.js +37 -6
  13. package/esm/checker/checks/api.js +37 -6
  14. package/esm/checker/checks/index.js +78 -68
  15. package/esm/checker/checks/webrtc-transport.js +78 -68
  16. package/esm/checker/checks/webrtc.js +78 -68
  17. package/esm/domain/AdHocAPIConference.js +37 -6
  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 +4 -1
  23. package/esm/domain/Features.js +37 -6
  24. package/esm/domain/Meeting.js +15 -5
  25. package/esm/domain/Phone/CTIPhone.js +41 -6
  26. package/esm/domain/Phone/WebRTCPhone.js +41 -15
  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 +4 -1
  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 +122 -82
  35. package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
  36. package/esm/service/CallApi.js +37 -6
  37. package/esm/service/getApiClient.js +37 -6
  38. package/esm/simple/Auth.js +122 -82
  39. package/esm/simple/Configuration.js +122 -82
  40. package/esm/simple/Directory.js +37 -6
  41. package/esm/simple/Phone.js +122 -82
  42. package/esm/simple/index.js +122 -82
  43. package/esm/simple/room/LocalParticipant.js +122 -82
  44. package/esm/simple/room/Participant.js +122 -82
  45. package/esm/simple/room/RemoteParticipant.js +122 -82
  46. package/esm/simple/room/Room.js +122 -82
  47. package/esm/simple/room/SipRoom.js +122 -82
  48. package/esm/simple/room/Stream.js +122 -82
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +122 -82
  50. package/esm/simple/utils.js +122 -82
  51. package/esm/types/WebSocketMessage.js +1 -1
  52. package/esm/web-rtc-client.js +78 -68
  53. package/lib/__tests__/api-client.test.js +37 -6
  54. package/lib/__tests__/web-rtc-client.test.js +78 -68
  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 +4 -1
  61. package/lib/api-client.js +37 -6
  62. package/lib/checker/Checker.js +78 -68
  63. package/lib/checker/checks/aor.js +37 -6
  64. package/lib/checker/checks/api.js +37 -6
  65. package/lib/checker/checks/index.js +78 -68
  66. package/lib/checker/checks/webrtc-transport.js +78 -68
  67. package/lib/checker/checks/webrtc.js +78 -68
  68. package/lib/domain/AdHocAPIConference.js +37 -6
  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 +4 -1
  74. package/lib/domain/Features.js +37 -6
  75. package/lib/domain/Meeting.js +19 -5
  76. package/lib/domain/Phone/CTIPhone.js +41 -6
  77. package/lib/domain/Phone/WebRTCPhone.js +41 -15
  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 +4 -1
  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 +122 -82
  86. package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
  87. package/lib/service/CallApi.js +37 -6
  88. package/lib/service/getApiClient.js +37 -6
  89. package/lib/simple/Auth.js +122 -82
  90. package/lib/simple/Configuration.js +122 -82
  91. package/lib/simple/Directory.js +37 -6
  92. package/lib/simple/Phone.js +122 -82
  93. package/lib/simple/index.js +122 -82
  94. package/lib/simple/room/LocalParticipant.js +122 -82
  95. package/lib/simple/room/Participant.js +122 -82
  96. package/lib/simple/room/RemoteParticipant.js +122 -82
  97. package/lib/simple/room/Room.js +122 -82
  98. package/lib/simple/room/SipRoom.js +122 -82
  99. package/lib/simple/room/Stream.js +122 -82
  100. package/lib/simple/room/__tests__/RemoteParticipant.test.js +122 -82
  101. package/lib/simple/utils.js +122 -82
  102. package/lib/types/WebSocketMessage.js +2 -0
  103. package/lib/web-rtc-client.js +78 -68
  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 +4 -1
  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 +41 -15
  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 -24
@@ -863,6 +863,9 @@ class Contact {
863
863
  }
864
864
 
865
865
  static parseMany(response ) {
866
+ if (!response || !response.results) {
867
+ return [];
868
+ }
866
869
  return response.results.map(r => Contact.parse(r, response.column_types));
867
870
  }
868
871
 
@@ -1233,7 +1236,7 @@ class Contact {
1233
1236
  this[key] = old[key] || this[key];
1234
1237
  });
1235
1238
 
1236
- if (old.lineState && !this.lineState) {
1239
+ if (old.lineState) {
1237
1240
  this.lineState = old.lineState;
1238
1241
  }
1239
1242
 
@@ -2627,8 +2630,9 @@ class ExternalApp {
2627
2630
 
2628
2631
 
2629
2632
 
2630
-
2633
+
2631
2634
 
2635
+
2632
2636
 
2633
2637
 
2634
2638
  class Meeting {
@@ -2639,9 +2643,10 @@ class Meeting {
2639
2643
 
2640
2644
 
2641
2645
 
2642
-
2646
+
2643
2647
 
2644
2648
 
2649
+
2645
2650
 
2646
2651
  static parse(plain ) {
2647
2652
  return new Meeting({
@@ -2651,12 +2656,16 @@ class Meeting {
2651
2656
  ownerUuids: plain.owner_uuids,
2652
2657
  port: plain.port,
2653
2658
  uuid: plain.uuid,
2654
- number: plain.number,
2659
+ extension: plain.exten,
2655
2660
  persistent: plain.persistent,
2661
+ creationTime: moment(plain.creation_time).toDate(),
2656
2662
  });
2657
2663
  }
2658
2664
 
2659
2665
  static parseMany(items ) {
2666
+ if (!items) {
2667
+ return [];
2668
+ }
2660
2669
  return items.map(plain => Meeting.parse(plain));
2661
2670
  }
2662
2671
 
@@ -2671,8 +2680,9 @@ class Meeting {
2671
2680
  ownerUuids,
2672
2681
  port,
2673
2682
  uri,
2674
- number,
2683
+ extension,
2675
2684
  persistent,
2685
+ creationTime,
2676
2686
  } = {}) {
2677
2687
  this.guestSipAuthorization = guestSipAuthorization;
2678
2688
  this.uri = uri;
@@ -2680,8 +2690,9 @@ class Meeting {
2680
2690
  this.ownerUuids = ownerUuids;
2681
2691
  this.port = port;
2682
2692
  this.uuid = uuid;
2683
- this.number = number;
2693
+ this.extension = extension;
2684
2694
  this.persistent = persistent;
2695
+ this.creationTime = creationTime;
2685
2696
 
2686
2697
  // Useful to compare instead of instanceof with minified code
2687
2698
  this.type = 'Meeting';
@@ -2859,6 +2870,10 @@ class ChatMessage {
2859
2870
 
2860
2871
 
2861
2872
  static parseMany(plain ) {
2873
+ if (!plain || !plain.items) {
2874
+ return [];
2875
+ }
2876
+
2862
2877
  return plain.items.map(item => ChatMessage.parse(item));
2863
2878
  }
2864
2879
 
@@ -2968,6 +2983,9 @@ class Voicemail {
2968
2983
  }
2969
2984
 
2970
2985
  static parseMany(plain ) {
2986
+ if (!plain) {
2987
+ return [];
2988
+ }
2971
2989
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2972
2990
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2973
2991
 
@@ -3077,6 +3095,9 @@ class Call {
3077
3095
 
3078
3096
 
3079
3097
  static parseMany(plain ) {
3098
+ if (!plain) {
3099
+ return [];
3100
+ }
3080
3101
  return plain.map((plainCall ) => Call.parse(plainCall));
3081
3102
  }
3082
3103
 
@@ -3620,6 +3641,9 @@ class Recording {
3620
3641
 
3621
3642
 
3622
3643
  static parseMany(recordings = []) {
3644
+ if (!recordings) {
3645
+ return [];
3646
+ }
3623
3647
  return recordings.map(item => Recording.parse(item));
3624
3648
  }
3625
3649
 
@@ -3721,6 +3745,10 @@ class CallLog {
3721
3745
  }
3722
3746
 
3723
3747
  static parseMany(plain ) {
3748
+ if (!plain || !plain.items) {
3749
+ return [];
3750
+ }
3751
+
3724
3752
  return plain.items.map(item => CallLog.parse(item));
3725
3753
  }
3726
3754
 
@@ -4290,6 +4318,10 @@ class CTIPhone extends Emitter {
4290
4318
  return false;
4291
4319
  }
4292
4320
 
4321
+ hasAVideoTrack() {
4322
+ return false;
4323
+ }
4324
+
4293
4325
  getLocalStreamForCall() {
4294
4326
  return null;
4295
4327
  }
@@ -4683,6 +4715,9 @@ class ChatRoom {
4683
4715
 
4684
4716
 
4685
4717
  static parseMany(plain ) {
4718
+ if (!plain || !plain.items) {
4719
+ return [];
4720
+ }
4686
4721
  return plain.items.map(item => ChatRoom.parse(item));
4687
4722
  }
4688
4723
 
@@ -5664,10 +5699,6 @@ const getSrflxOrRelay = (candidates ) =>
5664
5699
  candidates
5665
5700
  .filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
5666
5701
 
5667
- const areCandidateValid = (candidates ) =>
5668
- getSrflxOrRelay(candidates)
5669
- .length > 0;
5670
-
5671
5702
  const getVideoDirection = (sdp ) => {
5672
5703
  const parsedSdp = sdpParser.parse(sdp);
5673
5704
  const videoMedia = parsedSdp.media.find(media => media.type === 'video');
@@ -5720,8 +5751,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
5720
5751
  /* global RTCSessionDescriptionInit, navigator */
5721
5752
 
5722
5753
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
5723
- const MAX_WAIT_FOR_ICE_TRIES = 20;
5724
- const WAIT_FOR_ICE_TIMEOUT = 500;
5725
5754
 
5726
5755
  // Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
5727
5756
  const wazoMediaStreamFactory = (constraints ) => {
@@ -5911,38 +5940,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5911
5940
  this._peerConnection = undefined;
5912
5941
  }
5913
5942
 
5914
- async _waitForValidGatheredIce() {
5915
- let tries = 0;
5916
-
5917
- while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
5918
- wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
5919
- tries,
5920
- max: MAX_WAIT_FOR_ICE_TRIES,
5921
- });
5922
-
5923
- tries++;
5924
-
5925
- // eslint-disable-next-line no-await-in-loop
5926
- await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
5927
- }
5928
-
5929
- if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
5930
- const errorMsg = 'No valid candidates found, can\'t answer the call';
5931
- const error = new Error(errorMsg);
5932
- wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
5933
-
5934
- // Emit an error, because sip.js catches the exception and switch to status Terminated.
5935
- this.eventEmitter.emit('error', error);
5936
-
5937
- wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5938
- }
5939
-
5940
- // eslint-disable-next-line
5941
- wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5942
-
5943
- return this.getLocalSessionDescription();
5944
- }
5945
-
5946
5943
  // Overridden to send `inactive` in conference
5947
5944
  updateDirection(options , isConference = false,
5948
5945
  audioOnly = false) {
@@ -6710,7 +6707,7 @@ class WebRTCClient extends Emitter {
6710
6707
  }
6711
6708
 
6712
6709
  call(number , enableVideo , audioOnly = false, conference = false) {
6713
- logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6710
+ logger$9.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6714
6711
  const inviterOptions = {
6715
6712
  sessionDescriptionHandlerOptionsReInvite: {
6716
6713
  conference,
@@ -7786,6 +7783,7 @@ class WebRTCClient extends Emitter {
7786
7783
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
7787
7784
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
7788
7785
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
7786
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
7789
7787
 
7790
7788
  logger$9.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
7791
7789
 
@@ -7793,7 +7791,8 @@ class WebRTCClient extends Emitter {
7793
7791
  constraints: {
7794
7792
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
7795
7793
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
7796
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
7794
+ video: screenSharing ? (isDesktop
7795
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
7797
7796
  : this._getVideoConstraints(enableVideo),
7798
7797
  screen: screenSharing,
7799
7798
  desktop: isDesktop,
@@ -8128,12 +8127,14 @@ class WebRTCClient extends Emitter {
8128
8127
 
8129
8128
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8130
8129
 
8131
- pc.oniceconnectionstatechange = () => {
8132
- logger$9.info('on ice connection state changed', { state: pc.iceConnectionState });
8133
- if (pc.iceConnectionState === 'disconnected') {
8134
- this.eventEmitter.emit(ON_DISCONNECTED$1);
8135
- }
8136
- };
8130
+ if (pc) {
8131
+ pc.oniceconnectionstatechange = () => {
8132
+ logger$9.info('on ice connection state changed', { state: pc.iceConnectionState });
8133
+ if (pc.iceConnectionState === 'disconnected') {
8134
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8135
+ }
8136
+ };
8137
+ }
8137
8138
 
8138
8139
  if (withEvent) {
8139
8140
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8343,13 +8344,17 @@ class WebRTCClient extends Emitter {
8343
8344
  const nbStats = this.sessionNetworkStats[sessionId].length;
8344
8345
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8345
8346
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8347
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8346
8348
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8347
8349
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8350
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8348
8351
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8349
8352
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8350
8353
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8351
- let audioBytesSent = 0;
8352
- let audioBytesReceived = 0;
8354
+ let audioBytesSent = 0; // content + header
8355
+ let audioBytesReceived = 0; // content + header
8356
+ let audioContentSent = 0; // useful to detect blank call
8357
+ let audioContentReceived = 0;
8353
8358
  let videoBytesSent = 0;
8354
8359
  let videoBytesReceived = 0;
8355
8360
  let transportSent = 0;
@@ -8358,25 +8363,27 @@ class WebRTCClient extends Emitter {
8358
8363
 
8359
8364
  stats.forEach(report => {
8360
8365
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8361
- audioBytesSent += report.bytesSent + report.headerBytesSent;
8366
+ audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8367
+ audioContentSent += Number(report.bytesSent);
8362
8368
  }
8363
8369
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8364
- audioBytesSent += report.bytesSent;
8370
+ audioBytesSent += Number(report.bytesSent);
8365
8371
  }
8366
8372
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8367
- videoBytesSent += report.bytesSent + report.headerBytesSent;
8373
+ videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8368
8374
  }
8369
8375
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
8370
- packetsLost += report.packetsLost;
8371
- networkStats.packetsReceived = report.packetsReceived;
8372
- audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
8376
+ packetsLost += Number(report.packetsLost);
8377
+ networkStats.packetsReceived = Number(report.packetsReceived);
8378
+ audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8379
+ audioContentReceived += Number(report.bytesReceived);
8373
8380
  }
8374
8381
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8375
- videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
8382
+ videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8376
8383
  }
8377
8384
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
8378
8385
  if ('framesPerSecond' in report) {
8379
- networkStats.framesPerSecond = report.framesPerSecond;
8386
+ networkStats.framesPerSecond = Number(report.framesPerSecond);
8380
8387
  }
8381
8388
  if ('framerateMean' in report) {
8382
8389
  // framerateMean is only available in FF
@@ -8384,24 +8391,31 @@ class WebRTCClient extends Emitter {
8384
8391
  }
8385
8392
  }
8386
8393
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
8387
- packetsLost += report.packetsLost;
8388
- networkStats.roundTripTime = report.roundTripTime;
8389
- networkStats.jitter = report.jitter;
8394
+ packetsLost += Number(report.packetsLost);
8395
+ networkStats.roundTripTime = Number(report.roundTripTime);
8396
+ networkStats.jitter = Number(report.jitter);
8390
8397
  }
8391
8398
  if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
8392
- packetsLost += report.packetsLost;
8399
+ packetsLost += Number(report.packetsLost);
8393
8400
  }
8394
8401
  if (report.type === 'transport') {
8395
- transportSent += report.bytesSent;
8396
- transportReceived += report.bytesReceived;
8402
+ transportSent += Number(report.bytesSent);
8403
+ transportReceived += Number(report.bytesReceived);
8397
8404
  }
8398
8405
  });
8399
8406
 
8400
8407
  networkStats.packetsLost = packetsLost;
8408
+
8401
8409
  networkStats.totalAudioBytesSent = audioBytesSent;
8402
8410
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8403
8411
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8404
8412
  networkStats.audioBytesReceived = audioBytesReceived;
8413
+
8414
+ networkStats.totalAudioContentSent = audioContentSent;
8415
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8416
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8417
+ networkStats.audioContentReceived = audioContentReceived;
8418
+
8405
8419
  networkStats.totalVideoBytesSent = videoBytesSent;
8406
8420
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8407
8421
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -8613,6 +8627,7 @@ class WebRTCPhone extends Emitter {
8613
8627
  constraints,
8614
8628
  audioOnly,
8615
8629
  conference,
8630
+ iceRestart,
8616
8631
  });
8617
8632
 
8618
8633
  if (!sipSession) {
@@ -8716,6 +8731,11 @@ class WebRTCPhone extends Emitter {
8716
8731
 
8717
8732
  this.client.downgradeToAudio(sipSession);
8718
8733
 
8734
+ if (callSession) {
8735
+ callSession.cameraEnabled = false;
8736
+ this._updateCallSession(callSession);
8737
+ }
8738
+
8719
8739
  if (withMessage) {
8720
8740
  this._sendReinviteMessage(callSession, false);
8721
8741
  }
@@ -8743,6 +8763,11 @@ class WebRTCPhone extends Emitter {
8743
8763
 
8744
8764
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
8745
8765
 
8766
+ if (callSession) {
8767
+ callSession.cameraEnabled = true;
8768
+ this._updateCallSession(callSession);
8769
+ }
8770
+
8746
8771
  // If no stream is returned, it means we have to reinvite
8747
8772
  if (!newStream) {
8748
8773
  return true;
@@ -8979,18 +9004,20 @@ class WebRTCPhone extends Emitter {
8979
9004
  screenTrack,
8980
9005
  });
8981
9006
 
8982
- screenTrack.onended = () => {
8983
- logger$8.info('WebRTC phone - on screenshare ended', {
8984
- hadVideo,
8985
- id: this.getSipSessionId(sipSession),
8986
- screenTrack,
8987
- });
9007
+ if (screenTrack) {
9008
+ screenTrack.onended = () => {
9009
+ logger$8.info('WebRTC phone - on screenshare ended', {
9010
+ hadVideo,
9011
+ id: this.getSipSessionId(sipSession),
9012
+ screenTrack,
9013
+ });
8988
9014
 
8989
- this.eventEmitter.emit(
8990
- ON_SHARE_SCREEN_ENDING,
8991
- this._createCallSession(sipSession, callSession),
8992
- );
8993
- };
9015
+ this.eventEmitter.emit(
9016
+ ON_SHARE_SCREEN_ENDING,
9017
+ this._createCallSession(sipSession, callSession),
9018
+ );
9019
+ };
9020
+ }
8994
9021
 
8995
9022
  this.currentScreenShare = {
8996
9023
  stream: screenStream,
@@ -9010,7 +9037,7 @@ class WebRTCPhone extends Emitter {
9010
9037
  }
9011
9038
 
9012
9039
  _onCallAccepted(sipSession , cameraEnabled ) {
9013
- logger$8.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9040
+ logger$8.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9014
9041
 
9015
9042
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9016
9043
  this.currentSipSession = sipSession;
@@ -9522,7 +9549,7 @@ class WebRTCPhone extends Emitter {
9522
9549
  // @TODO: line is not used here
9523
9550
  async makeCall(number , line , cameraEnabled ,
9524
9551
  audioOnly = false, conference = false) {
9525
- logger$8.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9552
+ logger$8.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
9526
9553
  if (!number) {
9527
9554
  return Promise.resolve(null);
9528
9555
  }
@@ -9883,9 +9910,13 @@ class WebRTCPhone extends Emitter {
9883
9910
  if (this.shouldSendReinvite && this.currentSipSession
9884
9911
  && this.currentSipSession.state === SessionState.Established) {
9885
9912
  this.shouldSendReinvite = false;
9913
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
9914
+ const isConference = pc ? pc.sfu : false;
9915
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
9916
+
9886
9917
  try {
9887
9918
  // Send reinvite with iceRestart
9888
- this.sendReinvite(this.currentCallSession, null, false, false, true);
9919
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
9889
9920
  } catch (e) {
9890
9921
  logger$8.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
9891
9922
  }
@@ -9969,6 +10000,15 @@ class WebRTCPhone extends Emitter {
9969
10000
  return this.client.getSipSessionId(sipSession);
9970
10001
  }
9971
10002
 
10003
+ _updateCallSession(callSession ) {
10004
+ const sipSession = this.findSipSession(callSession);
10005
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10006
+
10007
+ if (sipSessionId) {
10008
+ this.callSessions[sipSessionId] = callSession;
10009
+ }
10010
+ }
10011
+
9972
10012
  _onMessage(message ) {
9973
10013
  if (!message || message.method !== 'MESSAGE') {
9974
10014
  return;
@@ -1531,6 +1531,9 @@ class Contact {
1531
1531
  }
1532
1532
 
1533
1533
  static parseMany(response ) {
1534
+ if (!response || !response.results) {
1535
+ return [];
1536
+ }
1534
1537
  return response.results.map(r => Contact.parse(r, response.column_types));
1535
1538
  }
1536
1539
 
@@ -1901,7 +1904,7 @@ class Contact {
1901
1904
  this[key] = old[key] || this[key];
1902
1905
  });
1903
1906
 
1904
- if (old.lineState && !this.lineState) {
1907
+ if (old.lineState) {
1905
1908
  this.lineState = old.lineState;
1906
1909
  }
1907
1910
 
@@ -2608,8 +2611,9 @@ class ExternalApp {
2608
2611
 
2609
2612
 
2610
2613
 
2611
-
2614
+
2612
2615
 
2616
+
2613
2617
 
2614
2618
 
2615
2619
  class Meeting {
@@ -2620,9 +2624,10 @@ class Meeting {
2620
2624
 
2621
2625
 
2622
2626
 
2623
-
2627
+
2624
2628
 
2625
2629
 
2630
+
2626
2631
 
2627
2632
  static parse(plain ) {
2628
2633
  return new Meeting({
@@ -2632,12 +2637,16 @@ class Meeting {
2632
2637
  ownerUuids: plain.owner_uuids,
2633
2638
  port: plain.port,
2634
2639
  uuid: plain.uuid,
2635
- number: plain.number,
2640
+ extension: plain.exten,
2636
2641
  persistent: plain.persistent,
2642
+ creationTime: moment(plain.creation_time).toDate(),
2637
2643
  });
2638
2644
  }
2639
2645
 
2640
2646
  static parseMany(items ) {
2647
+ if (!items) {
2648
+ return [];
2649
+ }
2641
2650
  return items.map(plain => Meeting.parse(plain));
2642
2651
  }
2643
2652
 
@@ -2652,8 +2661,9 @@ class Meeting {
2652
2661
  ownerUuids,
2653
2662
  port,
2654
2663
  uri,
2655
- number,
2664
+ extension,
2656
2665
  persistent,
2666
+ creationTime,
2657
2667
  } = {}) {
2658
2668
  this.guestSipAuthorization = guestSipAuthorization;
2659
2669
  this.uri = uri;
@@ -2661,8 +2671,9 @@ class Meeting {
2661
2671
  this.ownerUuids = ownerUuids;
2662
2672
  this.port = port;
2663
2673
  this.uuid = uuid;
2664
- this.number = number;
2674
+ this.extension = extension;
2665
2675
  this.persistent = persistent;
2676
+ this.creationTime = creationTime;
2666
2677
 
2667
2678
  // Useful to compare instead of instanceof with minified code
2668
2679
  this.type = 'Meeting';
@@ -2840,6 +2851,10 @@ class ChatMessage {
2840
2851
 
2841
2852
 
2842
2853
  static parseMany(plain ) {
2854
+ if (!plain || !plain.items) {
2855
+ return [];
2856
+ }
2857
+
2843
2858
  return plain.items.map(item => ChatMessage.parse(item));
2844
2859
  }
2845
2860
 
@@ -2949,6 +2964,9 @@ class Voicemail {
2949
2964
  }
2950
2965
 
2951
2966
  static parseMany(plain ) {
2967
+ if (!plain) {
2968
+ return [];
2969
+ }
2952
2970
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2953
2971
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2954
2972
 
@@ -3058,6 +3076,9 @@ class Call {
3058
3076
 
3059
3077
 
3060
3078
  static parseMany(plain ) {
3079
+ if (!plain) {
3080
+ return [];
3081
+ }
3061
3082
  return plain.map((plainCall ) => Call.parse(plainCall));
3062
3083
  }
3063
3084
 
@@ -3230,6 +3251,9 @@ class Recording {
3230
3251
 
3231
3252
 
3232
3253
  static parseMany(recordings = []) {
3254
+ if (!recordings) {
3255
+ return [];
3256
+ }
3233
3257
  return recordings.map(item => Recording.parse(item));
3234
3258
  }
3235
3259
 
@@ -3331,6 +3355,10 @@ class CallLog {
3331
3355
  }
3332
3356
 
3333
3357
  static parseMany(plain ) {
3358
+ if (!plain || !plain.items) {
3359
+ return [];
3360
+ }
3361
+
3334
3362
  return plain.items.map(item => CallLog.parse(item));
3335
3363
  }
3336
3364
 
@@ -3888,6 +3916,9 @@ class ChatRoom {
3888
3916
 
3889
3917
 
3890
3918
  static parseMany(plain ) {
3919
+ if (!plain || !plain.items) {
3920
+ return [];
3921
+ }
3891
3922
  return plain.items.map(item => ChatRoom.parse(item));
3892
3923
  }
3893
3924