@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.
- package/dist/wazo-sdk.js +5 -5
- package/esm/__tests__/api-client.test.js +93 -16
- package/esm/__tests__/web-rtc-client.test.js +153 -54
- package/esm/api/agentd.js +24 -3
- package/esm/api/amid.js +7 -1
- package/esm/api/application.js +24 -3
- package/esm/api/auth.js +24 -3
- package/esm/api/call-logd.js +78 -20
- package/esm/api/calld.js +24 -20
- package/esm/api/chatd.js +24 -3
- package/esm/api/confd.js +24 -3
- package/esm/api/ctid-ng.js +24 -3
- package/esm/api/dird.js +27 -6
- package/esm/api/webhookd.js +7 -1
- package/esm/api-client.js +93 -16
- package/esm/checker/Checker.js +156 -54
- package/esm/checker/checks/aor.js +95 -16
- package/esm/checker/checks/api.js +94 -16
- package/esm/checker/checks/index.js +156 -54
- package/esm/checker/checks/wazo-websocket.js +7 -1
- package/esm/checker/checks/webrtc-transport.js +153 -54
- package/esm/checker/checks/webrtc.js +153 -54
- package/esm/domain/AdHocAPIConference.js +1717 -1640
- package/esm/domain/CallLog.js +71 -19
- package/esm/domain/CallSession.js +1 -18
- package/esm/domain/Contact.js +3 -3
- package/esm/domain/Features.js +93 -16
- package/esm/domain/IndirectTransfer.js +0 -17
- package/esm/domain/Phone/CTIPhone.js +100 -19
- package/esm/domain/Phone/Phone.js +0 -17
- package/esm/domain/Phone/WebRTCPhone.js +51 -36
- package/esm/domain/Recording.js +51 -0
- package/esm/domain/Room.js +0 -17
- package/esm/domain/SwitchboardCall.js +0 -17
- package/esm/domain/__tests__/CallLog.test.js +89 -19
- package/esm/domain/__tests__/CallSession.test.js +1 -18
- package/esm/domain/__tests__/Contact.test.js +3 -3
- package/esm/domain/__tests__/IndirectTransfer.test.js +1 -18
- package/esm/domain/__tests__/Room.test.js +1 -18
- package/esm/domain/__tests__/Session.test.js +7 -0
- package/esm/index.js +3436 -2911
- package/esm/lib/WazoSessionDescriptionHandler.js +28 -10
- package/esm/service/CallApi.js +93 -16
- package/esm/service/IssueReporter.js +7 -1
- package/esm/service/__tests__/IssueReporter.test.js +26 -2
- package/esm/service/getApiClient.js +93 -16
- package/esm/simple/Auth.js +619 -97
- package/esm/simple/Configuration.js +619 -97
- package/esm/simple/Directory.js +93 -16
- package/esm/simple/Phone.js +3261 -2739
- package/esm/simple/Websocket.js +7 -1
- package/esm/simple/index.js +619 -97
- package/esm/simple/room/LocalParticipant.js +619 -97
- package/esm/simple/room/Participant.js +619 -97
- package/esm/simple/room/RemoteParticipant.js +619 -97
- package/esm/simple/room/Room.js +619 -97
- package/esm/simple/room/Stream.js +619 -97
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +619 -97
- package/esm/simple/utils.js +619 -97
- package/esm/utils/__tests__/api-requester.test.js +32 -6
- package/esm/utils/api-requester.js +24 -3
- package/esm/web-rtc-client.js +153 -54
- package/esm/websocket-client.js +7 -1
- package/lib/__tests__/api-client.test.js +93 -16
- package/lib/__tests__/web-rtc-client.test.js +154 -55
- package/lib/api/agentd.js +24 -3
- package/lib/api/amid.js +7 -1
- package/lib/api/application.js +24 -3
- package/lib/api/auth.js +24 -3
- package/lib/api/call-logd.js +78 -20
- package/lib/api/calld.js +24 -20
- package/lib/api/chatd.js +24 -3
- package/lib/api/confd.js +24 -3
- package/lib/api/ctid-ng.js +24 -3
- package/lib/api/dird.js +27 -6
- package/lib/api/webhookd.js +7 -1
- package/lib/api-client.js +93 -16
- package/lib/checker/Checker.js +157 -55
- package/lib/checker/checks/aor.js +95 -16
- package/lib/checker/checks/api.js +94 -16
- package/lib/checker/checks/index.js +157 -55
- package/lib/checker/checks/wazo-websocket.js +7 -1
- package/lib/checker/checks/webrtc-transport.js +154 -55
- package/lib/checker/checks/webrtc.js +154 -55
- package/lib/domain/AdHocAPIConference.js +1717 -1640
- package/lib/domain/CallLog.js +71 -19
- package/lib/domain/CallSession.js +1 -18
- package/lib/domain/Contact.js +3 -3
- package/lib/domain/Features.js +93 -16
- package/lib/domain/IndirectTransfer.js +0 -17
- package/lib/domain/Phone/CTIPhone.js +100 -19
- package/lib/domain/Phone/Phone.js +0 -16
- package/lib/domain/Phone/WebRTCPhone.js +51 -36
- package/lib/domain/Recording.js +57 -0
- package/lib/domain/Room.js +0 -17
- package/lib/domain/SwitchboardCall.js +0 -17
- package/lib/domain/__tests__/CallLog.test.js +89 -19
- package/lib/domain/__tests__/CallSession.test.js +1 -18
- package/lib/domain/__tests__/Contact.test.js +3 -3
- package/lib/domain/__tests__/IndirectTransfer.test.js +1 -18
- package/lib/domain/__tests__/Room.test.js +1 -18
- package/lib/domain/__tests__/Session.test.js +7 -0
- package/lib/index.js +3437 -2912
- package/lib/lib/WazoSessionDescriptionHandler.js +28 -10
- package/lib/service/CallApi.js +93 -16
- package/lib/service/IssueReporter.js +7 -1
- package/lib/service/__tests__/IssueReporter.test.js +26 -2
- package/lib/service/getApiClient.js +93 -16
- package/lib/simple/Auth.js +620 -98
- package/lib/simple/Configuration.js +620 -98
- package/lib/simple/Directory.js +93 -16
- package/lib/simple/Phone.js +3262 -2740
- package/lib/simple/Websocket.js +7 -1
- package/lib/simple/index.js +620 -98
- package/lib/simple/room/LocalParticipant.js +620 -98
- package/lib/simple/room/Participant.js +620 -98
- package/lib/simple/room/RemoteParticipant.js +620 -98
- package/lib/simple/room/Room.js +620 -98
- package/lib/simple/room/Stream.js +620 -98
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +620 -98
- package/lib/simple/utils.js +620 -98
- package/lib/utils/__tests__/api-requester.test.js +32 -6
- package/lib/utils/api-requester.js +24 -3
- package/lib/web-rtc-client.js +154 -55
- package/lib/websocket-client.js +7 -1
- package/package.json +1 -1
- package/src/api-client.js +4 -0
- package/src/checker/checks/aor.js +2 -0
- package/src/checker/checks/api.js +1 -0
- package/src/domain/CallLog.js +18 -11
- package/src/domain/CallSession.js +1 -2
- package/src/domain/Contact.js +3 -3
- package/src/domain/Phone/CTIPhone.js +6 -2
- package/src/domain/Phone/Phone.js +2 -0
- package/src/domain/Phone/WebRTCPhone.js +26 -16
- package/src/domain/Recording.js +48 -0
- package/src/domain/__tests__/CallLog.test.js +19 -0
- package/src/domain/__tests__/Session.test.js +7 -0
- package/src/index.js +6 -0
- package/src/lib/WazoSessionDescriptionHandler.js +21 -9
- package/src/service/IssueReporter.js +7 -1
- package/src/service/__tests__/IssueReporter.test.js +20 -1
- package/src/simple/Phone.js +5 -1
- package/src/simple/index.js +6 -0
- package/src/simple/room/Room.js +18 -15
- package/src/simple/room/Stream.js +1 -4
- package/src/utils/__tests__/api-requester.test.js +9 -4
- package/src/utils/api-requester.js +17 -2
- package/src/web-rtc-client.js +40 -13
|
@@ -311,7 +311,13 @@ class IssueReporter {
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
_isLevelAbove(level1 , level2 ) {
|
|
314
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
});
|
package/lib/web-rtc-client.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 = [
|
|
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.
|
|
5497
|
+
inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
|
|
5421
5498
|
|
|
5499
|
+
inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
|
|
5422
5500
|
if (audioOnly) {
|
|
5423
|
-
inviteOptions.sessionDescriptionHandlerModifiers.push(
|
|
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 `
|
|
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 !==
|
|
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 ===
|
|
6606
|
+
return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === modifiers.stripVideo);
|
|
6508
6607
|
}
|
|
6509
6608
|
|
|
6510
6609
|
_setupMedias(session , newStream ) {
|
package/lib/websocket-client.js
CHANGED
|
@@ -310,7 +310,13 @@ class IssueReporter {
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
_isLevelAbove(level1 , level2 ) {
|
|
313
|
-
|
|
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