@wazo/sdk 0.37.0-rc.5 → 0.37.2

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 (149) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +93 -16
  3. package/esm/__tests__/web-rtc-client.test.js +153 -54
  4. package/esm/api/agentd.js +24 -3
  5. package/esm/api/amid.js +7 -1
  6. package/esm/api/application.js +24 -3
  7. package/esm/api/auth.js +24 -3
  8. package/esm/api/call-logd.js +78 -20
  9. package/esm/api/calld.js +24 -20
  10. package/esm/api/chatd.js +24 -3
  11. package/esm/api/confd.js +24 -3
  12. package/esm/api/ctid-ng.js +24 -3
  13. package/esm/api/dird.js +27 -6
  14. package/esm/api/webhookd.js +7 -1
  15. package/esm/api-client.js +93 -16
  16. package/esm/checker/Checker.js +156 -54
  17. package/esm/checker/checks/aor.js +95 -16
  18. package/esm/checker/checks/api.js +94 -16
  19. package/esm/checker/checks/index.js +156 -54
  20. package/esm/checker/checks/wazo-websocket.js +7 -1
  21. package/esm/checker/checks/webrtc-transport.js +153 -54
  22. package/esm/checker/checks/webrtc.js +153 -54
  23. package/esm/domain/AdHocAPIConference.js +1717 -1640
  24. package/esm/domain/CallLog.js +71 -19
  25. package/esm/domain/CallSession.js +1 -18
  26. package/esm/domain/Contact.js +3 -3
  27. package/esm/domain/Features.js +93 -16
  28. package/esm/domain/IndirectTransfer.js +0 -17
  29. package/esm/domain/Phone/CTIPhone.js +100 -19
  30. package/esm/domain/Phone/Phone.js +0 -17
  31. package/esm/domain/Phone/WebRTCPhone.js +51 -36
  32. package/esm/domain/Recording.js +51 -0
  33. package/esm/domain/Room.js +0 -17
  34. package/esm/domain/SwitchboardCall.js +0 -17
  35. package/esm/domain/__tests__/CallLog.test.js +89 -19
  36. package/esm/domain/__tests__/CallSession.test.js +1 -18
  37. package/esm/domain/__tests__/Contact.test.js +3 -3
  38. package/esm/domain/__tests__/IndirectTransfer.test.js +1 -18
  39. package/esm/domain/__tests__/Room.test.js +1 -18
  40. package/esm/domain/__tests__/Session.test.js +7 -0
  41. package/esm/index.js +3436 -2911
  42. package/esm/lib/WazoSessionDescriptionHandler.js +28 -10
  43. package/esm/service/CallApi.js +93 -16
  44. package/esm/service/IssueReporter.js +7 -1
  45. package/esm/service/__tests__/IssueReporter.test.js +26 -2
  46. package/esm/service/getApiClient.js +93 -16
  47. package/esm/simple/Auth.js +619 -97
  48. package/esm/simple/Configuration.js +619 -97
  49. package/esm/simple/Directory.js +93 -16
  50. package/esm/simple/Phone.js +3261 -2739
  51. package/esm/simple/Websocket.js +7 -1
  52. package/esm/simple/index.js +619 -97
  53. package/esm/simple/room/LocalParticipant.js +619 -97
  54. package/esm/simple/room/Participant.js +619 -97
  55. package/esm/simple/room/RemoteParticipant.js +619 -97
  56. package/esm/simple/room/Room.js +619 -97
  57. package/esm/simple/room/Stream.js +619 -97
  58. package/esm/simple/room/__tests__/RemoteParticipant.test.js +619 -97
  59. package/esm/simple/utils.js +619 -97
  60. package/esm/utils/__tests__/api-requester.test.js +32 -6
  61. package/esm/utils/api-requester.js +24 -3
  62. package/esm/web-rtc-client.js +153 -54
  63. package/esm/websocket-client.js +7 -1
  64. package/lib/__tests__/api-client.test.js +93 -16
  65. package/lib/__tests__/web-rtc-client.test.js +154 -55
  66. package/lib/api/agentd.js +24 -3
  67. package/lib/api/amid.js +7 -1
  68. package/lib/api/application.js +24 -3
  69. package/lib/api/auth.js +24 -3
  70. package/lib/api/call-logd.js +78 -20
  71. package/lib/api/calld.js +24 -20
  72. package/lib/api/chatd.js +24 -3
  73. package/lib/api/confd.js +24 -3
  74. package/lib/api/ctid-ng.js +24 -3
  75. package/lib/api/dird.js +27 -6
  76. package/lib/api/webhookd.js +7 -1
  77. package/lib/api-client.js +93 -16
  78. package/lib/checker/Checker.js +157 -55
  79. package/lib/checker/checks/aor.js +95 -16
  80. package/lib/checker/checks/api.js +94 -16
  81. package/lib/checker/checks/index.js +157 -55
  82. package/lib/checker/checks/wazo-websocket.js +7 -1
  83. package/lib/checker/checks/webrtc-transport.js +154 -55
  84. package/lib/checker/checks/webrtc.js +154 -55
  85. package/lib/domain/AdHocAPIConference.js +1717 -1640
  86. package/lib/domain/CallLog.js +71 -19
  87. package/lib/domain/CallSession.js +1 -18
  88. package/lib/domain/Contact.js +3 -3
  89. package/lib/domain/Features.js +93 -16
  90. package/lib/domain/IndirectTransfer.js +0 -17
  91. package/lib/domain/Phone/CTIPhone.js +100 -19
  92. package/lib/domain/Phone/Phone.js +0 -16
  93. package/lib/domain/Phone/WebRTCPhone.js +51 -36
  94. package/lib/domain/Recording.js +57 -0
  95. package/lib/domain/Room.js +0 -17
  96. package/lib/domain/SwitchboardCall.js +0 -17
  97. package/lib/domain/__tests__/CallLog.test.js +89 -19
  98. package/lib/domain/__tests__/CallSession.test.js +1 -18
  99. package/lib/domain/__tests__/Contact.test.js +3 -3
  100. package/lib/domain/__tests__/IndirectTransfer.test.js +1 -18
  101. package/lib/domain/__tests__/Room.test.js +1 -18
  102. package/lib/domain/__tests__/Session.test.js +7 -0
  103. package/lib/index.js +3437 -2912
  104. package/lib/lib/WazoSessionDescriptionHandler.js +28 -10
  105. package/lib/service/CallApi.js +93 -16
  106. package/lib/service/IssueReporter.js +7 -1
  107. package/lib/service/__tests__/IssueReporter.test.js +26 -2
  108. package/lib/service/getApiClient.js +93 -16
  109. package/lib/simple/Auth.js +620 -98
  110. package/lib/simple/Configuration.js +620 -98
  111. package/lib/simple/Directory.js +93 -16
  112. package/lib/simple/Phone.js +3262 -2740
  113. package/lib/simple/Websocket.js +7 -1
  114. package/lib/simple/index.js +620 -98
  115. package/lib/simple/room/LocalParticipant.js +620 -98
  116. package/lib/simple/room/Participant.js +620 -98
  117. package/lib/simple/room/RemoteParticipant.js +620 -98
  118. package/lib/simple/room/Room.js +620 -98
  119. package/lib/simple/room/Stream.js +620 -98
  120. package/lib/simple/room/__tests__/RemoteParticipant.test.js +620 -98
  121. package/lib/simple/utils.js +620 -98
  122. package/lib/utils/__tests__/api-requester.test.js +32 -6
  123. package/lib/utils/api-requester.js +24 -3
  124. package/lib/web-rtc-client.js +154 -55
  125. package/lib/websocket-client.js +7 -1
  126. package/package.json +1 -1
  127. package/src/api-client.js +4 -0
  128. package/src/checker/checks/aor.js +2 -0
  129. package/src/checker/checks/api.js +1 -0
  130. package/src/domain/CallLog.js +18 -11
  131. package/src/domain/CallSession.js +1 -2
  132. package/src/domain/Contact.js +3 -3
  133. package/src/domain/Phone/CTIPhone.js +6 -2
  134. package/src/domain/Phone/Phone.js +2 -0
  135. package/src/domain/Phone/WebRTCPhone.js +26 -16
  136. package/src/domain/Recording.js +48 -0
  137. package/src/domain/__tests__/CallLog.test.js +19 -0
  138. package/src/domain/__tests__/Session.test.js +7 -0
  139. package/src/index.js +6 -0
  140. package/src/lib/WazoSessionDescriptionHandler.js +21 -9
  141. package/src/service/IssueReporter.js +7 -1
  142. package/src/service/__tests__/IssueReporter.test.js +20 -1
  143. package/src/simple/Phone.js +5 -1
  144. package/src/simple/index.js +6 -0
  145. package/src/simple/room/Room.js +18 -15
  146. package/src/simple/room/Stream.js +1 -4
  147. package/src/utils/__tests__/api-requester.test.js +9 -4
  148. package/src/utils/api-requester.js +17 -2
  149. package/src/web-rtc-client.js +40 -13
@@ -2,7 +2,6 @@
2
2
 
3
3
  require('webrtc-adapter');
4
4
  var userAgentState = require('sip.js/lib/api/user-agent-state');
5
- require('sip.js/lib/api/message');
6
5
  var parser = require('sip.js/lib/core/messages/parser');
7
6
  var constants = require('sip.js/lib/core/messages/methods/constants');
8
7
  var uri = require('sip.js/lib/grammar/uri');
@@ -145,6 +144,7 @@ class ApiRequester {
145
144
 
146
145
 
147
146
 
147
+
148
148
 
149
149
 
150
150
 
@@ -184,6 +184,8 @@ class ApiRequester {
184
184
  this.token = token;
185
185
  }
186
186
 
187
+ this.shouldLogErrors = true;
188
+
187
189
  methods.forEach(method => {
188
190
  // $FlowFixMe
189
191
  ApiRequester.prototype[method] = function sugar(...args) {
@@ -207,6 +209,14 @@ class ApiRequester {
207
209
  this.fetchOptions = options;
208
210
  }
209
211
 
212
+ disableErrorLogging() {
213
+ this.shouldLogErrors = false;
214
+ }
215
+
216
+ enableErrorLogging() {
217
+ this.shouldLogErrors = true;
218
+ }
219
+
210
220
  async call(
211
221
  path ,
212
222
  method = 'get',
@@ -267,7 +277,9 @@ class ApiRequester {
267
277
  ? exceptionClass.fromText(err, response.status)
268
278
  : exceptionClass.fromResponse(err, response.status);
269
279
 
270
- logger$2.error('API error', error);
280
+ if (this.shouldLogErrors) {
281
+ logger$2.error('API error', error);
282
+ }
271
283
 
272
284
  throw error;
273
285
  });
@@ -275,7 +287,9 @@ class ApiRequester {
275
287
 
276
288
  return newParse(response, isJson);
277
289
  }).catch(error => {
278
- logger$2.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
290
+ if (this.shouldLogErrors) {
291
+ logger$2.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
292
+ }
279
293
 
280
294
  throw error;
281
295
  });
@@ -586,7 +600,13 @@ class IssueReporter {
586
600
  }
587
601
 
588
602
  _isLevelAbove(level1 , level2 ) {
589
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
603
+ const index1 = LOG_LEVELS.indexOf(level1);
604
+ const index2 = LOG_LEVELS.indexOf(level2);
605
+ if (index1 === -1 || index2 === -1) {
606
+ return false;
607
+ }
608
+
609
+ return index1 > index2;
590
610
  }
591
611
 
592
612
  _makeCategory(category ) {
@@ -615,23 +635,6 @@ const areCandidateValid = (candidates ) =>
615
635
  getSrflxOrRelay(candidates)
616
636
  .length > 0;
617
637
 
618
- const toggleVideoDirection = (sdp , direction ) => {
619
- const parsedSdp = sdpParser__default['default'].parse(sdp);
620
- parsedSdp.media = parsedSdp.media.map(media => ({
621
- ...media,
622
- ...(media.type === 'video' ? { direction } : {}),
623
- }));
624
-
625
- return sdpParser__default['default'].write(parsedSdp);
626
- };
627
-
628
- const deactivateVideoModifier = (rawDescription ) => {
629
- const description = rawDescription;
630
- description.sdp = toggleVideoDirection(description.sdp, 'inactive');
631
-
632
- return Promise.resolve(description);
633
- };
634
-
635
638
  const hasAnActiveVideo = (sdp ) => {
636
639
  if (!sdp) {
637
640
  return false;
@@ -743,6 +746,7 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
743
746
  const iceRestart = options.offerOptions ? options.offerOptions.iceRestart : false;
744
747
 
745
748
  const isConference = options ? !!options.conference : false;
749
+ const audioOnly = options ? !!options.audioOnly : false;
746
750
 
747
751
  // We should wait for ice when iceRestart (reinvite) or for the first invite
748
752
  // We shouldn't wait for ice when holding or resuming the call
@@ -769,16 +773,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
769
773
  };
770
774
 
771
775
  return this.getLocalMediaStream(options)
772
- .then(() => this.updateDirection(options, isConference))
776
+ .then(() => this.updateDirection(options, isConference, audioOnly))
773
777
  .then(() => this.createDataChannel(options))
774
778
  .then(() => {
775
- if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options)) {
779
+ if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
776
780
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
777
781
  this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
778
782
  }
779
783
  })
780
784
  .then(() => this.createLocalOfferOrAnswer(options))
781
- .then((sessionDescription) => this.setLocalSessionDescription(sessionDescription))
785
+ .then(sessionDescription => this.setLocalSessionDescription(sessionDescription))
782
786
  .then(() => this.waitForIceGatheringComplete(iceRestart, iceTimeout))
783
787
  .then(() => this.getLocalSessionDescription())
784
788
  .then(description => {
@@ -901,7 +905,8 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
901
905
  }
902
906
 
903
907
  // Overridden to send `inactive` in conference
904
- updateDirection(options , isConference = false) {
908
+ updateDirection(options , isConference = false,
909
+ audioOnly = false) {
905
910
  if (this._peerConnection === undefined) {
906
911
  return Promise.reject(new Error('Peer connection closed.'));
907
912
  }
@@ -916,14 +921,17 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
916
921
  // if we are stable, assume we are creating a local offer
917
922
  this.logger.debug('SessionDescriptionHandler.updateDirection - setting offer direction');
918
923
  // determine the direction to offer given the current direction and hold state
919
- const directionToOffer = (currentDirection ) => {
924
+ const directionToOffer = (currentDirection , transceiver /* RTCRtpTransceiver */) => {
920
925
  if (isConference) {
926
+ if (audioOnly && transceiver.receiver.track && transceiver.receiver.track.kind === 'video') {
927
+ return 'sendonly';
928
+ }
921
929
  return options && options.hold ? 'sendonly' : 'sendrecv';
922
930
  }
923
931
 
924
932
  switch (currentDirection) {
925
933
  case 'inactive':
926
- return options && options.hold ? 'inactive' : 'recvonly';
934
+ return options && options.hold ? 'inactive' : (isConference && !audioOnly ? 'sendrecv' : 'recvonly');
927
935
  case 'recvonly':
928
936
  return options && options.hold ? 'inactive' : 'recvonly';
929
937
  case 'sendonly':
@@ -939,7 +947,7 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
939
947
  // set the transceiver direction to the offer direction
940
948
  this._peerConnection.getTransceivers().forEach((transceiver) => {
941
949
  if (transceiver.direction /* guarding, but should always be true */) {
942
- const offerDirection = directionToOffer(transceiver.direction);
950
+ const offerDirection = directionToOffer(transceiver.direction, transceiver);
943
951
  if (transceiver.direction !== offerDirection) {
944
952
  // eslint-disable-next-line no-param-reassign
945
953
  transceiver.direction = offerDirection;
@@ -998,6 +1006,13 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
998
1006
  // set the transceiver direction to the answer direction
999
1007
  this._peerConnection.getTransceivers().forEach((transceiver) => {
1000
1008
  if (transceiver.direction /* guarding, but should always be true */) {
1009
+ const { receiver } = transceiver;
1010
+ if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
1011
+ // eslint-disable-next-line no-param-reassign
1012
+ transceiver.direction = 'inactive';
1013
+ return;
1014
+ }
1015
+
1001
1016
  if (transceiver.direction !== 'stopped' && transceiver.direction !== answerDirection) {
1002
1017
  // eslint-disable-next-line no-param-reassign
1003
1018
  transceiver.direction = answerDirection;
@@ -1036,8 +1051,8 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
1036
1051
  }
1037
1052
  const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
1038
1053
 
1039
- // Do not reuse sender tracks in SFU
1040
- if (sender && !sfu) {
1054
+ // Do not reuse sender video tracks in SFU
1055
+ if (sender && (!sfu || newTrack.kind === 'audio')) {
1041
1056
  trackUpdates.push(
1042
1057
  new Promise((resolve) => {
1043
1058
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -2103,7 +2118,7 @@ class Contact {
2103
2118
 
2104
2119
  return new Contact({
2105
2120
  sourceId: single.id || '',
2106
- name: single.displayName,
2121
+ name: single.displayName || '',
2107
2122
  number: numbers.length ? numbers[0].number : '',
2108
2123
  numbers,
2109
2124
  emails,
@@ -2134,7 +2149,7 @@ class Contact {
2134
2149
 
2135
2150
  return new Contact({
2136
2151
  sourceId: single.id || '',
2137
- name: single.name,
2152
+ name: single.name || '',
2138
2153
  number: numbers.length ? numbers[0].number : '',
2139
2154
  numbers,
2140
2155
  emails,
@@ -2235,7 +2250,7 @@ class Contact {
2235
2250
  } = {}) {
2236
2251
  this.id = id;
2237
2252
  this.uuid = uuid;
2238
- this.name = name;
2253
+ this.name = name || '';
2239
2254
  this.number = number;
2240
2255
  this.numbers = numbers;
2241
2256
  this.email = email;
@@ -3544,17 +3559,66 @@ var updateFrom = (instance , from ) => {
3544
3559
 
3545
3560
  //
3546
3561
 
3562
+
3563
+
3564
+
3565
+
3566
+
3567
+
3568
+
3569
+
3570
+
3571
+
3572
+
3573
+
3574
+
3575
+
3576
+
3577
+
3578
+ class Recording {
3579
+
3580
+
3581
+
3582
+
3583
+
3584
+
3585
+ static parseMany(recordings ) {
3586
+ return recordings.map(item => Recording.parse(item));
3587
+ }
3588
+
3589
+ static parse(plain ) {
3590
+ return new Recording({
3591
+ deleted: plain.deleted,
3592
+ fileName: plain.filename,
3593
+ end: plain.end_time ? moment__default['default'](plain.end_time).toDate() : null,
3594
+ start: moment__default['default'](plain.start_time).toDate(),
3595
+ uuid: plain.uuid,
3596
+ });
3597
+ }
3598
+
3599
+ constructor({ deleted, end, fileName, start, uuid } ) {
3600
+ this.deleted = deleted;
3601
+ this.end = end;
3602
+ this.fileName = fileName;
3603
+ this.start = start;
3604
+ this.uuid = uuid;
3605
+ }
3606
+ }
3607
+
3608
+ //
3609
+
3547
3610
 
3548
-
3611
+
3549
3612
 
3550
3613
 
3551
3614
 
3552
3615
 
3553
3616
 
3554
-
3617
+
3555
3618
 
3556
3619
 
3557
3620
 
3621
+
3558
3622
 
3559
3623
 
3560
3624
 
@@ -3567,7 +3631,7 @@ var updateFrom = (instance , from ) => {
3567
3631
 
3568
3632
 
3569
3633
 
3570
-
3634
+
3571
3635
 
3572
3636
 
3573
3637
 
@@ -3582,13 +3646,14 @@ var updateFrom = (instance , from ) => {
3582
3646
 
3583
3647
 
3584
3648
 
3585
-
3649
+
3650
+
3586
3651
 
3587
3652
 
3588
3653
  class CallLog {
3589
3654
 
3590
3655
 
3591
-
3656
+
3592
3657
 
3593
3658
 
3594
3659
 
@@ -3605,7 +3670,7 @@ class CallLog {
3605
3670
 
3606
3671
 
3607
3672
 
3608
-
3673
+
3609
3674
 
3610
3675
  static merge(current , toMerge ) {
3611
3676
  const onlyUnique = (value, index, self) => self.indexOf(value) === index;
@@ -3622,7 +3687,7 @@ class CallLog {
3622
3687
 
3623
3688
  static parse(plain ) {
3624
3689
  return new CallLog({
3625
- answer: moment__default['default'](plain.answer).toDate(),
3690
+ answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3626
3691
  answered: plain.answered,
3627
3692
  callDirection: plain.call_direction,
3628
3693
  destination: {
@@ -3636,13 +3701,14 @@ class CallLog {
3636
3701
  id: plain.id,
3637
3702
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3638
3703
  start: moment__default['default'](plain.start).toDate(),
3639
- end: moment__default['default'](plain.end).toDate(),
3704
+ end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3705
+ recordings: Recording.parseMany(plain.recordings),
3640
3706
  });
3641
3707
  }
3642
3708
 
3643
3709
  static parseNew(plain , session ) {
3644
3710
  return new CallLog({
3645
- answer: moment__default['default'](plain.answer).toDate(),
3711
+ answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3646
3712
  answered: plain.answered,
3647
3713
  callDirection: plain.call_direction,
3648
3714
  destination: {
@@ -3656,7 +3722,8 @@ class CallLog {
3656
3722
  id: plain.id,
3657
3723
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3658
3724
  start: moment__default['default'](plain.start).toDate(),
3659
- end: moment__default['default'](plain.end).toDate(),
3725
+ end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3726
+ recordings: Recording.parseMany(plain.recordings),
3660
3727
  // @TODO: FIXME add verification declined vs missed call
3661
3728
  newMissedCall: session
3662
3729
  && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
@@ -4892,6 +4959,10 @@ class ApiClient {
4892
4959
  this.fetchOptions = fetchOptions;
4893
4960
  this.client.setFetchOptions(fetchOptions);
4894
4961
  }
4962
+
4963
+ disableErrorLogging() {
4964
+ this.client.disableErrorLogging();
4965
+ }
4895
4966
  }
4896
4967
 
4897
4968
  //
@@ -5381,9 +5452,15 @@ class WebRTCClient extends Emitter {
5381
5452
 
5382
5453
  call(number , enableVideo , audioOnly = false, conference = false) {
5383
5454
  logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
5384
- const inviterOptions = {};
5455
+ const inviterOptions = {
5456
+ sessionDescriptionHandlerOptionsReInvite: {
5457
+ conference,
5458
+ audioOnly,
5459
+ },
5460
+ };
5461
+
5385
5462
  if (audioOnly) {
5386
- inviterOptions.sessionDescriptionHandlerModifiersReInvite = [deactivateVideoModifier];
5463
+ inviterOptions.sessionDescriptionHandlerModifiersReInvite = [modifiers.stripVideo];
5387
5464
  }
5388
5465
 
5389
5466
  const session = new inviter.Inviter(this.userAgent, this._makeURI(number), inviterOptions);
@@ -5412,10 +5489,11 @@ class WebRTCClient extends Emitter {
5412
5489
  sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
5413
5490
  };
5414
5491
 
5415
- inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
5492
+ inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
5416
5493
 
5494
+ inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
5417
5495
  if (audioOnly) {
5418
- inviteOptions.sessionDescriptionHandlerModifiers.push(deactivateVideoModifier);
5496
+ inviteOptions.sessionDescriptionHandlerModifiers.push(modifiers.stripVideo);
5419
5497
  }
5420
5498
 
5421
5499
  // Do not await invite here or we'll miss the Establishing state transition
@@ -5629,6 +5707,9 @@ class WebRTCClient extends Emitter {
5629
5707
  if (!this._isWeb()) {
5630
5708
  options.sessionDescriptionHandlerModifiers = [modifiers.holdModifier];
5631
5709
  }
5710
+ options.sessionDescriptionHandlerOptions = {
5711
+ constraints: options.constraints,
5712
+ };
5632
5713
 
5633
5714
  // Send re-INVITE
5634
5715
  return session.invite(options);
@@ -5668,6 +5749,9 @@ class WebRTCClient extends Emitter {
5668
5749
  // (eg: holdModifier)
5669
5750
  options.sessionDescriptionHandlerModifiers = [];
5670
5751
  }
5752
+ options.sessionDescriptionHandlerOptions = {
5753
+ constraints: options.constraints,
5754
+ };
5671
5755
 
5672
5756
  // Send re-INVITE
5673
5757
  return session.invite(options);
@@ -5897,7 +5981,8 @@ class WebRTCClient extends Emitter {
5897
5981
  ? this.video.deviceId.exact : undefined;
5898
5982
  }
5899
5983
 
5900
- reinvite(sipSession , newConstraints = null, conference = false) {
5984
+ reinvite(sipSession , newConstraints = null, conference = false,
5985
+ audioOnly = false) {
5901
5986
  if (!sipSession) {
5902
5987
  return false;
5903
5988
  }
@@ -5907,16 +5992,17 @@ class WebRTCClient extends Emitter {
5907
5992
  }
5908
5993
 
5909
5994
  const wasMuted = this.isAudioMuted(sipSession);
5910
- // When upgrading to video, remove the `deactivateVideoModifier` modifiers
5995
+ // When upgrading to video, remove the `stripVideo` modifiers
5911
5996
  if (newConstraints && newConstraints.video) {
5912
- const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
5913
- sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier =>
5914
- modifier !== deactivateVideoModifier);
5997
+ const modifiers$1 = sipSession.sessionDescriptionHandlerModifiersReInvite;
5998
+ sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers$1.filter(modifier =>
5999
+ modifier !== modifiers.stripVideo);
5915
6000
  }
5916
6001
 
5917
6002
  sipSession.sessionDescriptionHandlerOptionsReInvite = {
5918
6003
  ...sipSession.sessionDescriptionHandlerOptionsReInvite,
5919
6004
  conference,
6005
+ audioOnly,
5920
6006
  };
5921
6007
 
5922
6008
  const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
@@ -5956,6 +6042,8 @@ class WebRTCClient extends Emitter {
5956
6042
  },
5957
6043
  sessionDescriptionHandlerOptions: {
5958
6044
  constraints,
6045
+ conference,
6046
+ audioOnly,
5959
6047
  offerOptions: {
5960
6048
  iceRestart: false,
5961
6049
  },
@@ -6415,6 +6503,8 @@ class WebRTCClient extends Emitter {
6415
6503
 
6416
6504
  // Invitation and Inviter extends Session
6417
6505
  _setupSession(session ) {
6506
+ const sipSessionId = this.getSipSessionId(session);
6507
+
6418
6508
  // When receiving an Invitation, the delegate is not defined.
6419
6509
  if (!session.delegate) {
6420
6510
  session.delegate = {};
@@ -6438,8 +6528,18 @@ class WebRTCClient extends Emitter {
6438
6528
  };
6439
6529
  };
6440
6530
 
6531
+ const oldInviteRequest = session.onInviteRequest.bind(session);
6532
+ let hadRemoteVideo = false;
6533
+
6534
+ // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
6535
+ // Becase when `onInvite` is called we already got the video track
6536
+ session.onInviteRequest = (request) => {
6537
+ hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
6538
+
6539
+ oldInviteRequest(request);
6540
+ };
6541
+
6441
6542
  session.delegate.onInvite = (request ) => {
6442
- const sipSessionId = this.getSipSessionId(session);
6443
6543
  let updatedCalleeName = null;
6444
6544
  let updatedNumber = null;
6445
6545
  if (session.assertedIdentity) {
@@ -6449,7 +6549,6 @@ class WebRTCClient extends Emitter {
6449
6549
  logger.info('re-invite received', { updatedCalleeName, updatedNumber });
6450
6550
 
6451
6551
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
6452
- const hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
6453
6552
 
6454
6553
  // Update SDP
6455
6554
  // Remote video is handled by the `track` event. Here we're dealing with video stream removal.
@@ -6499,7 +6598,7 @@ class WebRTCClient extends Emitter {
6499
6598
  }
6500
6599
 
6501
6600
  _isAudioOnly(session ) {
6502
- return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === deactivateVideoModifier);
6601
+ return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === modifiers.stripVideo);
6503
6602
  }
6504
6603
 
6505
6604
  _setupMedias(session , newStream ) {
package/lib/api/agentd.js CHANGED
@@ -311,7 +311,13 @@ class IssueReporter {
311
311
  }
312
312
 
313
313
  _isLevelAbove(level1 , level2 ) {
314
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
314
+ const index1 = LOG_LEVELS.indexOf(level1);
315
+ const index2 = LOG_LEVELS.indexOf(level2);
316
+ if (index1 === -1 || index2 === -1) {
317
+ return false;
318
+ }
319
+
320
+ return index1 > index2;
315
321
  }
316
322
 
317
323
  _makeCategory(category ) {
@@ -369,6 +375,7 @@ class ApiRequester {
369
375
 
370
376
 
371
377
 
378
+
372
379
 
373
380
 
374
381
 
@@ -408,6 +415,8 @@ class ApiRequester {
408
415
  this.token = token;
409
416
  }
410
417
 
418
+ this.shouldLogErrors = true;
419
+
411
420
  methods.forEach(method => {
412
421
  // $FlowFixMe
413
422
  ApiRequester.prototype[method] = function sugar(...args) {
@@ -431,6 +440,14 @@ class ApiRequester {
431
440
  this.fetchOptions = options;
432
441
  }
433
442
 
443
+ disableErrorLogging() {
444
+ this.shouldLogErrors = false;
445
+ }
446
+
447
+ enableErrorLogging() {
448
+ this.shouldLogErrors = true;
449
+ }
450
+
434
451
  async call(
435
452
  path ,
436
453
  method = 'get',
@@ -491,7 +508,9 @@ class ApiRequester {
491
508
  ? exceptionClass.fromText(err, response.status)
492
509
  : exceptionClass.fromResponse(err, response.status);
493
510
 
494
- logger.error('API error', error);
511
+ if (this.shouldLogErrors) {
512
+ logger.error('API error', error);
513
+ }
495
514
 
496
515
  throw error;
497
516
  });
@@ -499,7 +518,9 @@ class ApiRequester {
499
518
 
500
519
  return newParse(response, isJson);
501
520
  }).catch(error => {
502
- logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
521
+ if (this.shouldLogErrors) {
522
+ logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
523
+ }
503
524
 
504
525
  throw error;
505
526
  });
package/lib/api/amid.js CHANGED
@@ -250,7 +250,13 @@ class IssueReporter {
250
250
  }
251
251
 
252
252
  _isLevelAbove(level1 , level2 ) {
253
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
253
+ const index1 = LOG_LEVELS.indexOf(level1);
254
+ const index2 = LOG_LEVELS.indexOf(level2);
255
+ if (index1 === -1 || index2 === -1) {
256
+ return false;
257
+ }
258
+
259
+ return index1 > index2;
254
260
  }
255
261
 
256
262
  _makeCategory(category ) {
@@ -311,7 +311,13 @@ class IssueReporter {
311
311
  }
312
312
 
313
313
  _isLevelAbove(level1 , level2 ) {
314
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
314
+ const index1 = LOG_LEVELS.indexOf(level1);
315
+ const index2 = LOG_LEVELS.indexOf(level2);
316
+ if (index1 === -1 || index2 === -1) {
317
+ return false;
318
+ }
319
+
320
+ return index1 > index2;
315
321
  }
316
322
 
317
323
  _makeCategory(category ) {
@@ -369,6 +375,7 @@ class ApiRequester {
369
375
 
370
376
 
371
377
 
378
+
372
379
 
373
380
 
374
381
 
@@ -408,6 +415,8 @@ class ApiRequester {
408
415
  this.token = token;
409
416
  }
410
417
 
418
+ this.shouldLogErrors = true;
419
+
411
420
  methods.forEach(method => {
412
421
  // $FlowFixMe
413
422
  ApiRequester.prototype[method] = function sugar(...args) {
@@ -431,6 +440,14 @@ class ApiRequester {
431
440
  this.fetchOptions = options;
432
441
  }
433
442
 
443
+ disableErrorLogging() {
444
+ this.shouldLogErrors = false;
445
+ }
446
+
447
+ enableErrorLogging() {
448
+ this.shouldLogErrors = true;
449
+ }
450
+
434
451
  async call(
435
452
  path ,
436
453
  method = 'get',
@@ -491,7 +508,9 @@ class ApiRequester {
491
508
  ? exceptionClass.fromText(err, response.status)
492
509
  : exceptionClass.fromResponse(err, response.status);
493
510
 
494
- logger.error('API error', error);
511
+ if (this.shouldLogErrors) {
512
+ logger.error('API error', error);
513
+ }
495
514
 
496
515
  throw error;
497
516
  });
@@ -499,7 +518,9 @@ class ApiRequester {
499
518
 
500
519
  return newParse(response, isJson);
501
520
  }).catch(error => {
502
- logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
521
+ if (this.shouldLogErrors) {
522
+ logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
523
+ }
503
524
 
504
525
  throw error;
505
526
  });