@wazo/sdk 0.38.7 → 0.38.8

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 (106) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/api-client.test.js +142 -2
  3. package/esm/__tests__/web-rtc-client.test.js +227 -27
  4. package/esm/api/calld.js +8 -0
  5. package/esm/api/confd.js +134 -2
  6. package/esm/api-client.js +142 -2
  7. package/esm/checker/Checker.js +183 -24
  8. package/esm/checker/checks/aor.js +142 -2
  9. package/esm/checker/checks/api.js +142 -2
  10. package/esm/checker/checks/index.js +183 -24
  11. package/esm/checker/checks/wazo-websocket.js +2 -0
  12. package/esm/checker/checks/webrtc-transport.js +181 -24
  13. package/esm/checker/checks/webrtc.js +181 -24
  14. package/esm/domain/AdHocAPIConference.js +142 -2
  15. package/esm/domain/Features.js +142 -2
  16. package/esm/domain/Meeting.js +18 -0
  17. package/esm/domain/MeetingAuthorization.js +70 -0
  18. package/esm/domain/Phone/CTIPhone.js +142 -2
  19. package/esm/domain/__tests__/Meeting.test.js +87 -1
  20. package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
  21. package/esm/index.js +226 -27
  22. package/esm/service/CallApi.js +142 -2
  23. package/esm/service/getApiClient.js +142 -2
  24. package/esm/simple/Auth.js +226 -27
  25. package/esm/simple/Configuration.js +226 -27
  26. package/esm/simple/Directory.js +142 -2
  27. package/esm/simple/Phone.js +226 -27
  28. package/esm/simple/Websocket.js +3 -0
  29. package/esm/simple/index.js +226 -27
  30. package/esm/simple/room/LocalParticipant.js +226 -27
  31. package/esm/simple/room/Participant.js +226 -27
  32. package/esm/simple/room/RemoteParticipant.js +226 -27
  33. package/esm/simple/room/Room.js +226 -27
  34. package/esm/simple/room/SipRoom.js +226 -27
  35. package/esm/simple/room/Stream.js +226 -27
  36. package/esm/simple/room/__tests__/Participant.test.js +14747 -0
  37. package/esm/simple/room/__tests__/RemoteParticipant.test.js +226 -27
  38. package/esm/simple/utils.js +226 -27
  39. package/esm/utils/__tests__/object.test.js +57 -0
  40. package/esm/utils/__tests__/string.test.js +30 -0
  41. package/esm/utils/object.js +24 -0
  42. package/esm/utils/string.js +10 -0
  43. package/esm/web-rtc-client.js +181 -24
  44. package/esm/websocket-client.js +3 -1
  45. package/lib/__tests__/api-client.test.js +142 -2
  46. package/lib/__tests__/web-rtc-client.test.js +227 -27
  47. package/lib/api/calld.js +8 -0
  48. package/lib/api/confd.js +134 -2
  49. package/lib/api-client.js +142 -2
  50. package/lib/checker/Checker.js +183 -24
  51. package/lib/checker/checks/aor.js +142 -2
  52. package/lib/checker/checks/api.js +142 -2
  53. package/lib/checker/checks/index.js +183 -24
  54. package/lib/checker/checks/wazo-websocket.js +2 -0
  55. package/lib/checker/checks/webrtc-transport.js +181 -24
  56. package/lib/checker/checks/webrtc.js +181 -24
  57. package/lib/domain/AdHocAPIConference.js +142 -2
  58. package/lib/domain/Features.js +142 -2
  59. package/lib/domain/Meeting.js +18 -0
  60. package/lib/domain/MeetingAuthorization.js +79 -0
  61. package/lib/domain/Phone/CTIPhone.js +142 -2
  62. package/lib/domain/__tests__/Meeting.test.js +87 -1
  63. package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
  64. package/lib/index.js +226 -27
  65. package/lib/service/CallApi.js +142 -2
  66. package/lib/service/getApiClient.js +142 -2
  67. package/lib/simple/Auth.js +226 -27
  68. package/lib/simple/Configuration.js +226 -27
  69. package/lib/simple/Directory.js +142 -2
  70. package/lib/simple/Phone.js +226 -27
  71. package/lib/simple/Websocket.js +3 -0
  72. package/lib/simple/index.js +226 -27
  73. package/lib/simple/room/LocalParticipant.js +226 -27
  74. package/lib/simple/room/Participant.js +226 -27
  75. package/lib/simple/room/RemoteParticipant.js +226 -27
  76. package/lib/simple/room/Room.js +226 -27
  77. package/lib/simple/room/SipRoom.js +226 -27
  78. package/lib/simple/room/Stream.js +226 -27
  79. package/lib/simple/room/__tests__/Participant.test.js +14757 -0
  80. package/lib/simple/room/__tests__/RemoteParticipant.test.js +226 -27
  81. package/lib/simple/utils.js +226 -27
  82. package/lib/utils/__tests__/object.test.js +59 -0
  83. package/lib/utils/__tests__/string.test.js +32 -0
  84. package/lib/utils/object.js +28 -0
  85. package/lib/utils/string.js +14 -0
  86. package/lib/web-rtc-client.js +181 -24
  87. package/lib/websocket-client.js +3 -0
  88. package/package.json +2 -2
  89. package/src/__tests__/web-rtc-client.test.js +46 -3
  90. package/src/api/calld.js +8 -0
  91. package/src/api/confd.js +43 -2
  92. package/src/domain/Meeting.js +20 -0
  93. package/src/domain/MeetingAuthorization.js +67 -0
  94. package/src/domain/__tests__/Meeting.test.js +70 -1
  95. package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
  96. package/src/simple/room/Participant.js +40 -0
  97. package/src/simple/room/Room.js +2 -2
  98. package/src/simple/room/SipRoom.js +1 -1
  99. package/src/simple/room/__tests__/Participant.test.js +81 -0
  100. package/src/types/WebSocketMessage.js +7 -1
  101. package/src/utils/__tests__/object.test.js +35 -0
  102. package/src/utils/__tests__/string.test.js +23 -0
  103. package/src/utils/object.js +15 -0
  104. package/src/utils/string.js +8 -0
  105. package/src/web-rtc-client.js +39 -22
  106. package/src/websocket-client.js +2 -0
@@ -2657,6 +2657,70 @@ class ExternalApp {
2657
2657
 
2658
2658
  //
2659
2659
 
2660
+ class MeetingAuthorization {
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+ constructor({
2668
+ meetingUuid,
2669
+ uuid,
2670
+ userUuid,
2671
+ userName,
2672
+ } = {}) {
2673
+ this.meetingUuid = meetingUuid;
2674
+ this.uuid = uuid;
2675
+ this.userUuid = userUuid;
2676
+ this.userName = userName;
2677
+ }
2678
+
2679
+ setStatus(status ) {
2680
+ this.status = status;
2681
+ }
2682
+
2683
+ getStatus() {
2684
+ return this.status;
2685
+ }
2686
+
2687
+ static parse(plain ) {
2688
+ const {
2689
+ meeting_uuid: meetingUuid,
2690
+ uuid,
2691
+ guest_uuid: userUuid,
2692
+ guest_name: userName,
2693
+ } = plain;
2694
+
2695
+ return new MeetingAuthorization({
2696
+ meetingUuid,
2697
+ uuid,
2698
+ userUuid,
2699
+ userName,
2700
+ });
2701
+ }
2702
+
2703
+ static parseMany(items ) {
2704
+ if (!items) {
2705
+ return [];
2706
+ }
2707
+ return items.map(MeetingAuthorization.parse);
2708
+ }
2709
+ }
2710
+
2711
+ //
2712
+
2713
+
2714
+
2715
+
2716
+
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2660
2724
 
2661
2725
 
2662
2726
 
@@ -2667,6 +2731,7 @@ class ExternalApp {
2667
2731
 
2668
2732
 
2669
2733
 
2734
+
2670
2735
 
2671
2736
 
2672
2737
  class Meeting {
@@ -2681,6 +2746,8 @@ class Meeting {
2681
2746
 
2682
2747
 
2683
2748
 
2749
+
2750
+
2684
2751
 
2685
2752
  static parse(plain ) {
2686
2753
  return new Meeting({
@@ -2693,6 +2760,7 @@ class Meeting {
2693
2760
  extension: plain.exten,
2694
2761
  persistent: plain.persistent,
2695
2762
  creationTime: moment__default['default'](plain.creation_time).toDate(),
2763
+ requireAuthorization: plain.require_authorization,
2696
2764
  });
2697
2765
  }
2698
2766
 
@@ -2717,6 +2785,7 @@ class Meeting {
2717
2785
  extension,
2718
2786
  persistent,
2719
2787
  creationTime,
2788
+ requireAuthorization,
2720
2789
  } = {}) {
2721
2790
  this.guestSipAuthorization = guestSipAuthorization;
2722
2791
  this.uri = uri;
@@ -2727,6 +2796,7 @@ class Meeting {
2727
2796
  this.extension = extension;
2728
2797
  this.persistent = persistent;
2729
2798
  this.creationTime = creationTime;
2799
+ this.requireAuthorization = requireAuthorization;
2730
2800
 
2731
2801
  // Useful to compare instead of instanceof with minified code
2732
2802
  this.type = 'Meeting';
@@ -2737,8 +2807,32 @@ class Meeting {
2737
2807
  const [username, secret] = atob(this.guestSipAuthorization).split(':');
2738
2808
  return { username, secret };
2739
2809
  }
2810
+
2740
2811
  }
2741
2812
 
2813
+ //
2814
+
2815
+ const camelToUnderscore = (key ) => {
2816
+ if (typeof key !== 'string') {
2817
+ throw new Error('Input is not a string');
2818
+ }
2819
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
2820
+ };
2821
+
2822
+ //
2823
+
2824
+ const convertKeysFromCamelToUnderscore = (args ) => {
2825
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
2826
+ throw new Error('Input is not an object');
2827
+ }
2828
+
2829
+ return Object.keys(args).reduce((acc, key) => {
2830
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
2831
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
2832
+ return acc;
2833
+ }, {});
2834
+ };
2835
+
2742
2836
  /* */
2743
2837
 
2744
2838
  var confdMethods = (client , baseUrl ) => ({
@@ -2807,8 +2901,18 @@ var confdMethods = (client , baseUrl ) => ({
2807
2901
  getMyMeetings: () =>
2808
2902
  client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
2809
2903
 
2810
- createMyMeeting: (name , persistent ) =>
2811
- client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
2904
+ createMyMeeting: (args ) =>
2905
+ client
2906
+ .post(`${baseUrl}/users/me/meetings`, convertKeysFromCamelToUnderscore(args))
2907
+ .then(Meeting.parse),
2908
+
2909
+ updateMyMeeting: (meetingUuid , data ) =>
2910
+ client.put(
2911
+ `${baseUrl}/users/me/meetings/${meetingUuid}`,
2912
+ convertKeysFromCamelToUnderscore(data),
2913
+ null,
2914
+ ApiRequester.successResponseParser,
2915
+ ),
2812
2916
 
2813
2917
  deleteMyMeeting: (meetingUuid ) =>
2814
2918
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -2816,8 +2920,36 @@ var confdMethods = (client , baseUrl ) => ({
2816
2920
  getMeeting: (meetingUuid ) =>
2817
2921
  client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2818
2922
 
2923
+ meetingAuthorizations: (meetingUuid ) =>
2924
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/authorizations`, null).then(MeetingAuthorization.parseMany),
2925
+
2926
+ meetingAuthorizationReject: (meetingUuid , authorizationUuid ) =>
2927
+ client.put(
2928
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/reject`,
2929
+ {},
2930
+ null,
2931
+ ApiRequester.successResponseParser,
2932
+ ),
2933
+
2934
+ meetingAuthorizationAccept: (meetingUuid , authorizationUuid ) =>
2935
+ client.put(
2936
+ `${baseUrl}/users/me/meetings/${meetingUuid}/authorizations/${authorizationUuid}/accept`,
2937
+ {},
2938
+ null,
2939
+ ApiRequester.successResponseParser,
2940
+ ),
2941
+
2819
2942
  guestGetMeeting: (meetingUuid ) =>
2820
2943
  client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2944
+
2945
+ guestAuthorizationRequest: (userUuid , meetingUuid , username ) =>
2946
+ client
2947
+ .post(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations`, { guest_name: username })
2948
+ .then(MeetingAuthorization.parse),
2949
+
2950
+ guestAuthorizationCheck: (userUuid , meetingUuid , authorizationUuid ) =>
2951
+ client.get(`${baseUrl}/guests/${userUuid}/meetings/${meetingUuid}/authorizations/${authorizationUuid}`, null),
2952
+
2821
2953
  });
2822
2954
 
2823
2955
  //
@@ -5068,6 +5200,14 @@ var calldMethods = (client , baseUrl ) => ({
5068
5200
  getMeetingParticipantsAsUser: async (meetingUuid ) =>
5069
5201
  client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
5070
5202
 
5203
+ banMeetingParticipant: (meetingUuid , participantUuid ) =>
5204
+ client.delete(
5205
+ `${baseUrl}/users/me/meetings/${meetingUuid}/participants/${participantUuid}`,
5206
+ null,
5207
+ null,
5208
+ ApiRequester.successResponseParser,
5209
+ ),
5210
+
5071
5211
  listTrunks: () => client.get(`${baseUrl}/trunks`),
5072
5212
 
5073
5213
  mute: (callId ) =>
@@ -7826,7 +7966,7 @@ class WebRTCClient extends Emitter {
7826
7966
  });
7827
7967
  }
7828
7968
 
7829
- changeAudioInputDevice(id , session , force ) {
7969
+ async changeAudioInputDevice(id , session , force ) {
7830
7970
  const currentId = this.getAudioDeviceId();
7831
7971
  logger$8.info('setting audio input device', { id, currentId, session: !!session });
7832
7972
 
@@ -7834,33 +7974,50 @@ class WebRTCClient extends Emitter {
7834
7974
  return null;
7835
7975
  }
7836
7976
 
7977
+ // in order to handle an audio track change for default devices
7978
+ // we need the actual id of the device (not 'default')
7979
+ let deviceId = id;
7980
+ if (id === 'default' && navigator.mediaDevices) {
7981
+ const devices = await navigator.mediaDevices.enumerateDevices();
7982
+ const defaultDevice = devices.find(device => device.deviceId === 'default');
7983
+ if (defaultDevice) {
7984
+ const deviceLabel = defaultDevice.label.replace('Default - ', '');
7985
+ const targetDevice = devices.find(device => device.label === deviceLabel);
7986
+ if (targetDevice) {
7987
+ deviceId = targetDevice.deviceId;
7988
+ if (!force && deviceId === currentId) {
7989
+ return null;
7990
+ }
7991
+ }
7992
+ }
7993
+ }
7994
+
7837
7995
  // let's update the local audio value
7838
7996
  if (this.audio) {
7839
7997
  this.audio = {
7840
7998
  deviceId: {
7841
- exact: id,
7999
+ exact: deviceId,
7842
8000
  },
7843
8001
  };
7844
8002
  }
7845
8003
 
7846
- if (session) {
8004
+ if (session && navigator.mediaDevices) {
7847
8005
  const sdh = session.sessionDescriptionHandler;
7848
8006
  const pc = sdh.peerConnection;
7849
8007
 
7850
- // $FlowFixMe
7851
- return navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: id } } }).then(async stream => {
7852
- const audioTrack = stream.getAudioTracks()[0];
7853
- const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
8008
+ const constraints = { audio: { deviceId: { exact: deviceId } } };
8009
+ const stream = await navigator.mediaDevices.getUserMedia(constraints);
8010
+ const audioTrack = stream.getAudioTracks()[0];
8011
+ const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
7854
8012
 
7855
- if (sender) {
7856
- if (sender.track) {
7857
- audioTrack.enabled = sender.track.enabled;
7858
- }
7859
- sender.replaceTrack(audioTrack);
8013
+ if (sender) {
8014
+ if (sender.track) {
8015
+ audioTrack.enabled = sender.track.enabled;
7860
8016
  }
8017
+ sender.replaceTrack(audioTrack);
8018
+ }
7861
8019
 
7862
- return stream;
7863
- });
8020
+ return stream;
7864
8021
  }
7865
8022
  }
7866
8023
 
@@ -7880,14 +8037,14 @@ class WebRTCClient extends Emitter {
7880
8037
  return null;
7881
8038
  }
7882
8039
 
7883
- // let's update the local video value
7884
- if (this.video) {
7885
- this.video = {
7886
- deviceId: {
7887
- exact: id,
7888
- },
7889
- };
7890
- }
8040
+ // let's make sure we don't lose other video constraints settings -- width, height, frameRate...
8041
+ const videoObject = typeof this.video === 'object' ? this.video : {};
8042
+ this.video = {
8043
+ ...videoObject,
8044
+ deviceId: {
8045
+ exact: id,
8046
+ },
8047
+ };
7891
8048
  }
7892
8049
 
7893
8050
  changeSessionVideoInputDevice(id , session ) {
@@ -11282,6 +11439,7 @@ const AGENT_UNPAUSED = 'agent_unpaused';
11282
11439
  const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
11283
11440
  const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
11284
11441
  const MEETING_USER_PROGRESS = 'meeting_user_progress';
11442
+ const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
11285
11443
 
11286
11444
  const BLACKLIST_EVENTS = [
11287
11445
  CHAT_MESSAGE_SENT,
@@ -11633,6 +11791,7 @@ WebSocketClient.eventLists = [
11633
11791
  CONFERENCE_ADHOC_PARTICIPANT_LEFT,
11634
11792
  CONFERENCE_ADHOC_DELETED,
11635
11793
  MEETING_USER_PROGRESS,
11794
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED,
11636
11795
  ];
11637
11796
 
11638
11797
  var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
@@ -11704,6 +11863,7 @@ var WebSocketClient$1 = /*#__PURE__*/Object.freeze({
11704
11863
  CONFERENCE_ADHOC_PARTICIPANT_LEFT: CONFERENCE_ADHOC_PARTICIPANT_LEFT,
11705
11864
  CONFERENCE_ADHOC_DELETED: CONFERENCE_ADHOC_DELETED,
11706
11865
  MEETING_USER_PROGRESS: MEETING_USER_PROGRESS,
11866
+ MEETING_USER_GUEST_AUTHORIZATION_CREATED: MEETING_USER_GUEST_AUTHORIZATION_CREATED,
11707
11867
  HEARTBEAT_ENGINE_VERSION: HEARTBEAT_ENGINE_VERSION,
11708
11868
  'default': WebSocketClient
11709
11869
  });
@@ -11808,6 +11968,7 @@ class Participant extends Emitter {
11808
11968
 
11809
11969
 
11810
11970
 
11971
+
11811
11972
 
11812
11973
 
11813
11974
 
@@ -11825,6 +11986,7 @@ class Participant extends Emitter {
11825
11986
 
11826
11987
 
11827
11988
 
11989
+
11828
11990
 
11829
11991
  /**
11830
11992
  * @param room Room The room where the participant is
@@ -11848,6 +12010,7 @@ class Participant extends Emitter {
11848
12010
  this.screensharing = false;
11849
12011
  this.isOnHold = false;
11850
12012
  this.extra = extra;
12013
+ this.banned = false;
11851
12014
 
11852
12015
  this.ON_UPDATED = 'participant/ON_UPDATED';
11853
12016
  this.ON_START_TALKING = 'participant/ON_START_TALKING';
@@ -11864,6 +12027,7 @@ class Participant extends Emitter {
11864
12027
  this.ON_EXTRA_CHANGE = 'participant/ON_EXTRA_CHANGE';
11865
12028
  this.ON_HOLD = 'participant/ON_HOLD';
11866
12029
  this.ON_RESUME = 'participant/ON_RESUME';
12030
+ this.ON_BAN = 'participant/ON_BAN';
11867
12031
  }
11868
12032
 
11869
12033
  triggerEvent(name , ...args ) {
@@ -11904,6 +12068,10 @@ class Participant extends Emitter {
11904
12068
  status.extra = this.extra;
11905
12069
  break;
11906
12070
  }
12071
+ case this.ON_BAN: {
12072
+ status.banned = true;
12073
+ break;
12074
+ }
11907
12075
  }
11908
12076
 
11909
12077
  if (broadcast) {
@@ -12006,6 +12174,11 @@ class Participant extends Emitter {
12006
12174
  this.triggerUpdate(this.ON_RESUME, broadcast);
12007
12175
  }
12008
12176
 
12177
+ onBan(broadcast = true) {
12178
+ this.banned = true;
12179
+ this.triggerUpdate(this.ON_BAN, broadcast);
12180
+ }
12181
+
12009
12182
  getStatus() {
12010
12183
  return {
12011
12184
  callId: this.callId,
@@ -12052,6 +12225,10 @@ class Participant extends Emitter {
12052
12225
  }
12053
12226
  }
12054
12227
 
12228
+ if (status.banned) {
12229
+ this.onBan(false);
12230
+ }
12231
+
12055
12232
  // Poor man's object comparison
12056
12233
  if (typeof status.extra !== 'undefined' && JSON.stringify(this.extra) !== JSON.stringify(status.extra)) {
12057
12234
  this.extra = { ...this.extra, ...status.extra };
@@ -12079,6 +12256,28 @@ class Participant extends Emitter {
12079
12256
  this.streams = streams;
12080
12257
  this.videoStreams = streams;
12081
12258
  }
12259
+
12260
+ async ban(apiRequestDelay = null) {
12261
+ const { meetingUuid } = this.room;
12262
+ if (!meetingUuid) {
12263
+ throw new Error('Attempting to ban a participant without a `meetingUuid`');
12264
+ }
12265
+
12266
+ // this notifies all that someone is being banned
12267
+ this.onBan(true);
12268
+
12269
+ // this allows to delay the actual ban, in order for the banned participant as well as others to react to the situation
12270
+ if (apiRequestDelay) {
12271
+ await this.delay(apiRequestDelay);
12272
+ }
12273
+
12274
+ // proceed with the actual kick
12275
+ return getApiClient().calld.banMeetingParticipant(meetingUuid, this.callId);
12276
+ }
12277
+
12278
+ async delay(ms ) {
12279
+ return new Promise(resolve => setTimeout(resolve, ms));
12280
+ }
12082
12281
  }
12083
12282
 
12084
12283
  //
@@ -12231,7 +12430,7 @@ class Room$1 extends Emitter {
12231
12430
  logger$2.info('connecting to room', { extension, audioOnly, room: !!room });
12232
12431
 
12233
12432
  if (!room) {
12234
- await Wazo.Phone.connect();
12433
+ await Wazo.Phone.connect({ media: constraints });
12235
12434
 
12236
12435
  const withCamera = constraints && !!constraints.video;
12237
12436
 
@@ -12676,7 +12875,7 @@ class Room$1 extends Emitter {
12676
12875
  const participant = this._getParticipantFromCallId(status.callId);
12677
12876
 
12678
12877
  if (participant) {
12679
- // we're received, so no need to broadcast, hence the input false arg
12878
+ // we're receiving, so no need to broadcast
12680
12879
  participant.updateStatus(status, false);
12681
12880
  }
12682
12881
  break;
@@ -12943,7 +13142,7 @@ class SipRoom extends Room$1 {
12943
13142
  logger$1.info('connecting to sip room', { extension, audioOnly, room: !!room });
12944
13143
 
12945
13144
  if (!room) {
12946
- await Wazo.Phone.connect();
13145
+ await Wazo.Phone.connect({ media: constraints });
12947
13146
 
12948
13147
  const withCamera = constraints && !!constraints.video;
12949
13148
 
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ //
4
+
5
+ const camelToUnderscore = (key ) => {
6
+ if (typeof key !== 'string') {
7
+ throw new Error('Input is not a string');
8
+ }
9
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
10
+ };
11
+
12
+ //
13
+
14
+ const convertKeysFromCamelToUnderscore = (args ) => {
15
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
16
+ throw new Error('Input is not an object');
17
+ }
18
+
19
+ return Object.keys(args).reduce((acc, key) => {
20
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
21
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
22
+ return acc;
23
+ }, {});
24
+ };
25
+
26
+ //
27
+
28
+ describe('object utils', () => {
29
+ describe('convertKeysFromCamelToUnderscore', () => {
30
+ it('should throw an error when input is not an object', () => {
31
+ const msg = 'Input is not an object';
32
+ expect(() => convertKeysFromCamelToUnderscore(true)).toThrow(msg);
33
+ expect(() => convertKeysFromCamelToUnderscore(null)).toThrow(msg);
34
+ expect(() => convertKeysFromCamelToUnderscore(undefined)).toThrow(msg);
35
+ expect(() => convertKeysFromCamelToUnderscore([])).toThrow(msg);
36
+ expect(() => convertKeysFromCamelToUnderscore('some-string')).toThrow(msg);
37
+ });
38
+
39
+ it('should convert camel-cased keys to underscore', () => {
40
+ let value = Math.random();
41
+ expect(convertKeysFromCamelToUnderscore({ LoremIpsum: value })).toEqual({ lorem_ipsum: value });
42
+ value = Math.random();
43
+ expect(convertKeysFromCamelToUnderscore({ loremIpsum: value })).toEqual({ lorem_ipsum: value });
44
+ value = Math.random();
45
+ expect(convertKeysFromCamelToUnderscore({ 'lorem-ipsum': value })).toEqual({ 'lorem-ipsum': value });
46
+ value = Math.random();
47
+ expect(convertKeysFromCamelToUnderscore({ L123: value })).toEqual({ l123: value });
48
+ });
49
+
50
+ it('should handle multi-leveled object', () => {
51
+ const value = Math.random();
52
+ expect(convertKeysFromCamelToUnderscore({ LoremIpsum: { DoloreSit: { Amet: value }, regular: 'reg' } }))
53
+ .toEqual({ lorem_ipsum: { dolore_sit: { amet: value }, regular: 'reg' } });
54
+
55
+ expect(convertKeysFromCamelToUnderscore({ LoremIpsum: { DoloreSit: { Amet: [value] }, regular: ['something'] } }))
56
+ .toEqual({ lorem_ipsum: { dolore_sit: { amet: [value] }, regular: ['something'] } });
57
+ });
58
+ });
59
+ });
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ //
4
+
5
+ const camelToUnderscore = (key ) => {
6
+ if (typeof key !== 'string') {
7
+ throw new Error('Input is not a string');
8
+ }
9
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
10
+ };
11
+
12
+ describe('string utils', () => {
13
+ describe('camelToUnderscore', () => {
14
+ it('', () => {
15
+ expect(() => camelToUnderscore(null)).toThrow('Input is not a string');
16
+ expect(() => camelToUnderscore(undefined)).toThrow('Input is not a string');
17
+ expect(() => camelToUnderscore({})).toThrow('Input is not a string');
18
+ expect(() => camelToUnderscore([])).toThrow('Input is not a string');
19
+ });
20
+
21
+ it('should convert camel-cased string to underscore', () => {
22
+ expect(camelToUnderscore('loremIpsum')).toEqual('lorem_ipsum');
23
+ expect(camelToUnderscore('lorem-ipsum')).toEqual('lorem-ipsum');
24
+ expect(camelToUnderscore('')).toEqual('');
25
+ });
26
+
27
+ it('should not prefix string with an underscore', () => {
28
+ expect(camelToUnderscore('LoremIpsum')).toEqual('lorem_ipsum');
29
+ expect(camelToUnderscore('L123')).toEqual('l123');
30
+ });
31
+ });
32
+ });
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ //
6
+
7
+ const camelToUnderscore = (key ) => {
8
+ if (typeof key !== 'string') {
9
+ throw new Error('Input is not a string');
10
+ }
11
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
12
+ };
13
+
14
+ //
15
+
16
+ const convertKeysFromCamelToUnderscore = (args ) => {
17
+ if (!args || typeof args !== 'object' || Array.isArray(args)) {
18
+ throw new Error('Input is not an object');
19
+ }
20
+
21
+ return Object.keys(args).reduce((acc, key) => {
22
+ acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
23
+ ? convertKeysFromCamelToUnderscore(args[key]) : args[key];
24
+ return acc;
25
+ }, {});
26
+ };
27
+
28
+ exports.convertKeysFromCamelToUnderscore = convertKeysFromCamelToUnderscore;
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ //
6
+
7
+ const camelToUnderscore = (key ) => {
8
+ if (typeof key !== 'string') {
9
+ throw new Error('Input is not a string');
10
+ }
11
+ return key.charAt(0).toLowerCase() + key.substring(1).replace(/([A-Z])/g, '_$1').toLowerCase();
12
+ };
13
+
14
+ exports.camelToUnderscore = camelToUnderscore;