@webex/plugin-meetings 3.9.0-next.1 → 3.9.0-next.11
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +15 -6
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +4 -1
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/meeting/index.js +101 -79
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +29 -21
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +31 -25
- package/dist/meetings/index.js.map +1 -1
- package/dist/members/index.js +3 -2
- package/dist/members/index.js.map +1 -1
- package/dist/members/util.js +7 -2
- package/dist/members/util.js.map +1 -1
- package/dist/reachability/index.js +3 -3
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/locus-info/index.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +1 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
- package/dist/types/meetings/index.d.ts +3 -1
- package/dist/types/members/index.d.ts +2 -1
- package/dist/types/members/util.d.ts +6 -3
- package/dist/webinar/index.js +1 -1
- package/package.json +13 -13
- package/src/locus-info/index.ts +13 -5
- package/src/locus-info/parser.ts +5 -1
- package/src/meeting/index.ts +29 -3
- package/src/meeting-info/meeting-info-v2.ts +24 -5
- package/src/meetings/index.ts +9 -3
- package/src/members/index.ts +9 -2
- package/src/members/util.ts +18 -2
- package/src/reachability/index.ts +3 -3
- package/test/unit/spec/locus-info/index.js +7 -7
- package/test/unit/spec/locus-info/parser.js +3 -2
- package/test/unit/spec/meeting/index.js +96 -22
- package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
- package/test/unit/spec/meetings/index.js +10 -1
- package/test/unit/spec/members/index.js +30 -2
- package/test/unit/spec/members/request.js +55 -0
- package/test/unit/spec/members/utils.js +116 -14
- package/test/unit/spec/reachability/index.ts +158 -3
package/src/locus-info/parser.ts
CHANGED
@@ -728,13 +728,17 @@ export default class Parser {
|
|
728
728
|
break;
|
729
729
|
|
730
730
|
case USE_INCOMING:
|
731
|
-
case LOCUS_URL_CHANGED:
|
732
731
|
// update working copy for future comparisons.
|
733
732
|
// Note: The working copy of parser gets updated in .onFullLocus()
|
734
733
|
// and here when USE_INCOMING or LOCUS_URL_CHANGED locus.
|
735
734
|
this.workingCopy = newLoci;
|
736
735
|
break;
|
737
736
|
|
737
|
+
case LOCUS_URL_CHANGED:
|
738
|
+
// clear the working copy completely, do a full locus sync
|
739
|
+
this.workingCopy = null;
|
740
|
+
break;
|
741
|
+
|
738
742
|
case WAIT:
|
739
743
|
// we've taken newLoci from the front of the queue, so put it back there as we have to wait
|
740
744
|
// for the one that should be in front of it, before we can process it
|
package/src/meeting/index.ts
CHANGED
@@ -269,6 +269,7 @@ export enum ScreenShareFloorStatus {
|
|
269
269
|
type FetchMeetingInfoParams = {
|
270
270
|
password?: string;
|
271
271
|
registrationId?: string;
|
272
|
+
classificationId?: string;
|
272
273
|
captchaCode?: string;
|
273
274
|
extraParams?: Record<string, any>;
|
274
275
|
sendCAevents?: boolean;
|
@@ -1902,6 +1903,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1902
1903
|
extraParams = {},
|
1903
1904
|
sendCAevents = false,
|
1904
1905
|
registrationId = null,
|
1906
|
+
classificationId = null,
|
1905
1907
|
}): Promise<void> {
|
1906
1908
|
try {
|
1907
1909
|
const captchaInfo = captchaCode
|
@@ -1918,7 +1920,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
1918
1920
|
this.locusId,
|
1919
1921
|
extraParams,
|
1920
1922
|
{meetingId: this.id, sendCAevents},
|
1921
|
-
registrationId
|
1923
|
+
registrationId,
|
1924
|
+
null,
|
1925
|
+
classificationId
|
1922
1926
|
);
|
1923
1927
|
|
1924
1928
|
this.parseMeetingInfo(info?.body, this.destination, info?.errors);
|
@@ -3149,6 +3153,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
3149
3153
|
},
|
3150
3154
|
EVENT_TRIGGERS.MEETING_STOPPED_SHARING_WHITEBOARD
|
3151
3155
|
);
|
3156
|
+
// @ts-ignore
|
3157
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp({
|
3158
|
+
key: 'internal.client.share.stopped',
|
3159
|
+
});
|
3160
|
+
// @ts-ignore
|
3161
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
3162
|
+
name: 'client.share.stopped',
|
3163
|
+
payload: {
|
3164
|
+
mediaType: 'whiteboard',
|
3165
|
+
shareDuration:
|
3166
|
+
// @ts-ignore
|
3167
|
+
this.webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration(),
|
3168
|
+
},
|
3169
|
+
options: {
|
3170
|
+
meetingId: this.id,
|
3171
|
+
},
|
3172
|
+
});
|
3152
3173
|
break;
|
3153
3174
|
|
3154
3175
|
case SHARE_STATUS.NO_SHARE:
|
@@ -6948,10 +6969,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
6948
6969
|
}
|
6949
6970
|
}
|
6950
6971
|
|
6951
|
-
// Count members that are in the meeting.
|
6972
|
+
// Count members that are in the meeting or in the lobby.
|
6952
6973
|
const {members} = this.getMembers().membersCollection;
|
6953
6974
|
event.data.intervalMetadata.meetingUserCount = Object.values(members).filter(
|
6954
|
-
(member: Member) => member.isInMeeting
|
6975
|
+
(member: Member) => member.isInMeeting || member.isInLobby
|
6955
6976
|
).length;
|
6956
6977
|
|
6957
6978
|
// @ts-ignore
|
@@ -7819,6 +7840,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7819
7840
|
|
7820
7841
|
this.allowMediaInLobby = options?.allowMediaInLobby;
|
7821
7842
|
|
7843
|
+
// @ts-ignore
|
7844
|
+
const ipver = MeetingUtil.getIpVersion(this.webex); // used just for metrics
|
7845
|
+
|
7822
7846
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
7823
7847
|
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
7824
7848
|
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
@@ -7917,6 +7941,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7917
7941
|
locus_id: this.locusUrl.split('/').pop(),
|
7918
7942
|
connectionType,
|
7919
7943
|
ipVersion,
|
7944
|
+
ipver,
|
7920
7945
|
selectedCandidatePairChanges,
|
7921
7946
|
numTransports,
|
7922
7947
|
isMultistream: this.isMultistream,
|
@@ -7985,6 +8010,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
7985
8010
|
...reachabilityMetrics,
|
7986
8011
|
...iceCandidateErrors,
|
7987
8012
|
iceCandidatesCount: this.iceCandidatesCount,
|
8013
|
+
ipver,
|
7988
8014
|
});
|
7989
8015
|
|
7990
8016
|
await this.cleanUpOnAddMediaFailure();
|
@@ -371,6 +371,7 @@ export default class MeetingInfoV2 {
|
|
371
371
|
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
|
372
372
|
* @param {String} installedOrgID org ID of user's machine
|
373
373
|
* @param {Boolean} enableStaticMeetingLink whether or not to enable static meeting link
|
374
|
+
* @param {String} classificationId need it to start adhoc meeting if space support classification
|
374
375
|
* @returns {Promise} returns a meeting info object
|
375
376
|
* @public
|
376
377
|
* @memberof MeetingInfo
|
@@ -379,7 +380,8 @@ export default class MeetingInfoV2 {
|
|
379
380
|
conversationUrl: string,
|
380
381
|
installedOrgID?: string,
|
381
382
|
// setting this to true enables static meeting link
|
382
|
-
enableStaticMeetingLink = false
|
383
|
+
enableStaticMeetingLink = false,
|
384
|
+
classificationId = undefined
|
383
385
|
) {
|
384
386
|
const getInvitees = (particpants = []) => {
|
385
387
|
const invitees = [];
|
@@ -407,6 +409,7 @@ export default class MeetingInfoV2 {
|
|
407
409
|
invitees: getInvitees(conversation.participants?.items),
|
408
410
|
installedOrgID,
|
409
411
|
schedule: enableStaticMeetingLink,
|
412
|
+
classificationId,
|
410
413
|
};
|
411
414
|
|
412
415
|
if (installedOrgID) {
|
@@ -429,16 +432,26 @@ export default class MeetingInfoV2 {
|
|
429
432
|
* Creates adhoc space meetings for a space by fetching the conversation infomation
|
430
433
|
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
|
431
434
|
* @param {String} installedOrgID org ID of user's machine
|
435
|
+
* @param {String} classificationId if space is support classification, it needs provide it during start instant meeting
|
432
436
|
* @returns {Promise} returns a meeting info object
|
433
437
|
* @public
|
434
438
|
* @memberof MeetingInfo
|
435
439
|
*/
|
436
|
-
async createAdhocSpaceMeeting(
|
440
|
+
async createAdhocSpaceMeeting(
|
441
|
+
conversationUrl: string,
|
442
|
+
installedOrgID?: string,
|
443
|
+
classificationId?: string
|
444
|
+
) {
|
437
445
|
if (!this.webex.meetings.preferredWebexSite) {
|
438
446
|
throw Error('No preferred webex site found');
|
439
447
|
}
|
440
448
|
|
441
|
-
return this.createAdhocSpaceMeetingOrEnableStaticMeetingLink(
|
449
|
+
return this.createAdhocSpaceMeetingOrEnableStaticMeetingLink(
|
450
|
+
conversationUrl,
|
451
|
+
installedOrgID,
|
452
|
+
false,
|
453
|
+
classificationId
|
454
|
+
)
|
442
455
|
.then((requestResult) => {
|
443
456
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS);
|
444
457
|
|
@@ -618,6 +631,7 @@ export default class MeetingInfoV2 {
|
|
618
631
|
* @param {Object} options
|
619
632
|
* @param {String} registrationId
|
620
633
|
* @param {String} fullSiteUrl
|
634
|
+
* @param {String} classificationId
|
621
635
|
* @returns {Promise} returns a meeting info object
|
622
636
|
* @public
|
623
637
|
* @memberof MeetingInfo
|
@@ -635,7 +649,8 @@ export default class MeetingInfoV2 {
|
|
635
649
|
extraParams: object = {},
|
636
650
|
options: {meetingId?: string; sendCAevents?: boolean} = {},
|
637
651
|
registrationId: string = null,
|
638
|
-
fullSiteUrl: string = null
|
652
|
+
fullSiteUrl: string = null,
|
653
|
+
classificationId: string = null
|
639
654
|
) {
|
640
655
|
const {meetingId, sendCAevents} = options;
|
641
656
|
|
@@ -650,7 +665,11 @@ export default class MeetingInfoV2 {
|
|
650
665
|
this.webex.config.meetings.experimental.enableAdhocMeetings &&
|
651
666
|
this.webex.meetings.preferredWebexSite
|
652
667
|
) {
|
653
|
-
return this.createAdhocSpaceMeeting(
|
668
|
+
return this.createAdhocSpaceMeeting(
|
669
|
+
destinationType.destination,
|
670
|
+
installedOrgID,
|
671
|
+
classificationId
|
672
|
+
);
|
654
673
|
}
|
655
674
|
|
656
675
|
const body = await MeetingInfoUtil.getRequestBody({
|
package/src/meetings/index.ts
CHANGED
@@ -1331,6 +1331,7 @@ export default class Meetings extends WebexPlugin {
|
|
1331
1331
|
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
1332
1332
|
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
1333
1333
|
* @param {string} sessionCorrelationId - the optional specified sessionCorrelationId (callStateForMetrics.sessionCorrelationId) can be provided instead
|
1334
|
+
* @param {String} classificationId - If space support classification, it will provide it while start instant meeting
|
1334
1335
|
* @returns {Promise<Meeting>} A new Meeting.
|
1335
1336
|
* @public
|
1336
1337
|
* @memberof Meetings
|
@@ -1345,7 +1346,8 @@ export default class Meetings extends WebexPlugin {
|
|
1345
1346
|
callStateForMetrics: CallStateForMetrics = undefined,
|
1346
1347
|
meetingInfo = undefined,
|
1347
1348
|
meetingLookupUrl = undefined,
|
1348
|
-
sessionCorrelationId: string = undefined
|
1349
|
+
sessionCorrelationId: string = undefined,
|
1350
|
+
classificationId: string = undefined
|
1349
1351
|
) {
|
1350
1352
|
// Validate meeting information based on the provided destination and
|
1351
1353
|
// type. This must be performed prior to determining if the meeting is
|
@@ -1415,7 +1417,8 @@ export default class Meetings extends WebexPlugin {
|
|
1415
1417
|
callStateForMetrics,
|
1416
1418
|
failOnMissingMeetingInfo,
|
1417
1419
|
meetingInfo,
|
1418
|
-
meetingLookupUrl
|
1420
|
+
meetingLookupUrl,
|
1421
|
+
classificationId
|
1419
1422
|
).then((createdMeeting: any) => {
|
1420
1423
|
// If the meeting was successfully created.
|
1421
1424
|
if (createdMeeting && createdMeeting.on) {
|
@@ -1529,6 +1532,7 @@ export default class Meetings extends WebexPlugin {
|
|
1529
1532
|
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
1530
1533
|
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
1531
1534
|
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
1535
|
+
* @param {String} classificationId see create()
|
1532
1536
|
* @returns {Promise} a new meeting instance complete with meeting info and destination
|
1533
1537
|
* @private
|
1534
1538
|
* @memberof Meetings
|
@@ -1541,7 +1545,8 @@ export default class Meetings extends WebexPlugin {
|
|
1541
1545
|
callStateForMetrics: CallStateForMetrics = undefined,
|
1542
1546
|
failOnMissingMeetingInfo = false,
|
1543
1547
|
meetingInfo = undefined,
|
1544
|
-
meetingLookupUrl = undefined
|
1548
|
+
meetingLookupUrl = undefined,
|
1549
|
+
classificationId = undefined
|
1545
1550
|
) {
|
1546
1551
|
const meeting = new Meeting(
|
1547
1552
|
{
|
@@ -1589,6 +1594,7 @@ export default class Meetings extends WebexPlugin {
|
|
1589
1594
|
// @ts-ignore
|
1590
1595
|
const {enableUnifiedMeetings} = this.config.experimental;
|
1591
1596
|
const meetingInfoOptions = {
|
1597
|
+
classificationId,
|
1592
1598
|
extraParams: infoExtraParams,
|
1593
1599
|
sendCAevents: !!callStateForMetrics?.correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
|
1594
1600
|
};
|
package/src/members/index.ts
CHANGED
@@ -1181,11 +1181,17 @@ export default class Members extends StatelessWebexPlugin {
|
|
1181
1181
|
* @param {string} memberId - id of the participant who is receiving request
|
1182
1182
|
* @param {string} requestingParticipantId - id of the participant who is sending request (optional)
|
1183
1183
|
* @param {string} [alias] - alias name
|
1184
|
+
* @param {string} [suffix] - name suffix (optional)
|
1184
1185
|
* @returns {Promise}
|
1185
1186
|
* @public
|
1186
1187
|
* @memberof Members
|
1187
1188
|
*/
|
1188
|
-
public editDisplayName(
|
1189
|
+
public editDisplayName(
|
1190
|
+
memberId: string,
|
1191
|
+
requestingParticipantId: string,
|
1192
|
+
alias: string,
|
1193
|
+
suffix?: string
|
1194
|
+
) {
|
1189
1195
|
if (!this.locusUrl) {
|
1190
1196
|
return Promise.reject(
|
1191
1197
|
new ParameterError(
|
@@ -1205,7 +1211,8 @@ export default class Members extends StatelessWebexPlugin {
|
|
1205
1211
|
memberId,
|
1206
1212
|
requestingParticipantId,
|
1207
1213
|
alias,
|
1208
|
-
locusUrl
|
1214
|
+
locusUrl,
|
1215
|
+
suffix
|
1209
1216
|
);
|
1210
1217
|
|
1211
1218
|
return this.membersRequest.editDisplayNameMember(options);
|
package/src/members/util.ts
CHANGED
@@ -190,13 +190,21 @@ const MembersUtil = {
|
|
190
190
|
* @param {String} requestingParticipantId id of the participant who is sending request (optional)
|
191
191
|
* @param {String} alias alias name
|
192
192
|
* @param {String} locusUrl url
|
193
|
+
* @param {String} suffix optional suffix
|
193
194
|
* @returns {Object} consists of {memberID: string, requestingParticipantId: string, alias: string, locusUrl: string}
|
194
195
|
*/
|
195
|
-
generateEditDisplayNameMemberOptions: (
|
196
|
+
generateEditDisplayNameMemberOptions: (
|
196
197
|
memberId,
|
197
198
|
requestingParticipantId,
|
198
199
|
alias,
|
199
200
|
locusUrl,
|
201
|
+
suffix
|
202
|
+
) => ({
|
203
|
+
memberId,
|
204
|
+
requestingParticipantId,
|
205
|
+
alias,
|
206
|
+
locusUrl,
|
207
|
+
suffix,
|
200
208
|
}),
|
201
209
|
|
202
210
|
getMuteMemberRequestParams: (options) => {
|
@@ -301,10 +309,18 @@ const MembersUtil = {
|
|
301
309
|
* @returns {Object} request parameters (method, uri, body) needed to make a editDisplayName request
|
302
310
|
*/
|
303
311
|
editDisplayNameMemberRequestParams: (options) => {
|
304
|
-
const body
|
312
|
+
const body: {
|
313
|
+
aliasValue: string;
|
314
|
+
requestingParticipantId: string;
|
315
|
+
suffixValue?: string;
|
316
|
+
} = {
|
305
317
|
aliasValue: options.alias,
|
306
318
|
requestingParticipantId: options.requestingParticipantId,
|
307
319
|
};
|
320
|
+
|
321
|
+
if (options.suffix !== undefined) {
|
322
|
+
body.suffixValue = options.suffix;
|
323
|
+
}
|
308
324
|
const uri = `${options.locusUrl}/${PARTICIPANT}/${options.memberId}/${ALIAS}`;
|
309
325
|
|
310
326
|
return {
|
@@ -923,10 +923,10 @@ export default class Reachability extends EventsScope {
|
|
923
923
|
|
924
924
|
// update expected results counters to include this cluster
|
925
925
|
this.expectedResultsCount[cluster.isVideoMesh ? 'videoMesh' : 'public'].udp +=
|
926
|
-
cluster.udp.length;
|
926
|
+
cluster.udp.length > 0 ? 1 : 0;
|
927
927
|
if (!cluster.isVideoMesh) {
|
928
|
-
this.expectedResultsCount.public.tcp += cluster.tcp.length;
|
929
|
-
this.expectedResultsCount.public.xtls += cluster.xtls.length;
|
928
|
+
this.expectedResultsCount.public.tcp += cluster.tcp.length > 0 ? 1 : 0;
|
929
|
+
this.expectedResultsCount.public.xtls += cluster.xtls.length > 0 ? 1 : 0;
|
930
930
|
}
|
931
931
|
});
|
932
932
|
|
@@ -2369,23 +2369,23 @@ describe('plugin-meetings', () => {
|
|
2369
2369
|
|
2370
2370
|
it('applyLocusDeltaData handles LOCUS_URL_CHANGED action correctly', () => {
|
2371
2371
|
const {LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
|
2372
|
-
const
|
2372
|
+
const fakeFullLocus = {
|
2373
|
+
url: 'new full loci url',
|
2374
|
+
};
|
2373
2375
|
const meeting = {
|
2374
2376
|
meetingRequest: {
|
2375
|
-
getLocusDTO: sandbox.stub().resolves({body:
|
2377
|
+
getLocusDTO: sandbox.stub().resolves({body: fakeFullLocus}),
|
2376
2378
|
},
|
2377
2379
|
locusInfo: {
|
2378
2380
|
handleLocusDelta: sandbox.stub(),
|
2379
2381
|
},
|
2380
|
-
locusUrl: 'current locus url',
|
2382
|
+
locusUrl: 'current BO session locus url',
|
2381
2383
|
};
|
2382
2384
|
|
2383
|
-
locusInfo.locusParser.workingCopy =
|
2384
|
-
syncUrl: 'current sync url',
|
2385
|
-
};
|
2385
|
+
locusInfo.locusParser.workingCopy = null;
|
2386
2386
|
|
2387
2387
|
locusInfo.applyLocusDeltaData(LOCUS_URL_CHANGED, fakeLocus, meeting);
|
2388
|
-
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url:
|
2388
|
+
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: fakeLocus.url});
|
2389
2389
|
});
|
2390
2390
|
|
2391
2391
|
describe('edge cases for sync failing', () => {
|
@@ -253,7 +253,8 @@ describe('locus-info/parser', () => {
|
|
253
253
|
});
|
254
254
|
|
255
255
|
it('replaces current loci when the locus URL changes and incoming sequence is later, even when baseSequence doesn\'t match', () => {
|
256
|
-
const {
|
256
|
+
const {LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
|
257
|
+
sandbox.stub(LocusDeltaParser, 'compare').returns(LOCUS_URL_CHANGED);
|
257
258
|
|
258
259
|
parser.queue.dequeue = sandbox.stub().returns(NEW_LOCI);
|
259
260
|
parser.onDeltaAction = sandbox.stub();
|
@@ -262,7 +263,7 @@ describe('locus-info/parser', () => {
|
|
262
263
|
|
263
264
|
parser.processDeltaEvent();
|
264
265
|
|
265
|
-
assert.equal(parser.workingCopy,
|
266
|
+
assert.equal(parser.workingCopy, null);
|
266
267
|
});
|
267
268
|
|
268
269
|
it('does not replace current loci when the locus URL changes but incoming sequence is not later', () => {
|