@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
@@ -7,12 +7,11 @@ import { jsonToGraphQLQuery } from 'json-to-graphql-query/lib/jsonToGraphQLQuery
7
7
  import ReconnectingWebSocket from 'reconnecting-websocket';
8
8
  import 'webrtc-adapter';
9
9
  import { UserAgentState } from 'sip.js/lib/api/user-agent-state';
10
- import 'sip.js/lib/api/message';
11
10
  import { Parser } from 'sip.js/lib/core/messages/parser';
12
11
  import { C } from 'sip.js/lib/core/messages/methods/constants';
13
12
  import { URI } from 'sip.js/lib/grammar/uri';
14
13
  import { UserAgent } from 'sip.js/lib/api/user-agent';
15
- import { holdModifier } from 'sip.js/lib/platform/web/modifiers/modifiers';
14
+ import { stripVideo, holdModifier } from 'sip.js/lib/platform/web/modifiers/modifiers';
16
15
  import { Registerer } from 'sip.js/lib/api/registerer';
17
16
  import { Inviter } from 'sip.js/lib/api/inviter';
18
17
  import { Messager } from 'sip.js/lib/api/messager';
@@ -328,7 +327,13 @@ class IssueReporter {
328
327
  }
329
328
 
330
329
  _isLevelAbove(level1 , level2 ) {
331
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
330
+ const index1 = LOG_LEVELS.indexOf(level1);
331
+ const index2 = LOG_LEVELS.indexOf(level2);
332
+ if (index1 === -1 || index2 === -1) {
333
+ return false;
334
+ }
335
+
336
+ return index1 > index2;
332
337
  }
333
338
 
334
339
  _makeCategory(category ) {
@@ -386,6 +391,7 @@ class ApiRequester {
386
391
 
387
392
 
388
393
 
394
+
389
395
 
390
396
 
391
397
 
@@ -425,6 +431,8 @@ class ApiRequester {
425
431
  this.token = token;
426
432
  }
427
433
 
434
+ this.shouldLogErrors = true;
435
+
428
436
  methods.forEach(method => {
429
437
  // $FlowFixMe
430
438
  ApiRequester.prototype[method] = function sugar(...args) {
@@ -448,6 +456,14 @@ class ApiRequester {
448
456
  this.fetchOptions = options;
449
457
  }
450
458
 
459
+ disableErrorLogging() {
460
+ this.shouldLogErrors = false;
461
+ }
462
+
463
+ enableErrorLogging() {
464
+ this.shouldLogErrors = true;
465
+ }
466
+
451
467
  async call(
452
468
  path ,
453
469
  method = 'get',
@@ -508,7 +524,9 @@ class ApiRequester {
508
524
  ? exceptionClass.fromText(err, response.status)
509
525
  : exceptionClass.fromResponse(err, response.status);
510
526
 
511
- logger$4.error('API error', error);
527
+ if (this.shouldLogErrors) {
528
+ logger$4.error('API error', error);
529
+ }
512
530
 
513
531
  throw error;
514
532
  });
@@ -516,7 +534,9 @@ class ApiRequester {
516
534
 
517
535
  return newParse(response, isJson);
518
536
  }).catch(error => {
519
- logger$4.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
537
+ if (this.shouldLogErrors) {
538
+ logger$4.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
539
+ }
520
540
 
521
541
  throw error;
522
542
  });
@@ -1566,7 +1586,7 @@ class Contact {
1566
1586
 
1567
1587
  return new Contact({
1568
1588
  sourceId: single.id || '',
1569
- name: single.displayName,
1589
+ name: single.displayName || '',
1570
1590
  number: numbers.length ? numbers[0].number : '',
1571
1591
  numbers,
1572
1592
  emails,
@@ -1597,7 +1617,7 @@ class Contact {
1597
1617
 
1598
1618
  return new Contact({
1599
1619
  sourceId: single.id || '',
1600
- name: single.name,
1620
+ name: single.name || '',
1601
1621
  number: numbers.length ? numbers[0].number : '',
1602
1622
  numbers,
1603
1623
  emails,
@@ -1698,7 +1718,7 @@ class Contact {
1698
1718
  } = {}) {
1699
1719
  this.id = id;
1700
1720
  this.uuid = uuid;
1701
- this.name = name;
1721
+ this.name = name || '';
1702
1722
  this.number = number;
1703
1723
  this.numbers = numbers;
1704
1724
  this.email = email;
@@ -3033,17 +3053,66 @@ class Emitter {
3033
3053
 
3034
3054
  //
3035
3055
 
3056
+
3057
+
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+ class Recording {
3073
+
3074
+
3075
+
3076
+
3077
+
3078
+
3079
+ static parseMany(recordings ) {
3080
+ return recordings.map(item => Recording.parse(item));
3081
+ }
3082
+
3083
+ static parse(plain ) {
3084
+ return new Recording({
3085
+ deleted: plain.deleted,
3086
+ fileName: plain.filename,
3087
+ end: plain.end_time ? moment(plain.end_time).toDate() : null,
3088
+ start: moment(plain.start_time).toDate(),
3089
+ uuid: plain.uuid,
3090
+ });
3091
+ }
3092
+
3093
+ constructor({ deleted, end, fileName, start, uuid } ) {
3094
+ this.deleted = deleted;
3095
+ this.end = end;
3096
+ this.fileName = fileName;
3097
+ this.start = start;
3098
+ this.uuid = uuid;
3099
+ }
3100
+ }
3101
+
3102
+ //
3103
+
3036
3104
 
3037
-
3105
+
3038
3106
 
3039
3107
 
3040
3108
 
3041
3109
 
3042
3110
 
3043
-
3111
+
3044
3112
 
3045
3113
 
3046
3114
 
3115
+
3047
3116
 
3048
3117
 
3049
3118
 
@@ -3056,7 +3125,7 @@ class Emitter {
3056
3125
 
3057
3126
 
3058
3127
 
3059
-
3128
+
3060
3129
 
3061
3130
 
3062
3131
 
@@ -3071,13 +3140,14 @@ class Emitter {
3071
3140
 
3072
3141
 
3073
3142
 
3074
-
3143
+
3144
+
3075
3145
 
3076
3146
 
3077
3147
  class CallLog {
3078
3148
 
3079
3149
 
3080
-
3150
+
3081
3151
 
3082
3152
 
3083
3153
 
@@ -3094,7 +3164,7 @@ class CallLog {
3094
3164
 
3095
3165
 
3096
3166
 
3097
-
3167
+
3098
3168
 
3099
3169
  static merge(current , toMerge ) {
3100
3170
  const onlyUnique = (value, index, self) => self.indexOf(value) === index;
@@ -3111,7 +3181,7 @@ class CallLog {
3111
3181
 
3112
3182
  static parse(plain ) {
3113
3183
  return new CallLog({
3114
- answer: moment(plain.answer).toDate(),
3184
+ answer: plain.answer ? moment(plain.answer).toDate() : null,
3115
3185
  answered: plain.answered,
3116
3186
  callDirection: plain.call_direction,
3117
3187
  destination: {
@@ -3125,13 +3195,14 @@ class CallLog {
3125
3195
  id: plain.id,
3126
3196
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3127
3197
  start: moment(plain.start).toDate(),
3128
- end: moment(plain.end).toDate(),
3198
+ end: plain.end ? moment(plain.end).toDate() : null,
3199
+ recordings: Recording.parseMany(plain.recordings),
3129
3200
  });
3130
3201
  }
3131
3202
 
3132
3203
  static parseNew(plain , session ) {
3133
3204
  return new CallLog({
3134
- answer: moment(plain.answer).toDate(),
3205
+ answer: plain.answer ? moment(plain.answer).toDate() : null,
3135
3206
  answered: plain.answered,
3136
3207
  callDirection: plain.call_direction,
3137
3208
  destination: {
@@ -3145,7 +3216,8 @@ class CallLog {
3145
3216
  id: plain.id,
3146
3217
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3147
3218
  start: moment(plain.start).toDate(),
3148
- end: moment(plain.end).toDate(),
3219
+ end: plain.end ? moment(plain.end).toDate() : null,
3220
+ recordings: Recording.parseMany(plain.recordings),
3149
3221
  // @TODO: FIXME add verification declined vs missed call
3150
3222
  newMissedCall: session
3151
3223
  && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
@@ -4381,6 +4453,10 @@ class ApiClient {
4381
4453
  this.fetchOptions = fetchOptions;
4382
4454
  this.client.setFetchOptions(fetchOptions);
4383
4455
  }
4456
+
4457
+ disableErrorLogging() {
4458
+ this.client.disableErrorLogging();
4459
+ }
4384
4460
  }
4385
4461
 
4386
4462
  var api = {
@@ -4388,6 +4464,7 @@ var api = {
4388
4464
  check: async (server, session) => {
4389
4465
  const client = new ApiClient({ server });
4390
4466
  client.setToken(session.token);
4467
+ client.disableErrorLogging();
4391
4468
 
4392
4469
  const handleApiError = (apiName, error) => {
4393
4470
  const statusText = error instanceof ServerError ? 'server error' : 'api error';
@@ -4462,6 +4539,8 @@ var aor = {
4462
4539
  check: async (server, session) => {
4463
4540
  const apiClient = new ApiClient({ server });
4464
4541
  apiClient.setToken(session.token);
4542
+ apiClient.disableErrorLogging();
4543
+
4465
4544
  const line = session.primaryWebRtcLine();
4466
4545
  if (!line) {
4467
4546
  return 'No WebRTC line for this user';
@@ -5072,23 +5151,6 @@ const areCandidateValid = (candidates ) =>
5072
5151
  getSrflxOrRelay(candidates)
5073
5152
  .length > 0;
5074
5153
 
5075
- const toggleVideoDirection = (sdp , direction ) => {
5076
- const parsedSdp = sdpParser.parse(sdp);
5077
- parsedSdp.media = parsedSdp.media.map(media => ({
5078
- ...media,
5079
- ...(media.type === 'video' ? { direction } : {}),
5080
- }));
5081
-
5082
- return sdpParser.write(parsedSdp);
5083
- };
5084
-
5085
- const deactivateVideoModifier = (rawDescription ) => {
5086
- const description = rawDescription;
5087
- description.sdp = toggleVideoDirection(description.sdp, 'inactive');
5088
-
5089
- return Promise.resolve(description);
5090
- };
5091
-
5092
5154
  const hasAnActiveVideo = (sdp ) => {
5093
5155
  if (!sdp) {
5094
5156
  return false;
@@ -5200,6 +5262,7 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5200
5262
  const iceRestart = options.offerOptions ? options.offerOptions.iceRestart : false;
5201
5263
 
5202
5264
  const isConference = options ? !!options.conference : false;
5265
+ const audioOnly = options ? !!options.audioOnly : false;
5203
5266
 
5204
5267
  // We should wait for ice when iceRestart (reinvite) or for the first invite
5205
5268
  // We shouldn't wait for ice when holding or resuming the call
@@ -5226,16 +5289,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5226
5289
  };
5227
5290
 
5228
5291
  return this.getLocalMediaStream(options)
5229
- .then(() => this.updateDirection(options, isConference))
5292
+ .then(() => this.updateDirection(options, isConference, audioOnly))
5230
5293
  .then(() => this.createDataChannel(options))
5231
5294
  .then(() => {
5232
- if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options)) {
5295
+ if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
5233
5296
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
5234
5297
  this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
5235
5298
  }
5236
5299
  })
5237
5300
  .then(() => this.createLocalOfferOrAnswer(options))
5238
- .then((sessionDescription) => this.setLocalSessionDescription(sessionDescription))
5301
+ .then(sessionDescription => this.setLocalSessionDescription(sessionDescription))
5239
5302
  .then(() => this.waitForIceGatheringComplete(iceRestart, iceTimeout))
5240
5303
  .then(() => this.getLocalSessionDescription())
5241
5304
  .then(description => {
@@ -5358,7 +5421,8 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5358
5421
  }
5359
5422
 
5360
5423
  // Overridden to send `inactive` in conference
5361
- updateDirection(options , isConference = false) {
5424
+ updateDirection(options , isConference = false,
5425
+ audioOnly = false) {
5362
5426
  if (this._peerConnection === undefined) {
5363
5427
  return Promise.reject(new Error('Peer connection closed.'));
5364
5428
  }
@@ -5373,14 +5437,17 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5373
5437
  // if we are stable, assume we are creating a local offer
5374
5438
  this.logger.debug('SessionDescriptionHandler.updateDirection - setting offer direction');
5375
5439
  // determine the direction to offer given the current direction and hold state
5376
- const directionToOffer = (currentDirection ) => {
5440
+ const directionToOffer = (currentDirection , transceiver /* RTCRtpTransceiver */) => {
5377
5441
  if (isConference) {
5442
+ if (audioOnly && transceiver.receiver.track && transceiver.receiver.track.kind === 'video') {
5443
+ return 'sendonly';
5444
+ }
5378
5445
  return options && options.hold ? 'sendonly' : 'sendrecv';
5379
5446
  }
5380
5447
 
5381
5448
  switch (currentDirection) {
5382
5449
  case 'inactive':
5383
- return options && options.hold ? 'inactive' : 'recvonly';
5450
+ return options && options.hold ? 'inactive' : (isConference && !audioOnly ? 'sendrecv' : 'recvonly');
5384
5451
  case 'recvonly':
5385
5452
  return options && options.hold ? 'inactive' : 'recvonly';
5386
5453
  case 'sendonly':
@@ -5396,7 +5463,7 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5396
5463
  // set the transceiver direction to the offer direction
5397
5464
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5398
5465
  if (transceiver.direction /* guarding, but should always be true */) {
5399
- const offerDirection = directionToOffer(transceiver.direction);
5466
+ const offerDirection = directionToOffer(transceiver.direction, transceiver);
5400
5467
  if (transceiver.direction !== offerDirection) {
5401
5468
  // eslint-disable-next-line no-param-reassign
5402
5469
  transceiver.direction = offerDirection;
@@ -5455,6 +5522,13 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5455
5522
  // set the transceiver direction to the answer direction
5456
5523
  this._peerConnection.getTransceivers().forEach((transceiver) => {
5457
5524
  if (transceiver.direction /* guarding, but should always be true */) {
5525
+ const { receiver } = transceiver;
5526
+ if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
5527
+ // eslint-disable-next-line no-param-reassign
5528
+ transceiver.direction = 'inactive';
5529
+ return;
5530
+ }
5531
+
5458
5532
  if (transceiver.direction !== 'stopped' && transceiver.direction !== answerDirection) {
5459
5533
  // eslint-disable-next-line no-param-reassign
5460
5534
  transceiver.direction = answerDirection;
@@ -5493,8 +5567,8 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5493
5567
  }
5494
5568
  const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
5495
5569
 
5496
- // Do not reuse sender tracks in SFU
5497
- if (sender && !sfu) {
5570
+ // Do not reuse sender video tracks in SFU
5571
+ if (sender && (!sfu || newTrack.kind === 'audio')) {
5498
5572
  trackUpdates.push(
5499
5573
  new Promise((resolve) => {
5500
5574
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -5948,9 +6022,15 @@ class WebRTCClient extends Emitter {
5948
6022
 
5949
6023
  call(number , enableVideo , audioOnly = false, conference = false) {
5950
6024
  logger$1.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
5951
- const inviterOptions = {};
6025
+ const inviterOptions = {
6026
+ sessionDescriptionHandlerOptionsReInvite: {
6027
+ conference,
6028
+ audioOnly,
6029
+ },
6030
+ };
6031
+
5952
6032
  if (audioOnly) {
5953
- inviterOptions.sessionDescriptionHandlerModifiersReInvite = [deactivateVideoModifier];
6033
+ inviterOptions.sessionDescriptionHandlerModifiersReInvite = [stripVideo];
5954
6034
  }
5955
6035
 
5956
6036
  const session = new Inviter(this.userAgent, this._makeURI(number), inviterOptions);
@@ -5979,10 +6059,11 @@ class WebRTCClient extends Emitter {
5979
6059
  sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
5980
6060
  };
5981
6061
 
5982
- inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
6062
+ inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
5983
6063
 
6064
+ inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
5984
6065
  if (audioOnly) {
5985
- inviteOptions.sessionDescriptionHandlerModifiers.push(deactivateVideoModifier);
6066
+ inviteOptions.sessionDescriptionHandlerModifiers.push(stripVideo);
5986
6067
  }
5987
6068
 
5988
6069
  // Do not await invite here or we'll miss the Establishing state transition
@@ -6196,6 +6277,9 @@ class WebRTCClient extends Emitter {
6196
6277
  if (!this._isWeb()) {
6197
6278
  options.sessionDescriptionHandlerModifiers = [holdModifier];
6198
6279
  }
6280
+ options.sessionDescriptionHandlerOptions = {
6281
+ constraints: options.constraints,
6282
+ };
6199
6283
 
6200
6284
  // Send re-INVITE
6201
6285
  return session.invite(options);
@@ -6235,6 +6319,9 @@ class WebRTCClient extends Emitter {
6235
6319
  // (eg: holdModifier)
6236
6320
  options.sessionDescriptionHandlerModifiers = [];
6237
6321
  }
6322
+ options.sessionDescriptionHandlerOptions = {
6323
+ constraints: options.constraints,
6324
+ };
6238
6325
 
6239
6326
  // Send re-INVITE
6240
6327
  return session.invite(options);
@@ -6464,7 +6551,8 @@ class WebRTCClient extends Emitter {
6464
6551
  ? this.video.deviceId.exact : undefined;
6465
6552
  }
6466
6553
 
6467
- reinvite(sipSession , newConstraints = null, conference = false) {
6554
+ reinvite(sipSession , newConstraints = null, conference = false,
6555
+ audioOnly = false) {
6468
6556
  if (!sipSession) {
6469
6557
  return false;
6470
6558
  }
@@ -6474,16 +6562,17 @@ class WebRTCClient extends Emitter {
6474
6562
  }
6475
6563
 
6476
6564
  const wasMuted = this.isAudioMuted(sipSession);
6477
- // When upgrading to video, remove the `deactivateVideoModifier` modifiers
6565
+ // When upgrading to video, remove the `stripVideo` modifiers
6478
6566
  if (newConstraints && newConstraints.video) {
6479
6567
  const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
6480
6568
  sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier =>
6481
- modifier !== deactivateVideoModifier);
6569
+ modifier !== stripVideo);
6482
6570
  }
6483
6571
 
6484
6572
  sipSession.sessionDescriptionHandlerOptionsReInvite = {
6485
6573
  ...sipSession.sessionDescriptionHandlerOptionsReInvite,
6486
6574
  conference,
6575
+ audioOnly,
6487
6576
  };
6488
6577
 
6489
6578
  const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
@@ -6523,6 +6612,8 @@ class WebRTCClient extends Emitter {
6523
6612
  },
6524
6613
  sessionDescriptionHandlerOptions: {
6525
6614
  constraints,
6615
+ conference,
6616
+ audioOnly,
6526
6617
  offerOptions: {
6527
6618
  iceRestart: false,
6528
6619
  },
@@ -6982,6 +7073,8 @@ class WebRTCClient extends Emitter {
6982
7073
 
6983
7074
  // Invitation and Inviter extends Session
6984
7075
  _setupSession(session ) {
7076
+ const sipSessionId = this.getSipSessionId(session);
7077
+
6985
7078
  // When receiving an Invitation, the delegate is not defined.
6986
7079
  if (!session.delegate) {
6987
7080
  session.delegate = {};
@@ -7005,8 +7098,18 @@ class WebRTCClient extends Emitter {
7005
7098
  };
7006
7099
  };
7007
7100
 
7101
+ const oldInviteRequest = session.onInviteRequest.bind(session);
7102
+ let hadRemoteVideo = false;
7103
+
7104
+ // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
7105
+ // Becase when `onInvite` is called we already got the video track
7106
+ session.onInviteRequest = (request) => {
7107
+ hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7108
+
7109
+ oldInviteRequest(request);
7110
+ };
7111
+
7008
7112
  session.delegate.onInvite = (request ) => {
7009
- const sipSessionId = this.getSipSessionId(session);
7010
7113
  let updatedCalleeName = null;
7011
7114
  let updatedNumber = null;
7012
7115
  if (session.assertedIdentity) {
@@ -7016,7 +7119,6 @@ class WebRTCClient extends Emitter {
7016
7119
  logger$1.info('re-invite received', { updatedCalleeName, updatedNumber });
7017
7120
 
7018
7121
  // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
7019
- const hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
7020
7122
 
7021
7123
  // Update SDP
7022
7124
  // Remote video is handled by the `track` event. Here we're dealing with video stream removal.
@@ -7066,7 +7168,7 @@ class WebRTCClient extends Emitter {
7066
7168
  }
7067
7169
 
7068
7170
  _isAudioOnly(session ) {
7069
- return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === deactivateVideoModifier);
7171
+ return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === stripVideo);
7070
7172
  }
7071
7173
 
7072
7174
  _setupMedias(session , newStream ) {