@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
@@ -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
  });
@@ -621,11 +642,16 @@ describe('Retrieving headers', () => {
621
642
  });
622
643
 
623
644
  describe('Calling fetch', () => {
624
- it('should call fetch without body but query string in get method', () => {
645
+ it('should call fetch without body but query string in get method', async () => {
625
646
  jest.mock('node-fetch/lib/index', () => {});
626
- global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve({}) }));
647
+ global.fetch = jest.fn(() => Promise.resolve({
648
+ json: () => Promise.resolve({}),
649
+ headers: {
650
+ get: () => '',
651
+ },
652
+ }));
627
653
 
628
- new ApiRequester({ server }).call(path, method, body, {});
654
+ await new ApiRequester({ server }).call(path, method, body, {});
629
655
  expect(global.fetch).toBeCalledWith(url, { method: 'get', body: null, headers: {}, agent: null });
630
656
  });
631
657
  });
@@ -313,7 +313,13 @@ class IssueReporter {
313
313
  }
314
314
 
315
315
  _isLevelAbove(level1 , level2 ) {
316
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
316
+ const index1 = LOG_LEVELS.indexOf(level1);
317
+ const index2 = LOG_LEVELS.indexOf(level2);
318
+ if (index1 === -1 || index2 === -1) {
319
+ return false;
320
+ }
321
+
322
+ return index1 > index2;
317
323
  }
318
324
 
319
325
  _makeCategory(category ) {
@@ -371,6 +377,7 @@ class ApiRequester {
371
377
 
372
378
 
373
379
 
380
+
374
381
 
375
382
 
376
383
 
@@ -410,6 +417,8 @@ class ApiRequester {
410
417
  this.token = token;
411
418
  }
412
419
 
420
+ this.shouldLogErrors = true;
421
+
413
422
  methods.forEach(method => {
414
423
  // $FlowFixMe
415
424
  ApiRequester.prototype[method] = function sugar(...args) {
@@ -433,6 +442,14 @@ class ApiRequester {
433
442
  this.fetchOptions = options;
434
443
  }
435
444
 
445
+ disableErrorLogging() {
446
+ this.shouldLogErrors = false;
447
+ }
448
+
449
+ enableErrorLogging() {
450
+ this.shouldLogErrors = true;
451
+ }
452
+
436
453
  async call(
437
454
  path ,
438
455
  method = 'get',
@@ -493,7 +510,9 @@ class ApiRequester {
493
510
  ? exceptionClass.fromText(err, response.status)
494
511
  : exceptionClass.fromResponse(err, response.status);
495
512
 
496
- logger.error('API error', error);
513
+ if (this.shouldLogErrors) {
514
+ logger.error('API error', error);
515
+ }
497
516
 
498
517
  throw error;
499
518
  });
@@ -501,7 +520,9 @@ class ApiRequester {
501
520
 
502
521
  return newParse(response, isJson);
503
522
  }).catch(error => {
504
- logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
523
+ if (this.shouldLogErrors) {
524
+ logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
525
+ }
505
526
 
506
527
  throw error;
507
528
  });
@@ -4,7 +4,6 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  require('webrtc-adapter');
6
6
  var userAgentState = require('sip.js/lib/api/user-agent-state');
7
- require('sip.js/lib/api/message');
8
7
  var parser = require('sip.js/lib/core/messages/parser');
9
8
  var constants = require('sip.js/lib/core/messages/methods/constants');
10
9
  var uri = require('sip.js/lib/grammar/uri');
@@ -147,6 +146,7 @@ class ApiRequester {
147
146
 
148
147
 
149
148
 
149
+
150
150
 
151
151
 
152
152
 
@@ -186,6 +186,8 @@ class ApiRequester {
186
186
  this.token = token;
187
187
  }
188
188
 
189
+ this.shouldLogErrors = true;
190
+
189
191
  methods.forEach(method => {
190
192
  // $FlowFixMe
191
193
  ApiRequester.prototype[method] = function sugar(...args) {
@@ -209,6 +211,14 @@ class ApiRequester {
209
211
  this.fetchOptions = options;
210
212
  }
211
213
 
214
+ disableErrorLogging() {
215
+ this.shouldLogErrors = false;
216
+ }
217
+
218
+ enableErrorLogging() {
219
+ this.shouldLogErrors = true;
220
+ }
221
+
212
222
  async call(
213
223
  path ,
214
224
  method = 'get',
@@ -269,7 +279,9 @@ class ApiRequester {
269
279
  ? exceptionClass.fromText(err, response.status)
270
280
  : exceptionClass.fromResponse(err, response.status);
271
281
 
272
- logger$2.error('API error', error);
282
+ if (this.shouldLogErrors) {
283
+ logger$2.error('API error', error);
284
+ }
273
285
 
274
286
  throw error;
275
287
  });
@@ -277,7 +289,9 @@ class ApiRequester {
277
289
 
278
290
  return newParse(response, isJson);
279
291
  }).catch(error => {
280
- logger$2.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
292
+ if (this.shouldLogErrors) {
293
+ logger$2.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
294
+ }
281
295
 
282
296
  throw error;
283
297
  });
@@ -588,7 +602,13 @@ class IssueReporter {
588
602
  }
589
603
 
590
604
  _isLevelAbove(level1 , level2 ) {
591
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
605
+ const index1 = LOG_LEVELS.indexOf(level1);
606
+ const index2 = LOG_LEVELS.indexOf(level2);
607
+ if (index1 === -1 || index2 === -1) {
608
+ return false;
609
+ }
610
+
611
+ return index1 > index2;
592
612
  }
593
613
 
594
614
  _makeCategory(category ) {
@@ -617,23 +637,6 @@ const areCandidateValid = (candidates ) =>
617
637
  getSrflxOrRelay(candidates)
618
638
  .length > 0;
619
639
 
620
- const toggleVideoDirection = (sdp , direction ) => {
621
- const parsedSdp = sdpParser__default['default'].parse(sdp);
622
- parsedSdp.media = parsedSdp.media.map(media => ({
623
- ...media,
624
- ...(media.type === 'video' ? { direction } : {}),
625
- }));
626
-
627
- return sdpParser__default['default'].write(parsedSdp);
628
- };
629
-
630
- const deactivateVideoModifier = (rawDescription ) => {
631
- const description = rawDescription;
632
- description.sdp = toggleVideoDirection(description.sdp, 'inactive');
633
-
634
- return Promise.resolve(description);
635
- };
636
-
637
640
  const hasAnActiveVideo = (sdp ) => {
638
641
  if (!sdp) {
639
642
  return false;
@@ -745,6 +748,7 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
745
748
  const iceRestart = options.offerOptions ? options.offerOptions.iceRestart : false;
746
749
 
747
750
  const isConference = options ? !!options.conference : false;
751
+ const audioOnly = options ? !!options.audioOnly : false;
748
752
 
749
753
  // We should wait for ice when iceRestart (reinvite) or for the first invite
750
754
  // We shouldn't wait for ice when holding or resuming the call
@@ -771,16 +775,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
771
775
  };
772
776
 
773
777
  return this.getLocalMediaStream(options)
774
- .then(() => this.updateDirection(options, isConference))
778
+ .then(() => this.updateDirection(options, isConference, audioOnly))
775
779
  .then(() => this.createDataChannel(options))
776
780
  .then(() => {
777
- if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options)) {
781
+ if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
778
782
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
779
783
  this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
780
784
  }
781
785
  })
782
786
  .then(() => this.createLocalOfferOrAnswer(options))
783
- .then((sessionDescription) => this.setLocalSessionDescription(sessionDescription))
787
+ .then(sessionDescription => this.setLocalSessionDescription(sessionDescription))
784
788
  .then(() => this.waitForIceGatheringComplete(iceRestart, iceTimeout))
785
789
  .then(() => this.getLocalSessionDescription())
786
790
  .then(description => {
@@ -903,7 +907,8 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
903
907
  }
904
908
 
905
909
  // Overridden to send `inactive` in conference
906
- updateDirection(options , isConference = false) {
910
+ updateDirection(options , isConference = false,
911
+ audioOnly = false) {
907
912
  if (this._peerConnection === undefined) {
908
913
  return Promise.reject(new Error('Peer connection closed.'));
909
914
  }
@@ -918,14 +923,17 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
918
923
  // if we are stable, assume we are creating a local offer
919
924
  this.logger.debug('SessionDescriptionHandler.updateDirection - setting offer direction');
920
925
  // determine the direction to offer given the current direction and hold state
921
- const directionToOffer = (currentDirection ) => {
926
+ const directionToOffer = (currentDirection , transceiver /* RTCRtpTransceiver */) => {
922
927
  if (isConference) {
928
+ if (audioOnly && transceiver.receiver.track && transceiver.receiver.track.kind === 'video') {
929
+ return 'sendonly';
930
+ }
923
931
  return options && options.hold ? 'sendonly' : 'sendrecv';
924
932
  }
925
933
 
926
934
  switch (currentDirection) {
927
935
  case 'inactive':
928
- return options && options.hold ? 'inactive' : 'recvonly';
936
+ return options && options.hold ? 'inactive' : (isConference && !audioOnly ? 'sendrecv' : 'recvonly');
929
937
  case 'recvonly':
930
938
  return options && options.hold ? 'inactive' : 'recvonly';
931
939
  case 'sendonly':
@@ -941,7 +949,7 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
941
949
  // set the transceiver direction to the offer direction
942
950
  this._peerConnection.getTransceivers().forEach((transceiver) => {
943
951
  if (transceiver.direction /* guarding, but should always be true */) {
944
- const offerDirection = directionToOffer(transceiver.direction);
952
+ const offerDirection = directionToOffer(transceiver.direction, transceiver);
945
953
  if (transceiver.direction !== offerDirection) {
946
954
  // eslint-disable-next-line no-param-reassign
947
955
  transceiver.direction = offerDirection;
@@ -1000,6 +1008,13 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
1000
1008
  // set the transceiver direction to the answer direction
1001
1009
  this._peerConnection.getTransceivers().forEach((transceiver) => {
1002
1010
  if (transceiver.direction /* guarding, but should always be true */) {
1011
+ const { receiver } = transceiver;
1012
+ if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
1013
+ // eslint-disable-next-line no-param-reassign
1014
+ transceiver.direction = 'inactive';
1015
+ return;
1016
+ }
1017
+
1003
1018
  if (transceiver.direction !== 'stopped' && transceiver.direction !== answerDirection) {
1004
1019
  // eslint-disable-next-line no-param-reassign
1005
1020
  transceiver.direction = answerDirection;
@@ -1038,8 +1053,8 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
1038
1053
  }
1039
1054
  const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
1040
1055
 
1041
- // Do not reuse sender tracks in SFU
1042
- if (sender && !sfu) {
1056
+ // Do not reuse sender video tracks in SFU
1057
+ if (sender && (!sfu || newTrack.kind === 'audio')) {
1043
1058
  trackUpdates.push(
1044
1059
  new Promise((resolve) => {
1045
1060
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -2105,7 +2120,7 @@ class Contact {
2105
2120
 
2106
2121
  return new Contact({
2107
2122
  sourceId: single.id || '',
2108
- name: single.displayName,
2123
+ name: single.displayName || '',
2109
2124
  number: numbers.length ? numbers[0].number : '',
2110
2125
  numbers,
2111
2126
  emails,
@@ -2136,7 +2151,7 @@ class Contact {
2136
2151
 
2137
2152
  return new Contact({
2138
2153
  sourceId: single.id || '',
2139
- name: single.name,
2154
+ name: single.name || '',
2140
2155
  number: numbers.length ? numbers[0].number : '',
2141
2156
  numbers,
2142
2157
  emails,
@@ -2237,7 +2252,7 @@ class Contact {
2237
2252
  } = {}) {
2238
2253
  this.id = id;
2239
2254
  this.uuid = uuid;
2240
- this.name = name;
2255
+ this.name = name || '';
2241
2256
  this.number = number;
2242
2257
  this.numbers = numbers;
2243
2258
  this.email = email;
@@ -3546,17 +3561,66 @@ var updateFrom = (instance , from ) => {
3546
3561
 
3547
3562
  //
3548
3563
 
3564
+
3565
+
3566
+
3567
+
3568
+
3569
+
3570
+
3571
+
3572
+
3573
+
3574
+
3575
+
3576
+
3577
+
3578
+
3579
+
3580
+ class Recording {
3581
+
3582
+
3583
+
3584
+
3585
+
3586
+
3587
+ static parseMany(recordings ) {
3588
+ return recordings.map(item => Recording.parse(item));
3589
+ }
3590
+
3591
+ static parse(plain ) {
3592
+ return new Recording({
3593
+ deleted: plain.deleted,
3594
+ fileName: plain.filename,
3595
+ end: plain.end_time ? moment__default['default'](plain.end_time).toDate() : null,
3596
+ start: moment__default['default'](plain.start_time).toDate(),
3597
+ uuid: plain.uuid,
3598
+ });
3599
+ }
3600
+
3601
+ constructor({ deleted, end, fileName, start, uuid } ) {
3602
+ this.deleted = deleted;
3603
+ this.end = end;
3604
+ this.fileName = fileName;
3605
+ this.start = start;
3606
+ this.uuid = uuid;
3607
+ }
3608
+ }
3609
+
3610
+ //
3611
+
3549
3612
 
3550
-
3613
+
3551
3614
 
3552
3615
 
3553
3616
 
3554
3617
 
3555
3618
 
3556
-
3619
+
3557
3620
 
3558
3621
 
3559
3622
 
3623
+
3560
3624
 
3561
3625
 
3562
3626
 
@@ -3569,7 +3633,7 @@ var updateFrom = (instance , from ) => {
3569
3633
 
3570
3634
 
3571
3635
 
3572
-
3636
+
3573
3637
 
3574
3638
 
3575
3639
 
@@ -3584,13 +3648,14 @@ var updateFrom = (instance , from ) => {
3584
3648
 
3585
3649
 
3586
3650
 
3587
-
3651
+
3652
+
3588
3653
 
3589
3654
 
3590
3655
  class CallLog {
3591
3656
 
3592
3657
 
3593
-
3658
+
3594
3659
 
3595
3660
 
3596
3661
 
@@ -3607,7 +3672,7 @@ class CallLog {
3607
3672
 
3608
3673
 
3609
3674
 
3610
-
3675
+
3611
3676
 
3612
3677
  static merge(current , toMerge ) {
3613
3678
  const onlyUnique = (value, index, self) => self.indexOf(value) === index;
@@ -3624,7 +3689,7 @@ class CallLog {
3624
3689
 
3625
3690
  static parse(plain ) {
3626
3691
  return new CallLog({
3627
- answer: moment__default['default'](plain.answer).toDate(),
3692
+ answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3628
3693
  answered: plain.answered,
3629
3694
  callDirection: plain.call_direction,
3630
3695
  destination: {
@@ -3638,13 +3703,14 @@ class CallLog {
3638
3703
  id: plain.id,
3639
3704
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3640
3705
  start: moment__default['default'](plain.start).toDate(),
3641
- end: moment__default['default'](plain.end).toDate(),
3706
+ end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3707
+ recordings: Recording.parseMany(plain.recordings),
3642
3708
  });
3643
3709
  }
3644
3710
 
3645
3711
  static parseNew(plain , session ) {
3646
3712
  return new CallLog({
3647
- answer: moment__default['default'](plain.answer).toDate(),
3713
+ answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3648
3714
  answered: plain.answered,
3649
3715
  callDirection: plain.call_direction,
3650
3716
  destination: {
@@ -3658,7 +3724,8 @@ class CallLog {
3658
3724
  id: plain.id,
3659
3725
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3660
3726
  start: moment__default['default'](plain.start).toDate(),
3661
- end: moment__default['default'](plain.end).toDate(),
3727
+ end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3728
+ recordings: Recording.parseMany(plain.recordings),
3662
3729
  // @TODO: FIXME add verification declined vs missed call
3663
3730
  newMissedCall: session
3664
3731
  && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
@@ -4894,6 +4961,10 @@ class ApiClient {
4894
4961
  this.fetchOptions = fetchOptions;
4895
4962
  this.client.setFetchOptions(fetchOptions);
4896
4963
  }
4964
+
4965
+ disableErrorLogging() {
4966
+ this.client.disableErrorLogging();
4967
+ }
4897
4968
  }
4898
4969
 
4899
4970
  //
@@ -5386,9 +5457,15 @@ class WebRTCClient extends Emitter {
5386
5457
 
5387
5458
  call(number , enableVideo , audioOnly = false, conference = false) {
5388
5459
  logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
5389
- const inviterOptions = {};
5460
+ const inviterOptions = {
5461
+ sessionDescriptionHandlerOptionsReInvite: {
5462
+ conference,
5463
+ audioOnly,
5464
+ },
5465
+ };
5466
+
5390
5467
  if (audioOnly) {
5391
- inviterOptions.sessionDescriptionHandlerModifiersReInvite = [deactivateVideoModifier];
5468
+ inviterOptions.sessionDescriptionHandlerModifiersReInvite = [modifiers.stripVideo];
5392
5469
  }
5393
5470
 
5394
5471
  const session = new inviter.Inviter(this.userAgent, this._makeURI(number), inviterOptions);
@@ -5417,10 +5494,11 @@ class WebRTCClient extends Emitter {
5417
5494
  sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
5418
5495
  };
5419
5496
 
5420
- inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
5497
+ inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
5421
5498
 
5499
+ inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
5422
5500
  if (audioOnly) {
5423
- inviteOptions.sessionDescriptionHandlerModifiers.push(deactivateVideoModifier);
5501
+ inviteOptions.sessionDescriptionHandlerModifiers.push(modifiers.stripVideo);
5424
5502
  }
5425
5503
 
5426
5504
  // Do not await invite here or we'll miss the Establishing state transition
@@ -5634,6 +5712,9 @@ class WebRTCClient extends Emitter {
5634
5712
  if (!this._isWeb()) {
5635
5713
  options.sessionDescriptionHandlerModifiers = [modifiers.holdModifier];
5636
5714
  }
5715
+ options.sessionDescriptionHandlerOptions = {
5716
+ constraints: options.constraints,
5717
+ };
5637
5718
 
5638
5719
  // Send re-INVITE
5639
5720
  return session.invite(options);
@@ -5673,6 +5754,9 @@ class WebRTCClient extends Emitter {
5673
5754
  // (eg: holdModifier)
5674
5755
  options.sessionDescriptionHandlerModifiers = [];
5675
5756
  }
5757
+ options.sessionDescriptionHandlerOptions = {
5758
+ constraints: options.constraints,
5759
+ };
5676
5760
 
5677
5761
  // Send re-INVITE
5678
5762
  return session.invite(options);
@@ -5902,7 +5986,8 @@ class WebRTCClient extends Emitter {
5902
5986
  ? this.video.deviceId.exact : undefined;
5903
5987
  }
5904
5988
 
5905
- reinvite(sipSession , newConstraints = null, conference = false) {
5989
+ reinvite(sipSession , newConstraints = null, conference = false,
5990
+ audioOnly = false) {
5906
5991
  if (!sipSession) {
5907
5992
  return false;
5908
5993
  }
@@ -5912,16 +5997,17 @@ class WebRTCClient extends Emitter {
5912
5997
  }
5913
5998
 
5914
5999
  const wasMuted = this.isAudioMuted(sipSession);
5915
- // When upgrading to video, remove the `deactivateVideoModifier` modifiers
6000
+ // When upgrading to video, remove the `stripVideo` modifiers
5916
6001
  if (newConstraints && newConstraints.video) {
5917
- const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
5918
- sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier =>
5919
- modifier !== deactivateVideoModifier);
6002
+ const modifiers$1 = sipSession.sessionDescriptionHandlerModifiersReInvite;
6003
+ sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers$1.filter(modifier =>
6004
+ modifier !== modifiers.stripVideo);
5920
6005
  }
5921
6006
 
5922
6007
  sipSession.sessionDescriptionHandlerOptionsReInvite = {
5923
6008
  ...sipSession.sessionDescriptionHandlerOptionsReInvite,
5924
6009
  conference,
6010
+ audioOnly,
5925
6011
  };
5926
6012
 
5927
6013
  const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
@@ -5961,6 +6047,8 @@ class WebRTCClient extends Emitter {
5961
6047
  },
5962
6048
  sessionDescriptionHandlerOptions: {
5963
6049
  constraints,
6050
+ conference,
6051
+ audioOnly,
5964
6052
  offerOptions: {
5965
6053
  iceRestart: false,
5966
6054
  },
@@ -6420,6 +6508,8 @@ class WebRTCClient extends Emitter {
6420
6508
 
6421
6509
  // Invitation and Inviter extends Session
6422
6510
  _setupSession(session ) {
6511
+ const sipSessionId = this.getSipSessionId(session);
6512
+
6423
6513
  // When receiving an Invitation, the delegate is not defined.
6424
6514
  if (!session.delegate) {
6425
6515
  session.delegate = {};
@@ -6443,8 +6533,18 @@ class WebRTCClient extends Emitter {
6443
6533
  };
6444
6534
  };
6445
6535
 
6536
+ const oldInviteRequest = session.onInviteRequest.bind(session);
6537
+ let hadRemoteVideo = false;
6538
+
6539
+ // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
6540
+ // Becase when `onInvite` is called we already got the video track
6541
+ session.onInviteRequest = (request) => {
6542
+ hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
6543
+
6544
+ oldInviteRequest(request);
6545
+ };
6546
+
6446
6547
  session.delegate.onInvite = (request ) => {
6447
- const sipSessionId = this.getSipSessionId(session);
6448
6548
  let updatedCalleeName = null;
6449
6549
  let updatedNumber = null;
6450
6550
  if (session.assertedIdentity) {
@@ -6454,7 +6554,6 @@ class WebRTCClient extends Emitter {
6454
6554
  logger.info('re-invite received', { updatedCalleeName, updatedNumber });
6455
6555
 
6456
6556
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
6457
- const hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
6458
6557
 
6459
6558
  // Update SDP
6460
6559
  // Remote video is handled by the `track` event. Here we're dealing with video stream removal.
@@ -6504,7 +6603,7 @@ class WebRTCClient extends Emitter {
6504
6603
  }
6505
6604
 
6506
6605
  _isAudioOnly(session ) {
6507
- return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === deactivateVideoModifier);
6606
+ return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === modifiers.stripVideo);
6508
6607
  }
6509
6608
 
6510
6609
  _setupMedias(session , newStream ) {
@@ -310,7 +310,13 @@ class IssueReporter {
310
310
  }
311
311
 
312
312
  _isLevelAbove(level1 , level2 ) {
313
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
313
+ const index1 = LOG_LEVELS.indexOf(level1);
314
+ const index2 = LOG_LEVELS.indexOf(level2);
315
+ if (index1 === -1 || index2 === -1) {
316
+ return false;
317
+ }
318
+
319
+ return index1 > index2;
314
320
  }
315
321
 
316
322
  _makeCategory(category ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "0.37.0-rc.5",
3
+ "version": "0.37.2",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "dist/wazo-sdk.js",
6
6
  "author": "Wazo (http://wazo.io)",
package/src/api-client.js CHANGED
@@ -157,4 +157,8 @@ export default class ApiClient {
157
157
  this.fetchOptions = fetchOptions;
158
158
  this.client.setFetchOptions(fetchOptions);
159
159
  }
160
+
161
+ disableErrorLogging() {
162
+ this.client.disableErrorLogging();
163
+ }
160
164
  }