@wazo/sdk 0.37.25 → 0.37.29

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 (125) hide show
  1. package/README.md +96 -58
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +2 -2
  4. package/esm/__tests__/web-rtc-client.test.js +10 -5
  5. package/esm/api/agentd.js +1 -1
  6. package/esm/api/amid.js +1 -1
  7. package/esm/api/application.js +1 -1
  8. package/esm/api/auth.js +1 -1
  9. package/esm/api/call-logd.js +1 -1
  10. package/esm/api/calld.js +1 -1
  11. package/esm/api/chatd.js +1 -1
  12. package/esm/api/confd.js +1 -1
  13. package/esm/api/ctid-ng.js +1 -1
  14. package/esm/api/dird.js +2 -2
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +2 -2
  17. package/esm/checker/Checker.js +10 -5
  18. package/esm/checker/checks/aor.js +2 -2
  19. package/esm/checker/checks/api.js +2 -2
  20. package/esm/checker/checks/index.js +10 -5
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +10 -5
  23. package/esm/checker/checks/webrtc.js +10 -5
  24. package/esm/domain/AdHocAPIConference.js +2 -2
  25. package/esm/domain/CallSession.js +29 -2
  26. package/esm/domain/Contact.js +1 -1
  27. package/esm/domain/Features.js +2 -2
  28. package/esm/domain/Phone/CTIPhone.js +31 -4
  29. package/esm/domain/Phone/WebRTCPhone.js +55 -6
  30. package/esm/domain/SFUNotAvailableError.js +9 -0
  31. package/esm/domain/__tests__/CallSession.test.js +46 -2
  32. package/esm/domain/__tests__/Contact.test.js +1 -1
  33. package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
  34. package/esm/domain/__tests__/Room.test.js +29 -2
  35. package/esm/index.js +75 -10
  36. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  37. package/esm/service/CallApi.js +2 -2
  38. package/esm/service/IssueReporter.js +1 -1
  39. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  40. package/esm/service/getApiClient.js +2 -2
  41. package/esm/simple/Auth.js +74 -10
  42. package/esm/simple/Configuration.js +74 -10
  43. package/esm/simple/Directory.js +2 -2
  44. package/esm/simple/Phone.js +74 -10
  45. package/esm/simple/Websocket.js +1 -1
  46. package/esm/simple/index.js +74 -10
  47. package/esm/simple/room/LocalParticipant.js +74 -10
  48. package/esm/simple/room/Participant.js +74 -10
  49. package/esm/simple/room/RemoteParticipant.js +74 -10
  50. package/esm/simple/room/Room.js +74 -10
  51. package/esm/simple/room/SipRoom.js +74 -10
  52. package/esm/simple/room/Stream.js +74 -10
  53. package/esm/simple/room/__tests__/RemoteParticipant.test.js +74 -10
  54. package/esm/simple/utils.js +74 -10
  55. package/esm/utils/__tests__/api-requester.test.js +1 -1
  56. package/esm/utils/api-requester.js +1 -1
  57. package/esm/web-rtc-client.js +10 -5
  58. package/esm/websocket-client.js +1 -1
  59. package/lib/__tests__/api-client.test.js +2 -2
  60. package/lib/__tests__/web-rtc-client.test.js +10 -5
  61. package/lib/api/agentd.js +1 -1
  62. package/lib/api/amid.js +1 -1
  63. package/lib/api/application.js +1 -1
  64. package/lib/api/auth.js +1 -1
  65. package/lib/api/call-logd.js +1 -1
  66. package/lib/api/calld.js +1 -1
  67. package/lib/api/chatd.js +1 -1
  68. package/lib/api/confd.js +1 -1
  69. package/lib/api/ctid-ng.js +1 -1
  70. package/lib/api/dird.js +2 -2
  71. package/lib/api/webhookd.js +1 -1
  72. package/lib/api-client.js +2 -2
  73. package/lib/checker/Checker.js +10 -5
  74. package/lib/checker/checks/aor.js +2 -2
  75. package/lib/checker/checks/api.js +2 -2
  76. package/lib/checker/checks/index.js +10 -5
  77. package/lib/checker/checks/wazo-websocket.js +1 -1
  78. package/lib/checker/checks/webrtc-transport.js +10 -5
  79. package/lib/checker/checks/webrtc.js +10 -5
  80. package/lib/domain/AdHocAPIConference.js +2 -2
  81. package/lib/domain/CallSession.js +29 -2
  82. package/lib/domain/Contact.js +1 -1
  83. package/lib/domain/Features.js +2 -2
  84. package/lib/domain/Phone/CTIPhone.js +31 -4
  85. package/lib/domain/Phone/WebRTCPhone.js +55 -5
  86. package/lib/domain/SFUNotAvailableError.js +11 -0
  87. package/lib/domain/__tests__/CallSession.test.js +46 -2
  88. package/lib/domain/__tests__/Contact.test.js +1 -1
  89. package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
  90. package/lib/domain/__tests__/Room.test.js +29 -2
  91. package/lib/index.js +75 -10
  92. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  93. package/lib/service/CallApi.js +2 -2
  94. package/lib/service/IssueReporter.js +1 -1
  95. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  96. package/lib/service/getApiClient.js +2 -2
  97. package/lib/simple/Auth.js +74 -10
  98. package/lib/simple/Configuration.js +74 -10
  99. package/lib/simple/Directory.js +2 -2
  100. package/lib/simple/Phone.js +74 -10
  101. package/lib/simple/Websocket.js +1 -1
  102. package/lib/simple/index.js +74 -10
  103. package/lib/simple/room/LocalParticipant.js +74 -10
  104. package/lib/simple/room/Participant.js +74 -10
  105. package/lib/simple/room/RemoteParticipant.js +74 -10
  106. package/lib/simple/room/Room.js +74 -10
  107. package/lib/simple/room/SipRoom.js +74 -10
  108. package/lib/simple/room/Stream.js +74 -10
  109. package/lib/simple/room/__tests__/RemoteParticipant.test.js +74 -10
  110. package/lib/simple/utils.js +74 -10
  111. package/lib/utils/__tests__/api-requester.test.js +1 -1
  112. package/lib/utils/api-requester.js +1 -1
  113. package/lib/web-rtc-client.js +10 -5
  114. package/lib/websocket-client.js +1 -1
  115. package/package.json +1 -1
  116. package/src/domain/CallSession.js +32 -4
  117. package/src/domain/Contact.js +1 -1
  118. package/src/domain/Phone/WebRTCPhone.js +24 -2
  119. package/src/domain/SFUNotAvailableError.js +7 -0
  120. package/src/domain/__tests__/CallSession.test.js +17 -0
  121. package/src/index.js +2 -0
  122. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  123. package/src/simple/Phone.js +2 -1
  124. package/src/simple/index.js +2 -0
  125. package/src/utils/api-requester.js +1 -1
@@ -54,13 +54,16 @@ var updateFrom = (instance , from ) => {
54
54
 
55
55
 
56
56
 
57
+
57
58
 
58
59
 
59
60
 
60
61
 
61
62
 
63
+
62
64
 
63
65
 
66
+
64
67
 
65
68
 
66
69
 
@@ -77,6 +80,7 @@ var updateFrom = (instance , from ) => {
77
80
 
78
81
 
79
82
 
83
+
80
84
 
81
85
 
82
86
  class CallSession {
@@ -96,10 +100,14 @@ class CallSession {
96
100
 
97
101
 
98
102
 
99
-
103
+
104
+
105
+ // = creationTime
100
106
 
101
107
 
102
108
 
109
+
110
+
103
111
 
104
112
 
105
113
 
@@ -135,6 +143,8 @@ class CallSession {
135
143
 
136
144
 
137
145
 
146
+
147
+
138
148
 
139
149
  constructor({
140
150
  answered,
@@ -148,6 +158,8 @@ class CallSession {
148
158
  paused,
149
159
  ringing,
150
160
  startTime,
161
+ creationTime,
162
+ endTime,
151
163
  cameraEnabled,
152
164
  dialedExtension,
153
165
  sipCallId,
@@ -160,12 +172,16 @@ class CallSession {
160
172
  recording,
161
173
  recordingPaused,
162
174
  videoRemotelyDowngraded,
175
+ sipSession,
176
+ answerTime,
163
177
  } ) {
164
178
  this.callId = callId;
165
179
  this.sipCallId = sipCallId;
166
180
  this.displayName = displayName;
167
181
  this.number = number;
182
+ this.creationTime = creationTime;
168
183
  this.startTime = startTime;
184
+ this.endTime = endTime;
169
185
  this.isCaller = isCaller;
170
186
  this.answered = answered;
171
187
  this.answeredBySystem = answeredBySystem;
@@ -184,6 +200,8 @@ class CallSession {
184
200
  this.recording = recording || false;
185
201
  this.recordingPaused = recordingPaused || false;
186
202
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
203
+ this.sipSession = sipSession;
204
+ this.answerTime = answerTime || this.answerTime;
187
205
 
188
206
  // Useful to compare instead of instanceof with minified code
189
207
  this.type = 'CallSession';
@@ -214,7 +232,7 @@ class CallSession {
214
232
  }
215
233
 
216
234
  answer() {
217
- this.answered = true;
235
+ this.answerTime = new Date();
218
236
  }
219
237
 
220
238
  systemAnswer() {
@@ -370,6 +388,15 @@ class CallSession {
370
388
  return newFrom(callSession, CallSession);
371
389
  }
372
390
 
391
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
392
+ set answered(value ) {
393
+ this.answerTime = value ? new Date() : null;
394
+ }
395
+
396
+ get answered() {
397
+ return !!this.answerTime;
398
+ }
399
+
373
400
  static parseCall(call ) {
374
401
  return new CallSession({
375
402
  callId: call.id,
@@ -405,7 +432,7 @@ IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
405
432
 
406
433
  // Use a function here to be able to mock it in tests
407
434
  const realFetch = () => {
408
- if (typeof document !== 'undefined') {
435
+ if (typeof document !== 'undefined' && window.fetch) {
409
436
  // Browser
410
437
  return window.fetch;
411
438
  }
@@ -878,6 +905,7 @@ const ON_CAMERA_DISABLED = 'onCameraDisabled';
878
905
  const ON_CAMERA_RESUMED = 'onCameraResumed';
879
906
  const ON_CALL_CANCELED = 'onCallCanceled';
880
907
  const ON_CALL_FAILED = 'onCallFailed';
908
+ const ON_CALL_REJECTED = 'onCallRejected';
881
909
  const ON_CALL_ENDED = 'onCallEnded';
882
910
  const ON_CALL_ENDING = 'onCallEnding';
883
911
  const ON_MESSAGE = 'onMessage';
@@ -922,6 +950,7 @@ const events = [
922
950
  ON_CAMERA_DISABLED,
923
951
  ON_CALL_FAILED,
924
952
  ON_CALL_ENDED,
953
+ ON_CALL_REJECTED,
925
954
  ON_MESSAGE,
926
955
  ON_REINVITE,
927
956
  ON_TRACK,
@@ -1278,6 +1307,7 @@ class WebRTCPhone extends Emitter {
1278
1307
 
1279
1308
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
1280
1309
  const callSession = this._createCallSession(sipSession);
1310
+ callSession.endTime = new Date();
1281
1311
  const wasCurrentSession = this._onCallTerminated(sipSession);
1282
1312
 
1283
1313
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -1473,6 +1503,7 @@ class WebRTCPhone extends Emitter {
1473
1503
  this.removeIncomingSessions(sipSessionId);
1474
1504
  }
1475
1505
 
1506
+ callSession.answerTime = new Date();
1476
1507
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
1477
1508
 
1478
1509
  return callSession;
@@ -1530,6 +1561,7 @@ class WebRTCPhone extends Emitter {
1530
1561
  _onCallTerminated(sipSession ) {
1531
1562
  logger.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
1532
1563
 
1564
+ const sipSessionId = this.getSipSessionId(sipSession);
1533
1565
  const callSession = this._createCallSession(sipSession);
1534
1566
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
1535
1567
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -1547,7 +1579,6 @@ class WebRTCPhone extends Emitter {
1547
1579
  }, 5);
1548
1580
  }
1549
1581
 
1550
- const sipSessionId = this.getSipSessionId(sipSession);
1551
1582
  if (sipSessionId) {
1552
1583
  this.removeIncomingSessions(sipSessionId);
1553
1584
  }
@@ -1688,6 +1719,7 @@ class WebRTCPhone extends Emitter {
1688
1719
  }
1689
1720
 
1690
1721
  this.shouldSendReinvite = false;
1722
+ callSession.answerTime = new Date();
1691
1723
  this.acceptedSessions[callSession.getId()] = true;
1692
1724
 
1693
1725
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -1997,6 +2029,7 @@ class WebRTCPhone extends Emitter {
1997
2029
  return Promise.resolve(null);
1998
2030
  }
1999
2031
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
2032
+ callSession.creationTime = new Date();
2000
2033
 
2001
2034
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
2002
2035
 
@@ -2192,8 +2225,12 @@ class WebRTCPhone extends Emitter {
2192
2225
  }
2193
2226
 
2194
2227
  const sessionId = this.incomingSessions[0];
2228
+ const sipSession = this.client.getSipSession(sessionId);
2229
+ if (!sipSession) {
2230
+ return null;
2231
+ }
2195
2232
 
2196
- return this._createCallSession(this.client.getSipSession(sessionId));
2233
+ return this._createCallSession(sipSession);
2197
2234
  }
2198
2235
 
2199
2236
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -2271,6 +2308,7 @@ class WebRTCPhone extends Emitter {
2271
2308
  callSession);
2272
2309
  }
2273
2310
 
2311
+ callSession.creationTime = new Date();
2274
2312
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
2275
2313
  });
2276
2314
 
@@ -2310,6 +2348,13 @@ class WebRTCPhone extends Emitter {
2310
2348
  this.eventEmitter.emit(ON_CALL_ERROR, e);
2311
2349
  });
2312
2350
 
2351
+ this.client.on(this.client.REJECTED, session => {
2352
+ logger.info('WebRTC call rejected', session.id);
2353
+ const callSession = this._createCallSession(session);
2354
+ callSession.endTime = new Date();
2355
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
2356
+ });
2357
+
2313
2358
  this.client.on(this.client.UNREGISTERED, () => {
2314
2359
  logger.info('WebRTC unregistered');
2315
2360
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -2522,6 +2567,7 @@ class WebRTCPhone extends Emitter {
2522
2567
  const number = identity ? identity.uri._normal.user : null;
2523
2568
  const { state } = sipSession || {};
2524
2569
  const sessionId = this.getSipSessionId(sipSession);
2570
+ fromSession = fromSession || this.callSessions[sessionId];
2525
2571
 
2526
2572
  const callSession = new CallSession({
2527
2573
  callId: fromSession && fromSession.callId,
@@ -2529,6 +2575,8 @@ class WebRTCPhone extends Emitter {
2529
2575
  sipStatus: state,
2530
2576
  displayName: identity ? identity.displayName || number : number,
2531
2577
  startTime: fromSession ? fromSession.startTime : new Date(),
2578
+ creationTime: fromSession ? fromSession.creationTime : null,
2579
+ endTime: fromSession ? fromSession.endTime : null,
2532
2580
  answered: state === SessionState.Established,
2533
2581
  paused: this.client.isCallHeld(sipSession),
2534
2582
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -2539,6 +2587,7 @@ class WebRTCPhone extends Emitter {
2539
2587
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
2540
2588
  recording: fromSession ? fromSession.isRecording() : false,
2541
2589
  recordingPaused: false, // @TODO
2590
+ sipSession,
2542
2591
  ...extra,
2543
2592
  });
2544
2593
 
@@ -2549,4 +2598,4 @@ class WebRTCPhone extends Emitter {
2549
2598
  }
2550
2599
 
2551
2600
  export default WebRTCPhone;
2552
- export { MESSAGE_TYPE_CHAT, MESSAGE_TYPE_SIGNAL, ON_AUDIO_STREAM, ON_CALL_ACCEPTED, ON_CALL_ANSWERED, ON_CALL_CANCELED, ON_CALL_ENDED, ON_CALL_ENDING, ON_CALL_ERROR, ON_CALL_FAILED, ON_CALL_HELD, ON_CALL_INCOMING, ON_CALL_MUTED, ON_CALL_OUTGOING, ON_CALL_RESUMED, ON_CALL_UNHELD, ON_CALL_UNMUTED, ON_CAMERA_DISABLED, ON_CAMERA_RESUMED, ON_CHAT, ON_DISCONNECTED, ON_MESSAGE, ON_MESSAGE_TRACK_UPDATED, ON_NETWORK_STATS, ON_PLAY_HANGUP_SOUND, ON_PLAY_INBOUND_CALL_SIGNAL_SOUND, ON_PLAY_PROGRESS_SOUND, ON_PLAY_RING_SOUND, ON_PROGRESS, ON_REGISTERED, ON_REINVITE, ON_REMOVE_STREAM, ON_SHARE_SCREEN_ENDED, ON_SHARE_SCREEN_ENDING, ON_SHARE_SCREEN_STARTED, ON_SIGNAL, ON_TERMINATE_SOUND, ON_TRACK, ON_UNREGISTERED, ON_USER_AGENT, ON_VIDEO_INPUT_CHANGE, ON_VIDEO_STREAM, events };
2601
+ export { MESSAGE_TYPE_CHAT, MESSAGE_TYPE_SIGNAL, ON_AUDIO_STREAM, ON_CALL_ACCEPTED, ON_CALL_ANSWERED, ON_CALL_CANCELED, ON_CALL_ENDED, ON_CALL_ENDING, ON_CALL_ERROR, ON_CALL_FAILED, ON_CALL_HELD, ON_CALL_INCOMING, ON_CALL_MUTED, ON_CALL_OUTGOING, ON_CALL_REJECTED, ON_CALL_RESUMED, ON_CALL_UNHELD, ON_CALL_UNMUTED, ON_CAMERA_DISABLED, ON_CAMERA_RESUMED, ON_CHAT, ON_DISCONNECTED, ON_MESSAGE, ON_MESSAGE_TRACK_UPDATED, ON_NETWORK_STATS, ON_PLAY_HANGUP_SOUND, ON_PLAY_INBOUND_CALL_SIGNAL_SOUND, ON_PLAY_PROGRESS_SOUND, ON_PLAY_RING_SOUND, ON_PROGRESS, ON_REGISTERED, ON_REINVITE, ON_REMOVE_STREAM, ON_SHARE_SCREEN_ENDED, ON_SHARE_SCREEN_ENDING, ON_SHARE_SCREEN_STARTED, ON_SIGNAL, ON_TERMINATE_SOUND, ON_TRACK, ON_UNREGISTERED, ON_USER_AGENT, ON_VIDEO_INPUT_CHANGE, ON_VIDEO_STREAM, events };
@@ -0,0 +1,9 @@
1
+ /* */
2
+ class SFUNotAvailableError extends Error {
3
+ constructor(message = 'Sorry your user is not configured to support video conference') {
4
+ super(message);
5
+ this.name = 'SFUNotAvailableError';
6
+ }
7
+ }
8
+
9
+ export default SFUNotAvailableError;
@@ -32,13 +32,16 @@ var updateFrom = (instance , from ) => {
32
32
 
33
33
 
34
34
 
35
+
35
36
 
36
37
 
37
38
 
38
39
 
39
40
 
41
+
40
42
 
41
43
 
44
+
42
45
 
43
46
 
44
47
 
@@ -55,6 +58,7 @@ var updateFrom = (instance , from ) => {
55
58
 
56
59
 
57
60
 
61
+
58
62
 
59
63
 
60
64
  class CallSession {
@@ -74,10 +78,14 @@ class CallSession {
74
78
 
75
79
 
76
80
 
77
-
81
+
82
+
83
+ // = creationTime
78
84
 
79
85
 
80
86
 
87
+
88
+
81
89
 
82
90
 
83
91
 
@@ -113,6 +121,8 @@ class CallSession {
113
121
 
114
122
 
115
123
 
124
+
125
+
116
126
 
117
127
  constructor({
118
128
  answered,
@@ -126,6 +136,8 @@ class CallSession {
126
136
  paused,
127
137
  ringing,
128
138
  startTime,
139
+ creationTime,
140
+ endTime,
129
141
  cameraEnabled,
130
142
  dialedExtension,
131
143
  sipCallId,
@@ -138,12 +150,16 @@ class CallSession {
138
150
  recording,
139
151
  recordingPaused,
140
152
  videoRemotelyDowngraded,
153
+ sipSession,
154
+ answerTime,
141
155
  } ) {
142
156
  this.callId = callId;
143
157
  this.sipCallId = sipCallId;
144
158
  this.displayName = displayName;
145
159
  this.number = number;
160
+ this.creationTime = creationTime;
146
161
  this.startTime = startTime;
162
+ this.endTime = endTime;
147
163
  this.isCaller = isCaller;
148
164
  this.answered = answered;
149
165
  this.answeredBySystem = answeredBySystem;
@@ -162,6 +178,8 @@ class CallSession {
162
178
  this.recording = recording || false;
163
179
  this.recordingPaused = recordingPaused || false;
164
180
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
181
+ this.sipSession = sipSession;
182
+ this.answerTime = answerTime || this.answerTime;
165
183
 
166
184
  // Useful to compare instead of instanceof with minified code
167
185
  this.type = 'CallSession';
@@ -192,7 +210,7 @@ class CallSession {
192
210
  }
193
211
 
194
212
  answer() {
195
- this.answered = true;
213
+ this.answerTime = new Date();
196
214
  }
197
215
 
198
216
  systemAnswer() {
@@ -348,6 +366,15 @@ class CallSession {
348
366
  return newFrom(callSession, CallSession);
349
367
  }
350
368
 
369
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
370
+ set answered(value ) {
371
+ this.answerTime = value ? new Date() : null;
372
+ }
373
+
374
+ get answered() {
375
+ return !!this.answerTime;
376
+ }
377
+
351
378
  static parseCall(call ) {
352
379
  return new CallSession({
353
380
  callId: call.id,
@@ -410,4 +437,21 @@ describe('CallSession domain', () => {
410
437
  expect(cs1.is(cs2)).toBeTruthy();
411
438
  expect(cs2.is(cs1)).toBeTruthy();
412
439
  });
440
+
441
+ it('should set answerTime when setting answered', () => {
442
+ const cs1 = new CallSession({});
443
+ cs1.answered = true;
444
+
445
+ const cs2 = new CallSession({});
446
+ cs2.answer();
447
+
448
+ const cs3 = new CallSession({ answered: true });
449
+
450
+ expect(cs1.answered).toBeTruthy();
451
+ expect(cs1.answerTime).not.toBeNull();
452
+ expect(cs2.answered).toBeTruthy();
453
+ expect(cs2.answerTime).not.toBeNull();
454
+ expect(cs3.answered).toBeTruthy();
455
+ expect(cs3.answerTime).not.toBeNull();
456
+ });
413
457
  });
@@ -698,7 +698,7 @@ class Contact {
698
698
  this[key] = old[key] || this[key];
699
699
  });
700
700
 
701
- if (old.lineState && !this.lineState) {
701
+ if (old.lineState) {
702
702
  this.lineState = old.lineState;
703
703
  }
704
704
 
@@ -32,13 +32,16 @@ var updateFrom = (instance , from ) => {
32
32
 
33
33
 
34
34
 
35
+
35
36
 
36
37
 
37
38
 
38
39
 
39
40
 
41
+
40
42
 
41
43
 
44
+
42
45
 
43
46
 
44
47
 
@@ -55,6 +58,7 @@ var updateFrom = (instance , from ) => {
55
58
 
56
59
 
57
60
 
61
+
58
62
 
59
63
 
60
64
  class CallSession {
@@ -74,10 +78,14 @@ class CallSession {
74
78
 
75
79
 
76
80
 
77
-
81
+
82
+
83
+ // = creationTime
78
84
 
79
85
 
80
86
 
87
+
88
+
81
89
 
82
90
 
83
91
 
@@ -113,6 +121,8 @@ class CallSession {
113
121
 
114
122
 
115
123
 
124
+
125
+
116
126
 
117
127
  constructor({
118
128
  answered,
@@ -126,6 +136,8 @@ class CallSession {
126
136
  paused,
127
137
  ringing,
128
138
  startTime,
139
+ creationTime,
140
+ endTime,
129
141
  cameraEnabled,
130
142
  dialedExtension,
131
143
  sipCallId,
@@ -138,12 +150,16 @@ class CallSession {
138
150
  recording,
139
151
  recordingPaused,
140
152
  videoRemotelyDowngraded,
153
+ sipSession,
154
+ answerTime,
141
155
  } ) {
142
156
  this.callId = callId;
143
157
  this.sipCallId = sipCallId;
144
158
  this.displayName = displayName;
145
159
  this.number = number;
160
+ this.creationTime = creationTime;
146
161
  this.startTime = startTime;
162
+ this.endTime = endTime;
147
163
  this.isCaller = isCaller;
148
164
  this.answered = answered;
149
165
  this.answeredBySystem = answeredBySystem;
@@ -162,6 +178,8 @@ class CallSession {
162
178
  this.recording = recording || false;
163
179
  this.recordingPaused = recordingPaused || false;
164
180
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
181
+ this.sipSession = sipSession;
182
+ this.answerTime = answerTime || this.answerTime;
165
183
 
166
184
  // Useful to compare instead of instanceof with minified code
167
185
  this.type = 'CallSession';
@@ -192,7 +210,7 @@ class CallSession {
192
210
  }
193
211
 
194
212
  answer() {
195
- this.answered = true;
213
+ this.answerTime = new Date();
196
214
  }
197
215
 
198
216
  systemAnswer() {
@@ -348,6 +366,15 @@ class CallSession {
348
366
  return newFrom(callSession, CallSession);
349
367
  }
350
368
 
369
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
370
+ set answered(value ) {
371
+ this.answerTime = value ? new Date() : null;
372
+ }
373
+
374
+ get answered() {
375
+ return !!this.answerTime;
376
+ }
377
+
351
378
  static parseCall(call ) {
352
379
  return new CallSession({
353
380
  callId: call.id,
@@ -32,13 +32,16 @@ var updateFrom = (instance , from ) => {
32
32
 
33
33
 
34
34
 
35
+
35
36
 
36
37
 
37
38
 
38
39
 
39
40
 
41
+
40
42
 
41
43
 
44
+
42
45
 
43
46
 
44
47
 
@@ -55,6 +58,7 @@ var updateFrom = (instance , from ) => {
55
58
 
56
59
 
57
60
 
61
+
58
62
 
59
63
 
60
64
  class CallSession {
@@ -74,10 +78,14 @@ class CallSession {
74
78
 
75
79
 
76
80
 
77
-
81
+
82
+
83
+ // = creationTime
78
84
 
79
85
 
80
86
 
87
+
88
+
81
89
 
82
90
 
83
91
 
@@ -113,6 +121,8 @@ class CallSession {
113
121
 
114
122
 
115
123
 
124
+
125
+
116
126
 
117
127
  constructor({
118
128
  answered,
@@ -126,6 +136,8 @@ class CallSession {
126
136
  paused,
127
137
  ringing,
128
138
  startTime,
139
+ creationTime,
140
+ endTime,
129
141
  cameraEnabled,
130
142
  dialedExtension,
131
143
  sipCallId,
@@ -138,12 +150,16 @@ class CallSession {
138
150
  recording,
139
151
  recordingPaused,
140
152
  videoRemotelyDowngraded,
153
+ sipSession,
154
+ answerTime,
141
155
  } ) {
142
156
  this.callId = callId;
143
157
  this.sipCallId = sipCallId;
144
158
  this.displayName = displayName;
145
159
  this.number = number;
160
+ this.creationTime = creationTime;
146
161
  this.startTime = startTime;
162
+ this.endTime = endTime;
147
163
  this.isCaller = isCaller;
148
164
  this.answered = answered;
149
165
  this.answeredBySystem = answeredBySystem;
@@ -162,6 +178,8 @@ class CallSession {
162
178
  this.recording = recording || false;
163
179
  this.recordingPaused = recordingPaused || false;
164
180
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
181
+ this.sipSession = sipSession;
182
+ this.answerTime = answerTime || this.answerTime;
165
183
 
166
184
  // Useful to compare instead of instanceof with minified code
167
185
  this.type = 'CallSession';
@@ -192,7 +210,7 @@ class CallSession {
192
210
  }
193
211
 
194
212
  answer() {
195
- this.answered = true;
213
+ this.answerTime = new Date();
196
214
  }
197
215
 
198
216
  systemAnswer() {
@@ -348,6 +366,15 @@ class CallSession {
348
366
  return newFrom(callSession, CallSession);
349
367
  }
350
368
 
369
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
370
+ set answered(value ) {
371
+ this.answerTime = value ? new Date() : null;
372
+ }
373
+
374
+ get answered() {
375
+ return !!this.answerTime;
376
+ }
377
+
351
378
  static parseCall(call ) {
352
379
  return new CallSession({
353
380
  callId: call.id,