@wazo/sdk 0.38.5 → 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.
- package/README.md +1 -1
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/api-client.test.js +148 -2
- package/esm/__tests__/web-rtc-client.test.js +303 -26
- package/esm/api/calld.js +14 -0
- package/esm/api/confd.js +134 -2
- package/esm/api/ctid-ng.js +6 -0
- package/esm/api-client.js +148 -2
- package/esm/checker/Checker.js +212 -26
- package/esm/checker/checks/aor.js +148 -2
- package/esm/checker/checks/api.js +148 -2
- package/esm/checker/checks/index.js +212 -26
- package/esm/checker/checks/wazo-websocket.js +2 -0
- package/esm/checker/checks/webrtc-transport.js +210 -26
- package/esm/checker/checks/webrtc.js +210 -26
- package/esm/domain/AdHocAPIConference.js +148 -2
- package/esm/domain/Call.js +6 -0
- package/esm/domain/CallSession.js +1 -1
- package/esm/domain/Features.js +148 -2
- package/esm/domain/Meeting.js +18 -0
- package/esm/domain/MeetingAuthorization.js +70 -0
- package/esm/domain/Phone/CTIPhone.js +149 -3
- package/esm/domain/Phone/WebRTCPhone.js +3 -3
- package/esm/domain/__tests__/Call.test.js +6 -0
- package/esm/domain/__tests__/CallSession.test.js +1 -1
- package/esm/domain/__tests__/IndirectTransfer.test.js +1 -1
- package/esm/domain/__tests__/Meeting.test.js +87 -1
- package/esm/domain/__tests__/MeetingAuthorization.test.js +109 -0
- package/esm/domain/__tests__/Room.test.js +1 -1
- package/esm/index.js +258 -32
- package/esm/lib/WazoSessionDescriptionHandler.js +22 -1
- package/esm/service/CallApi.js +148 -2
- package/esm/service/getApiClient.js +148 -2
- package/esm/simple/Auth.js +258 -32
- package/esm/simple/Configuration.js +258 -32
- package/esm/simple/Directory.js +148 -2
- package/esm/simple/Phone.js +258 -32
- package/esm/simple/Websocket.js +3 -0
- package/esm/simple/index.js +258 -32
- package/esm/simple/room/LocalParticipant.js +258 -32
- package/esm/simple/room/Participant.js +258 -32
- package/esm/simple/room/RemoteParticipant.js +258 -32
- package/esm/simple/room/Room.js +258 -32
- package/esm/simple/room/SipRoom.js +258 -32
- package/esm/simple/room/Stream.js +258 -32
- package/esm/simple/room/__tests__/Participant.test.js +14747 -0
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +258 -32
- package/esm/simple/utils.js +258 -32
- package/esm/utils/__tests__/object.test.js +57 -0
- package/esm/utils/__tests__/sdp.test.js +50 -0
- package/esm/utils/__tests__/string.test.js +30 -0
- package/esm/utils/object.js +24 -0
- package/esm/utils/sdp.js +19 -1
- package/esm/utils/string.js +10 -0
- package/esm/web-rtc-client.js +210 -26
- package/esm/websocket-client.js +3 -1
- package/lib/__tests__/api-client.test.js +148 -2
- package/lib/__tests__/web-rtc-client.test.js +303 -26
- package/lib/api/calld.js +14 -0
- package/lib/api/confd.js +134 -2
- package/lib/api/ctid-ng.js +6 -0
- package/lib/api-client.js +148 -2
- package/lib/checker/Checker.js +212 -26
- package/lib/checker/checks/aor.js +148 -2
- package/lib/checker/checks/api.js +148 -2
- package/lib/checker/checks/index.js +212 -26
- package/lib/checker/checks/wazo-websocket.js +2 -0
- package/lib/checker/checks/webrtc-transport.js +210 -26
- package/lib/checker/checks/webrtc.js +210 -26
- package/lib/domain/AdHocAPIConference.js +148 -2
- package/lib/domain/Call.js +6 -0
- package/lib/domain/CallSession.js +1 -1
- package/lib/domain/Features.js +148 -2
- package/lib/domain/Meeting.js +18 -0
- package/lib/domain/MeetingAuthorization.js +79 -0
- package/lib/domain/Phone/CTIPhone.js +149 -3
- package/lib/domain/Phone/WebRTCPhone.js +3 -3
- package/lib/domain/__tests__/Call.test.js +6 -0
- package/lib/domain/__tests__/CallSession.test.js +1 -1
- package/lib/domain/__tests__/IndirectTransfer.test.js +1 -1
- package/lib/domain/__tests__/Meeting.test.js +87 -1
- package/lib/domain/__tests__/MeetingAuthorization.test.js +111 -0
- package/lib/domain/__tests__/Room.test.js +1 -1
- package/lib/index.js +258 -32
- package/lib/lib/WazoSessionDescriptionHandler.js +22 -1
- package/lib/service/CallApi.js +148 -2
- package/lib/service/getApiClient.js +148 -2
- package/lib/simple/Auth.js +258 -32
- package/lib/simple/Configuration.js +258 -32
- package/lib/simple/Directory.js +148 -2
- package/lib/simple/Phone.js +258 -32
- package/lib/simple/Websocket.js +3 -0
- package/lib/simple/index.js +258 -32
- package/lib/simple/room/LocalParticipant.js +258 -32
- package/lib/simple/room/Participant.js +258 -32
- package/lib/simple/room/RemoteParticipant.js +258 -32
- package/lib/simple/room/Room.js +258 -32
- package/lib/simple/room/SipRoom.js +258 -32
- package/lib/simple/room/Stream.js +258 -32
- package/lib/simple/room/__tests__/Participant.test.js +14757 -0
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +258 -32
- package/lib/simple/utils.js +258 -32
- package/lib/utils/__tests__/object.test.js +59 -0
- package/lib/utils/__tests__/sdp.test.js +50 -0
- package/lib/utils/__tests__/string.test.js +32 -0
- package/lib/utils/object.js +28 -0
- package/lib/utils/sdp.js +19 -0
- package/lib/utils/string.js +14 -0
- package/lib/web-rtc-client.js +210 -26
- package/lib/websocket-client.js +3 -0
- package/package.json +2 -2
- package/src/__tests__/web-rtc-client.test.js +93 -0
- package/src/api/calld.js +8 -0
- package/src/api/confd.js +43 -2
- package/src/domain/Call.js +6 -0
- package/src/domain/CallSession.js +1 -1
- package/src/domain/Meeting.js +20 -0
- package/src/domain/MeetingAuthorization.js +67 -0
- package/src/domain/Phone/WebRTCPhone.js +2 -2
- package/src/domain/__tests__/Meeting.test.js +70 -1
- package/src/domain/__tests__/MeetingAuthorization.test.js +58 -0
- package/src/lib/WazoSessionDescriptionHandler.js +5 -2
- package/src/simple/room/Participant.js +40 -0
- package/src/simple/room/Room.js +2 -2
- package/src/simple/room/SipRoom.js +1 -1
- package/src/simple/room/__tests__/Participant.test.js +81 -0
- package/src/types/WebSocketMessage.js +7 -1
- package/src/utils/__tests__/object.test.js +35 -0
- package/src/utils/__tests__/sdp.test.js +33 -1
- package/src/utils/__tests__/string.test.js +23 -0
- package/src/utils/object.js +15 -0
- package/src/utils/sdp.js +18 -0
- package/src/utils/string.js +8 -0
- package/src/web-rtc-client.js +40 -23
- package/src/websocket-client.js +2 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import { convertKeysFromCamelToUnderscore } from '../object';
|
|
3
|
+
|
|
4
|
+
describe('object utils', () => {
|
|
5
|
+
describe('convertKeysFromCamelToUnderscore', () => {
|
|
6
|
+
it('should throw an error when input is not an object', () => {
|
|
7
|
+
const msg = 'Input is not an object';
|
|
8
|
+
expect(() => convertKeysFromCamelToUnderscore(true)).toThrow(msg);
|
|
9
|
+
expect(() => convertKeysFromCamelToUnderscore(null)).toThrow(msg);
|
|
10
|
+
expect(() => convertKeysFromCamelToUnderscore(undefined)).toThrow(msg);
|
|
11
|
+
expect(() => convertKeysFromCamelToUnderscore([])).toThrow(msg);
|
|
12
|
+
expect(() => convertKeysFromCamelToUnderscore('some-string')).toThrow(msg);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should convert camel-cased keys to underscore', () => {
|
|
16
|
+
let value = Math.random();
|
|
17
|
+
expect(convertKeysFromCamelToUnderscore({ LoremIpsum: value })).toEqual({ lorem_ipsum: value });
|
|
18
|
+
value = Math.random();
|
|
19
|
+
expect(convertKeysFromCamelToUnderscore({ loremIpsum: value })).toEqual({ lorem_ipsum: value });
|
|
20
|
+
value = Math.random();
|
|
21
|
+
expect(convertKeysFromCamelToUnderscore({ 'lorem-ipsum': value })).toEqual({ 'lorem-ipsum': value });
|
|
22
|
+
value = Math.random();
|
|
23
|
+
expect(convertKeysFromCamelToUnderscore({ L123: value })).toEqual({ l123: value });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should handle multi-leveled object', () => {
|
|
27
|
+
const value = Math.random();
|
|
28
|
+
expect(convertKeysFromCamelToUnderscore({ LoremIpsum: { DoloreSit: { Amet: value }, regular: 'reg' } }))
|
|
29
|
+
.toEqual({ lorem_ipsum: { dolore_sit: { amet: value }, regular: 'reg' } });
|
|
30
|
+
|
|
31
|
+
expect(convertKeysFromCamelToUnderscore({ LoremIpsum: { DoloreSit: { Amet: [value] }, regular: ['something'] } }))
|
|
32
|
+
.toEqual({ lorem_ipsum: { dolore_sit: { amet: [value] }, regular: ['something'] } });
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
fixSdp,
|
|
10
10
|
fixBundle,
|
|
11
11
|
toggleVideoDirection,
|
|
12
|
-
hasAnActiveVideo,
|
|
12
|
+
hasAnActiveVideo, addIcesInAllBundles,
|
|
13
13
|
} from '../sdp';
|
|
14
14
|
|
|
15
15
|
const goodSdp = `
|
|
@@ -174,4 +174,36 @@ describe('SDP utils', () => {
|
|
|
174
174
|
expect(hasAnActiveVideo(inactiveVideo)).toBeFalsy();
|
|
175
175
|
});
|
|
176
176
|
});
|
|
177
|
+
|
|
178
|
+
describe('Adding candidate in all bundles ', () => {
|
|
179
|
+
it('should add candidate everywhere', async () => {
|
|
180
|
+
const audioWithoutCandidate = `
|
|
181
|
+
c=IN IP4 203.0.113.1
|
|
182
|
+
m=audio 54400 RTP/SAVPF 0 96
|
|
183
|
+
m=video 54400 RTP/SAVPF 0 96
|
|
184
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
|
185
|
+
a=candidate:3996450952 1 udp 41819903 14.72.21.2 65092 typ relay raddr 0.0.0.0 rport 0 generation 0 network-id 3 network-cost 10
|
|
186
|
+
`;
|
|
187
|
+
const fixedAudioWithoutCandidate = sdpParser.parse(addIcesInAllBundles(audioWithoutCandidate));
|
|
188
|
+
|
|
189
|
+
expect(fixedAudioWithoutCandidate.media[0].candidates[0].type).toBe('host');
|
|
190
|
+
expect(fixedAudioWithoutCandidate.media[0].candidates[1].type).toBe('relay');
|
|
191
|
+
expect(fixedAudioWithoutCandidate.media[1].candidates[0].type).toBe('host');
|
|
192
|
+
expect(fixedAudioWithoutCandidate.media[1].candidates[1].type).toBe('relay');
|
|
193
|
+
|
|
194
|
+
// It should not add candidate if already present
|
|
195
|
+
const audioWithCandidate = `
|
|
196
|
+
c=IN IP4 203.0.113.1
|
|
197
|
+
m=audio 54400 RTP/SAVPF 0 96
|
|
198
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ srflx
|
|
199
|
+
|
|
200
|
+
m=video 54400 RTP/SAVPF 0 96
|
|
201
|
+
a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
|
|
202
|
+
`;
|
|
203
|
+
const fixedAudioWithCandidate = sdpParser.parse(addIcesInAllBundles(audioWithCandidate));
|
|
204
|
+
|
|
205
|
+
expect(fixedAudioWithCandidate.media[0].candidates[0].type).toBe('srflx');
|
|
206
|
+
expect(fixedAudioWithCandidate.media[1].candidates[0].type).toBe('host');
|
|
207
|
+
});
|
|
208
|
+
});
|
|
177
209
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { camelToUnderscore } from '../string';
|
|
2
|
+
|
|
3
|
+
describe('string utils', () => {
|
|
4
|
+
describe('camelToUnderscore', () => {
|
|
5
|
+
it('', () => {
|
|
6
|
+
expect(() => camelToUnderscore(null)).toThrow('Input is not a string');
|
|
7
|
+
expect(() => camelToUnderscore(undefined)).toThrow('Input is not a string');
|
|
8
|
+
expect(() => camelToUnderscore({})).toThrow('Input is not a string');
|
|
9
|
+
expect(() => camelToUnderscore([])).toThrow('Input is not a string');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should convert camel-cased string to underscore', () => {
|
|
13
|
+
expect(camelToUnderscore('loremIpsum')).toEqual('lorem_ipsum');
|
|
14
|
+
expect(camelToUnderscore('lorem-ipsum')).toEqual('lorem-ipsum');
|
|
15
|
+
expect(camelToUnderscore('')).toEqual('');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should not prefix string with an underscore', () => {
|
|
19
|
+
expect(camelToUnderscore('LoremIpsum')).toEqual('lorem_ipsum');
|
|
20
|
+
expect(camelToUnderscore('L123')).toEqual('l123');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import { camelToUnderscore } from './string';
|
|
4
|
+
|
|
5
|
+
export const convertKeysFromCamelToUnderscore = (args: Object) => {
|
|
6
|
+
if (!args || typeof args !== 'object' || Array.isArray(args)) {
|
|
7
|
+
throw new Error('Input is not an object');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return Object.keys(args).reduce((acc, key) => {
|
|
11
|
+
acc[camelToUnderscore(key)] = typeof args[key] === 'object' && !Array.isArray(args[key])
|
|
12
|
+
? convertKeysFromCamelToUnderscore(args[key]) : args[key];
|
|
13
|
+
return acc;
|
|
14
|
+
}, {});
|
|
15
|
+
};
|
package/src/utils/sdp.js
CHANGED
|
@@ -120,3 +120,21 @@ export const fixSdp = (sdp: string, candidates: Object[], forcePort: boolean = t
|
|
|
120
120
|
|
|
121
121
|
return fixed;
|
|
122
122
|
};
|
|
123
|
+
|
|
124
|
+
export const addIcesInAllBundles = (sdp: string) => {
|
|
125
|
+
const parsedSdp = sdpParser.parse(sdp);
|
|
126
|
+
|
|
127
|
+
const mediaWithCandidate = parsedSdp.media.find(media => !!media.candidates);
|
|
128
|
+
if (!mediaWithCandidate) {
|
|
129
|
+
return sdp;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const { candidates } = mediaWithCandidate;
|
|
133
|
+
|
|
134
|
+
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
135
|
+
...media,
|
|
136
|
+
candidates: media.candidates || candidates,
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
return sdpParser.write(parsedSdp);
|
|
140
|
+
};
|
package/src/web-rtc-client.js
CHANGED
|
@@ -1070,41 +1070,58 @@ export default class WebRTCClient extends Emitter {
|
|
|
1070
1070
|
});
|
|
1071
1071
|
}
|
|
1072
1072
|
|
|
1073
|
-
changeAudioInputDevice(id: string, session: ?Inviter) {
|
|
1073
|
+
async changeAudioInputDevice(id: string, session: ?Inviter, force: ?boolean) {
|
|
1074
1074
|
const currentId = this.getAudioDeviceId();
|
|
1075
1075
|
logger.info('setting audio input device', { id, currentId, session: !!session });
|
|
1076
1076
|
|
|
1077
|
-
if (id === currentId) {
|
|
1077
|
+
if (!force && id === currentId) {
|
|
1078
1078
|
return null;
|
|
1079
1079
|
}
|
|
1080
1080
|
|
|
1081
|
+
// in order to handle an audio track change for default devices
|
|
1082
|
+
// we need the actual id of the device (not 'default')
|
|
1083
|
+
let deviceId = id;
|
|
1084
|
+
if (id === 'default' && navigator.mediaDevices) {
|
|
1085
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
1086
|
+
const defaultDevice = devices.find(device => device.deviceId === 'default');
|
|
1087
|
+
if (defaultDevice) {
|
|
1088
|
+
const deviceLabel = defaultDevice.label.replace('Default - ', '');
|
|
1089
|
+
const targetDevice = devices.find(device => device.label === deviceLabel);
|
|
1090
|
+
if (targetDevice) {
|
|
1091
|
+
deviceId = targetDevice.deviceId;
|
|
1092
|
+
if (!force && deviceId === currentId) {
|
|
1093
|
+
return null;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1081
1099
|
// let's update the local audio value
|
|
1082
1100
|
if (this.audio) {
|
|
1083
1101
|
this.audio = {
|
|
1084
1102
|
deviceId: {
|
|
1085
|
-
exact:
|
|
1103
|
+
exact: deviceId,
|
|
1086
1104
|
},
|
|
1087
1105
|
};
|
|
1088
1106
|
}
|
|
1089
1107
|
|
|
1090
|
-
if (session) {
|
|
1108
|
+
if (session && navigator.mediaDevices) {
|
|
1091
1109
|
const sdh = session.sessionDescriptionHandler;
|
|
1092
1110
|
const pc = sdh.peerConnection;
|
|
1093
1111
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1112
|
+
const constraints = { audio: { deviceId: { exact: deviceId } } };
|
|
1113
|
+
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
1114
|
+
const audioTrack = stream.getAudioTracks()[0];
|
|
1115
|
+
const sender = pc && pc.getSenders().find(s => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
|
|
1098
1116
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
}
|
|
1103
|
-
sender.replaceTrack(audioTrack);
|
|
1117
|
+
if (sender) {
|
|
1118
|
+
if (sender.track) {
|
|
1119
|
+
audioTrack.enabled = sender.track.enabled;
|
|
1104
1120
|
}
|
|
1121
|
+
sender.replaceTrack(audioTrack);
|
|
1122
|
+
}
|
|
1105
1123
|
|
|
1106
|
-
|
|
1107
|
-
});
|
|
1124
|
+
return stream;
|
|
1108
1125
|
}
|
|
1109
1126
|
}
|
|
1110
1127
|
|
|
@@ -1124,14 +1141,14 @@ export default class WebRTCClient extends Emitter {
|
|
|
1124
1141
|
return null;
|
|
1125
1142
|
}
|
|
1126
1143
|
|
|
1127
|
-
// let's
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1144
|
+
// let's make sure we don't lose other video constraints settings -- width, height, frameRate...
|
|
1145
|
+
const videoObject = typeof this.video === 'object' ? this.video : {};
|
|
1146
|
+
this.video = {
|
|
1147
|
+
...videoObject,
|
|
1148
|
+
deviceId: {
|
|
1149
|
+
exact: id,
|
|
1150
|
+
},
|
|
1151
|
+
};
|
|
1135
1152
|
}
|
|
1136
1153
|
|
|
1137
1154
|
changeSessionVideoInputDevice(id: ?string, session: Inviter) {
|
package/src/websocket-client.js
CHANGED
|
@@ -94,6 +94,7 @@ export const AGENT_UNPAUSED = 'agent_unpaused';
|
|
|
94
94
|
export const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
|
|
95
95
|
export const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
|
|
96
96
|
export const MEETING_USER_PROGRESS = 'meeting_user_progress';
|
|
97
|
+
export const MEETING_USER_GUEST_AUTHORIZATION_CREATED = 'meeting_user_guest_authorization_created';
|
|
97
98
|
|
|
98
99
|
const BLACKLIST_EVENTS = [
|
|
99
100
|
CHAT_MESSAGE_SENT,
|
|
@@ -448,6 +449,7 @@ WebSocketClient.eventLists = [
|
|
|
448
449
|
CONFERENCE_ADHOC_PARTICIPANT_LEFT,
|
|
449
450
|
CONFERENCE_ADHOC_DELETED,
|
|
450
451
|
MEETING_USER_PROGRESS,
|
|
452
|
+
MEETING_USER_GUEST_AUTHORIZATION_CREATED,
|
|
451
453
|
];
|
|
452
454
|
|
|
453
455
|
export default WebSocketClient;
|