@webex/internal-plugin-metrics 3.0.0-beta.212 → 3.0.0-beta.213

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.
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
+ var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
5
+ var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
6
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
7
+ var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
8
+ var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
4
9
  var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
5
10
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
6
11
  _Object$defineProperty(exports, "__esModule", {
@@ -25,6 +30,8 @@ var _callDiagnosticMetrics = require("./call-diagnostic-metrics.util");
25
30
  var _config = require("../config");
26
31
  var _callDiagnosticMetricsBatcher = _interopRequireDefault(require("./call-diagnostic-metrics-batcher"));
27
32
  var _config2 = require("./config");
33
+ function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
34
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
28
35
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
29
36
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
30
37
  var _BrowserDetection = (0, _common.BrowserDetection)(),
@@ -75,6 +82,23 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
75
82
  return null;
76
83
  }
77
84
 
85
+ /**
86
+ * Returns if the meeting has converged architecture enabled
87
+ * @param options.meetingId
88
+ */
89
+ }, {
90
+ key: "getIsConvergedArchitectureEnabled",
91
+ value: function getIsConvergedArchitectureEnabled(_ref) {
92
+ var meetingId = _ref.meetingId;
93
+ if (meetingId) {
94
+ var _meeting$meetingInfo;
95
+ // @ts-ignore
96
+ var meeting = this.webex.meetings.meetingCollection.get(meetingId);
97
+ return meeting === null || meeting === void 0 ? void 0 : (_meeting$meetingInfo = meeting.meetingInfo) === null || _meeting$meetingInfo === void 0 ? void 0 : _meeting$meetingInfo.enableConvergedArchitecture;
98
+ }
99
+ return undefined;
100
+ }
101
+
78
102
  /**
79
103
  * Get origin object for Call Diagnostic Event payload.
80
104
  * @param options
@@ -84,35 +108,45 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
84
108
  }, {
85
109
  key: "getOrigin",
86
110
  value: function getOrigin(options, meetingId) {
87
- var _this$webex$meetings$, _this$webex$meetings$2, _this$webex$meetings$3, _this$webex$meetings$4;
111
+ var _this$webex$meetings$, _this$webex$meetings$2, _this$webex$meetings$3, _this$webex$meetings$4, _this$webex$meetings$5, _this$webex$meetings$6;
88
112
  var defaultClientType = // @ts-ignore
89
113
  (_this$webex$meetings$ = this.webex.meetings.config) === null || _this$webex$meetings$ === void 0 ? void 0 : (_this$webex$meetings$2 = _this$webex$meetings$.metrics) === null || _this$webex$meetings$2 === void 0 ? void 0 : _this$webex$meetings$2.clientType;
90
114
  var defaultSubClientType = // @ts-ignore
91
115
  (_this$webex$meetings$3 = this.webex.meetings.config) === null || _this$webex$meetings$3 === void 0 ? void 0 : (_this$webex$meetings$4 = _this$webex$meetings$3.metrics) === null || _this$webex$meetings$4 === void 0 ? void 0 : _this$webex$meetings$4.subClientType;
116
+ // @ts-ignore
117
+ var providedClientVersion = (_this$webex$meetings$5 = this.webex.meetings.config) === null || _this$webex$meetings$5 === void 0 ? void 0 : (_this$webex$meetings$6 = _this$webex$meetings$5.metrics) === null || _this$webex$meetings$6 === void 0 ? void 0 : _this$webex$meetings$6.clientVersion;
118
+ // @ts-ignore
119
+ var defaultSDKClientVersion = "".concat(_config.CLIENT_NAME, "/").concat(this.webex.version);
120
+ var versionMetadata = {};
121
+
122
+ // sdk version split doesn't really make sense for now...
123
+ if (providedClientVersion) {
124
+ versionMetadata = (0, _callDiagnosticMetrics.extractVersionMetadata)(providedClientVersion);
125
+ }
92
126
  if (defaultClientType && defaultSubClientType || options.clientType && options.subClientType) {
93
- var _this$webex$meetings, _this$webex$meetings$5, _this$webex$meetings$6;
127
+ var _this$webex$meetings, _this$webex$meetings$7, _this$webex$meetings$8;
94
128
  var origin = {
95
129
  name: 'endpoint',
96
130
  networkType: (options === null || options === void 0 ? void 0 : options.networkType) || 'unknown',
97
131
  userAgent: (0, _callDiagnosticMetrics.userAgentToString)({
98
132
  // @ts-ignore
99
- clientName: (_this$webex$meetings = this.webex.meetings) === null || _this$webex$meetings === void 0 ? void 0 : (_this$webex$meetings$5 = _this$webex$meetings.metrics) === null || _this$webex$meetings$5 === void 0 ? void 0 : _this$webex$meetings$5.clientName,
133
+ clientName: (_this$webex$meetings = this.webex.meetings) === null || _this$webex$meetings === void 0 ? void 0 : (_this$webex$meetings$7 = _this$webex$meetings.metrics) === null || _this$webex$meetings$7 === void 0 ? void 0 : _this$webex$meetings$7.clientName,
100
134
  // @ts-ignore
101
135
  webexVersion: this.webex.version
102
136
  }),
103
- clientInfo: {
137
+ clientInfo: _objectSpread(_objectSpread({
104
138
  clientType: (options === null || options === void 0 ? void 0 : options.clientType) || defaultClientType,
105
- // @ts-ignore
106
- clientVersion: "".concat(_config.CLIENT_NAME, "/").concat(this.webex.version),
139
+ clientVersion: providedClientVersion || defaultSDKClientVersion
140
+ }, versionMetadata), {}, {
107
141
  localNetworkPrefix:
108
142
  // @ts-ignore
109
- (0, _callDiagnosticMetrics.anonymizeIPAddress)((_this$webex$meetings$6 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$6 === void 0 ? void 0 : _this$webex$meetings$6.clientAddress) || undefined,
143
+ (0, _callDiagnosticMetrics.anonymizeIPAddress)((_this$webex$meetings$8 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$8 === void 0 ? void 0 : _this$webex$meetings$8.clientAddress) || undefined,
110
144
  osVersion: getOSVersion() || 'unknown',
111
145
  subClientType: (options === null || options === void 0 ? void 0 : options.subClientType) || defaultSubClientType,
112
146
  os: (0, _internalPluginMetrics.getOSNameInternal)(),
113
147
  browser: getBrowserName(),
114
148
  browserVersion: getBrowserVersion()
115
- }
149
+ })
116
150
  };
117
151
  if (meetingId) {
118
152
  // @ts-ignore
@@ -183,7 +217,7 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
183
217
  }, {
184
218
  key: "prepareDiagnosticEvent",
185
219
  value: function prepareDiagnosticEvent(eventData, options) {
186
- var _this$webex$meetings$7;
220
+ var _this$webex$meetings$9;
187
221
  var meetingId = options.meetingId;
188
222
  var origin = this.getOrigin(options, meetingId);
189
223
  var event = {
@@ -196,7 +230,7 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
196
230
  sent: 'not_defined_yet'
197
231
  },
198
232
  // @ts-ignore
199
- senderCountryCode: (_this$webex$meetings$7 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$7 === void 0 ? void 0 : _this$webex$meetings$7.countryCode,
233
+ senderCountryCode: (_this$webex$meetings$9 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$9 === void 0 ? void 0 : _this$webex$meetings$9.countryCode,
200
234
  event: eventData
201
235
  };
202
236
 
@@ -229,10 +263,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
229
263
  */
230
264
  }, {
231
265
  key: "submitMQE",
232
- value: function submitMQE(_ref) {
233
- var name = _ref.name,
234
- payload = _ref.payload,
235
- options = _ref.options;
266
+ value: function submitMQE(_ref2) {
267
+ var name = _ref2.name,
268
+ payload = _ref2.payload,
269
+ options = _ref2.options;
236
270
  var meetingId = options.meetingId,
237
271
  mediaConnections = options.mediaConnections;
238
272
 
@@ -297,9 +331,9 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
297
331
  */
298
332
  }, {
299
333
  key: "getErrorPayloadForClientErrorCode",
300
- value: function getErrorPayloadForClientErrorCode(_ref2) {
301
- var clientErrorCode = _ref2.clientErrorCode,
302
- serviceErrorCode = _ref2.serviceErrorCode;
334
+ value: function getErrorPayloadForClientErrorCode(_ref3) {
335
+ var clientErrorCode = _ref3.clientErrorCode,
336
+ serviceErrorCode = _ref3.serviceErrorCode;
303
337
  var error;
304
338
  if (clientErrorCode) {
305
339
  var partialParsedError = _config2.CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];
@@ -366,9 +400,9 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
366
400
  */
367
401
  }, {
368
402
  key: "createClientEventObjectInMeeting",
369
- value: function createClientEventObjectInMeeting(_ref3) {
370
- var name = _ref3.name,
371
- options = _ref3.options;
403
+ value: function createClientEventObjectInMeeting(_ref4) {
404
+ var name = _ref4.name,
405
+ options = _ref4.options;
372
406
  var meetingId = options.meetingId,
373
407
  mediaConnections = options.mediaConnections,
374
408
  rawError = options.rawError;
@@ -412,7 +446,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
412
446
  webClientDomain: window.location.hostname
413
447
  },
414
448
  userType: meeting.getCurUserType(),
415
- loginType: this.getCurLoginType()
449
+ loginType: this.getCurLoginType(),
450
+ isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({
451
+ meetingId: meetingId
452
+ })
416
453
  };
417
454
  return clientEventObject;
418
455
  }
@@ -426,9 +463,9 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
426
463
  */
427
464
  }, {
428
465
  key: "createClientEventObjectPreMeeting",
429
- value: function createClientEventObjectPreMeeting(_ref4) {
430
- var name = _ref4.name,
431
- options = _ref4.options;
466
+ value: function createClientEventObjectPreMeeting(_ref5) {
467
+ var name = _ref5.name,
468
+ options = _ref5.options;
432
469
  var correlationId = options.correlationId;
433
470
 
434
471
  // grab identifiers
@@ -460,10 +497,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
460
497
  */
461
498
  }, {
462
499
  key: "prepareClientEvent",
463
- value: function prepareClientEvent(_ref5) {
464
- var name = _ref5.name,
465
- payload = _ref5.payload,
466
- options = _ref5.options;
500
+ value: function prepareClientEvent(_ref6) {
501
+ var name = _ref6.name,
502
+ payload = _ref6.payload,
503
+ options = _ref6.options;
467
504
  var meetingId = options.meetingId,
468
505
  correlationId = options.correlationId;
469
506
  var clientEventObject;
@@ -502,10 +539,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
502
539
  */
503
540
  }, {
504
541
  key: "submitClientEvent",
505
- value: function submitClientEvent(_ref6) {
506
- var name = _ref6.name,
507
- payload = _ref6.payload,
508
- options = _ref6.options;
542
+ value: function submitClientEvent(_ref7) {
543
+ var name = _ref7.name,
544
+ payload = _ref7.payload,
545
+ options = _ref7.options;
509
546
  var diagnosticEvent = this.prepareClientEvent({
510
547
  name: name,
511
548
  payload: payload,
@@ -542,12 +579,12 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
542
579
  }, {
543
580
  key: "buildClientEventFetchRequestOptions",
544
581
  value: function () {
545
- var _buildClientEventFetchRequestOptions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref7) {
582
+ var _buildClientEventFetchRequestOptions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref8) {
546
583
  var name, payload, options, clientEvent, diagnosticEvent;
547
584
  return _regenerator.default.wrap(function _callee$(_context) {
548
585
  while (1) switch (_context.prev = _context.next) {
549
586
  case 0:
550
- name = _ref7.name, payload = _ref7.payload, options = _ref7.options;
587
+ name = _ref8.name, payload = _ref8.payload, options = _ref8.options;
551
588
  clientEvent = this.prepareClientEvent({
552
589
  name: name,
553
590
  payload: payload,
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","webex","canAuthorize","credentials","isUnverifiedGuest","options","meetingId","defaultClientType","meetings","config","metrics","clientType","defaultSubClientType","subClientType","origin","name","networkType","userAgent","userAgentToString","clientName","webexVersion","version","clientInfo","clientVersion","CLIENT_NAME","localNetworkPrefix","anonymizeIPAddress","geoHintInfo","clientAddress","undefined","osVersion","os","getOSNameInternal","browser","browserVersion","meeting","meetingCollection","get","environment","Error","mediaConnections","correlationId","identifiers","internal","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","event","eventId","uuid","v4","originTime","triggered","Date","toISOString","sent","senderCountryCode","countryCode","clearEmptyKeysRecursively","payload","console","warn","submitClientMetrics","CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND","fields","getIdentifiers","clientEventObject","canProceed","webClientDomain","window","location","hostname","intervals","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","diagnosticEvent","prepareDiagnosticEvent","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","rawError","body","code","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","getErrorPayloadForClientErrorCode","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","errors","generatedError","generateClientEventErrorPayload","push","userType","getCurUserType","loginType","getCurLoginType","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","finalEvent","eventPayload","type","request","clientEvent","prepareDiagnosticMetricItem","prepareFetchOptions","method","service","resource","StatelessWebexPlugin"],"sources":["call-diagnostic-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport {BrowserDetection} from '@webex/common';\nimport uuid from 'uuid';\nimport {merge} from 'lodash';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {\n anonymizeIPAddress,\n clearEmptyKeysRecursively,\n isLocusServiceErrorCode,\n prepareDiagnosticMetricItem,\n userAgentToString,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n RecursivePartial,\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientEventError,\n ClientEventPayload,\n} from '../metrics.types';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';\nimport {\n CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,\n CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n} from './config';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n};\n\n/**\n * @description Util class to handle Call Analyzer Metrics\n * @export\n * @class CallDiagnosticMetrics\n */\nexport default class CallDiagnosticMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.callDiagnosticEventsBatcher = new CallDiagnosticEventsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the login type of the current user\n * @returns one of 'login-ci','unverified-guest', null\n */\n getCurLoginType() {\n // @ts-ignore\n if (this.webex.canAuthorize) {\n // @ts-ignore\n return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';\n }\n\n return null;\n }\n\n /**\n * Get origin object for Call Diagnostic Event payload.\n * @param options\n * @param meetingId\n * @returns\n */\n getOrigin(options: GetOriginOptions, meetingId?: string) {\n const defaultClientType: ClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.clientType;\n const defaultSubClientType: SubClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.subClientType;\n\n if (\n (defaultClientType && defaultSubClientType) ||\n (options.clientType && options.subClientType)\n ) {\n const origin: Event['origin'] = {\n name: 'endpoint',\n networkType: options?.networkType || 'unknown',\n userAgent: userAgentToString({\n // @ts-ignore\n clientName: this.webex.meetings?.metrics?.clientName,\n // @ts-ignore\n webexVersion: this.webex.version,\n }),\n clientInfo: {\n clientType: options?.clientType || defaultClientType,\n // @ts-ignore\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix:\n // @ts-ignore\n anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,\n osVersion: getOSVersion() || 'unknown',\n subClientType: options?.subClientType || defaultSubClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n };\n\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n if (meeting?.environment) {\n origin.environment = meeting.environment;\n }\n }\n\n return origin;\n }\n\n throw new Error(\"ClientType and SubClientType can't be undefined\");\n }\n\n /**\n * Gather identifier details for call diagnostic payload.\n * @throws Error if initialization fails.\n * @param options\n */\n getIdentifiers(options: GetIdentifiersOptions) {\n const {meeting, mediaConnections, correlationId} = options;\n const identifiers: Event['event']['identifiers'] = {correlationId: 'unknown'};\n\n if (meeting) {\n identifiers.correlationId = meeting.correlationId;\n }\n\n if (correlationId) {\n identifiers.correlationId = correlationId;\n }\n // @ts-ignore\n if (this.webex.internal) {\n // @ts-ignore\n const {device} = this.webex.internal;\n identifiers.userId = device.userId;\n identifiers.deviceId = device.url;\n identifiers.orgId = device.orgId;\n // @ts-ignore\n identifiers.locusUrl = this.webex.internal.services.get('locus');\n }\n\n if (meeting?.locusInfo?.fullState) {\n identifiers.locusUrl = meeting.locusUrl;\n identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();\n identifiers.locusStartTime =\n meeting.locusInfo.fullState && meeting.locusInfo.fullState.lastActive;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (identifiers.correlationId === undefined) {\n throw new Error('Identifiers initialization failed.');\n }\n\n return identifiers;\n }\n\n /**\n * Create diagnostic event, which can hold client event, feature event or MQE event data.\n * This just initiates the shared properties that are required for all the 3 event categories.\n * @param eventData\n * @param options\n * @returns\n */\n prepareDiagnosticEvent(eventData: Event['event'], options: any) {\n const {meetingId} = options;\n const origin = this.getOrigin(options, meetingId);\n\n const event: Event = {\n eventId: uuid.v4(),\n version: 1,\n origin,\n originTime: {\n triggered: new Date().toISOString(),\n // is overridden in prepareRequest batcher\n sent: 'not_defined_yet',\n },\n // @ts-ignore\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: eventData,\n };\n\n // sanitize (remove empty properties, CA requires it)\n // but we don't want to sanitize MQE as most of the times\n // values will be 0, [] etc, and they are required.\n if (eventData.name !== 'client.mediaquality.event') {\n clearEmptyKeysRecursively(event);\n }\n\n return event;\n }\n\n /**\n * TODO: NOT IMPLEMENTED\n * Submit Feature Event\n * @returns\n */\n public submitFeatureEvent() {\n throw Error('Not implemented');\n }\n\n /**\n * Submit Media Quality Event\n * @param args - submit params\n * @param arg.name - event key\n * @param arg.payload - additional payload to be merge with the default payload\n * @param arg.options - options\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: SubmitMQEOptions;\n }) {\n const {meetingId, mediaConnections} = options;\n\n // events that will most likely happen in join phase\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send MQE but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return;\n }\n\n // merge identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting.mediaConnections || mediaConnections,\n });\n\n // create media quality event object\n let clientEventObject: MediaQualityEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n intervals: payload.intervals,\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n // @ts-ignore\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || 'unknown',\n startTime: new Date().toISOString(),\n },\n };\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append media quality event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n this.submitToCallDiagnostics(diagnosticEvent);\n } else {\n throw new Error(\n 'Media quality events cant be sent outside the context of a meeting. Meeting id is required.'\n );\n }\n }\n\n /**\n * Return Client Event payload by client error code\n * @param arg - get error arg\n * @param arg.clientErrorCode\n * @param arg.serviceErrorCode\n * @returns\n */\n public getErrorPayloadForClientErrorCode({\n clientErrorCode,\n serviceErrorCode,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n }): ClientEventError {\n let error: ClientEventError;\n\n if (clientErrorCode) {\n const partialParsedError = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n if (partialParsedError) {\n error = merge(\n {fatal: true, shownToUser: false, name: 'other', category: 'other'}, // default values\n {errorCode: clientErrorCode},\n {serviceErrorCode},\n partialParsedError\n );\n\n return error;\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate error payload for Client Event\n * @param rawError\n */\n generateClientEventErrorPayload(rawError: any) {\n const serviceErrorCode = rawError?.body?.errorCode || rawError?.body?.code;\n if (serviceErrorCode) {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n if (clientErrorCode) {\n return this.getErrorPayloadForClientErrorCode({clientErrorCode, serviceErrorCode});\n }\n\n // by default, if it is locus error, return nre locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n // otherwise return meeting info\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n return undefined;\n }\n\n /**\n * Create client event object for in meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - options\n * @returns object\n */\n private createClientEventObjectInMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, mediaConnections, rawError} = options;\n\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send client event but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return undefined;\n }\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting?.mediaConnections || mediaConnections,\n });\n\n // check if we need to generate errors\n const errors: ClientEvent['payload']['errors'] = [];\n\n if (rawError) {\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n }\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n errors,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n userType: meeting.getCurUserType(),\n loginType: this.getCurLoginType(),\n };\n\n return clientEventObject;\n }\n\n /**\n * Create client event object for pre meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - payload\n * @returns object\n */\n private createClientEventObjectPreMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {correlationId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n return clientEventObject;\n }\n\n /**\n * Prepare Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @returns {any} options to be with fetch\n * @throws\n */\n private prepareClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, correlationId} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options});\n } else {\n throw new Error('Not implemented');\n }\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append client event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n\n return diagnosticEvent;\n }\n\n /**\n * Submit Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @throws\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n return this.submitToCallDiagnostics(diagnosticEvent);\n }\n\n /**\n * Prepare the event and send the request to metrics-a service.\n * @param event\n * @returns promise\n */\n submitToCallDiagnostics(event: Event): Promise<any> {\n // build metrics-a event type\n const finalEvent = {\n eventPayload: event,\n type: ['diagnostic-event'],\n };\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Builds a request options object to later be passed to fetch().\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - client event options\n * @returns {Promise<any>}\n * @throws\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n const clientEvent = this.prepareClientEvent({name, payload, options});\n\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: clientEvent,\n type: ['diagnostic-event'],\n });\n\n // @ts-ignore\n return this.webex.prepareFetchOptions({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAGA;AACA;AACA;AAEA;AAEA;AAOA;AAeA;AACA;AAMkB;AAAA;AAElB,wBAA0D,IAAAA,wBAAgB,GAAE;EAArEC,YAAY,qBAAZA,YAAY;EAAEC,cAAc,qBAAdA,cAAc;EAAEC,iBAAiB,qBAAjBA,iBAAiB;AActD;AACA;AACA;AACA;AACA;AAJA,IAKqBC,qBAAqB;EAAA;EAAA;EACxC;;EAGA;AACF;AACA;AACA;EACE,iCAAqB;IAAA;IAAA;IAAA,kCAANC,IAAI;MAAJA,IAAI;IAAA;IACjB,gDAASA,IAAI;IACb;IAAA;IACA,MAAKC,2BAA2B,GAAG,IAAIC,qCAA2B,CAAC,CAAC,CAAC,EAAE;MAACC,MAAM,EAAE,MAAKC;IAAK,CAAC,CAAC;IAAC;EAC/F;;EAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,2BAAkB;MAChB;MACA,IAAI,IAAI,CAACA,KAAK,CAACC,YAAY,EAAE;QAC3B;QACA,OAAO,IAAI,CAACD,KAAK,CAACE,WAAW,CAACC,iBAAiB,GAAG,kBAAkB,GAAG,UAAU;MACnF;MAEA,OAAO,IAAI;IACb;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA,OAMA,mBAAUC,OAAyB,EAAEC,SAAkB,EAAE;MAAA;MACvD,IAAMC,iBAA6B,GACjC;MAAA,yBACA,IAAI,CAACN,KAAK,CAACO,QAAQ,CAACC,MAAM,oFAA1B,sBAA4BC,OAAO,2DAAnC,uBAAqCC,UAAU;MACjD,IAAMC,oBAAmC,GACvC;MAAA,0BACA,IAAI,CAACX,KAAK,CAACO,QAAQ,CAACC,MAAM,qFAA1B,uBAA4BC,OAAO,2DAAnC,uBAAqCG,aAAa;MAEpD,IACGN,iBAAiB,IAAIK,oBAAoB,IACzCP,OAAO,CAACM,UAAU,IAAIN,OAAO,CAACQ,aAAc,EAC7C;QAAA;QACA,IAAMC,MAAuB,GAAG;UAC9BC,IAAI,EAAE,UAAU;UAChBC,WAAW,EAAE,CAAAX,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEW,WAAW,KAAI,SAAS;UAC9CC,SAAS,EAAE,IAAAC,wCAAiB,EAAC;YAC3B;YACAC,UAAU,0BAAE,IAAI,CAAClB,KAAK,CAACO,QAAQ,mFAAnB,qBAAqBE,OAAO,2DAA5B,uBAA8BS,UAAU;YACpD;YACAC,YAAY,EAAE,IAAI,CAACnB,KAAK,CAACoB;UAC3B,CAAC,CAAC;UACFC,UAAU,EAAE;YACVX,UAAU,EAAE,CAAAN,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEM,UAAU,KAAIJ,iBAAiB;YACpD;YACAgB,aAAa,YAAKC,mBAAW,cAAI,IAAI,CAACvB,KAAK,CAACoB,OAAO,CAAE;YACrDI,kBAAkB;YAChB;YACA,IAAAC,yCAAkB,4BAAC,IAAI,CAACzB,KAAK,CAACO,QAAQ,CAACmB,WAAW,2DAA/B,uBAAiCC,aAAa,CAAC,IAAIC,SAAS;YACjFC,SAAS,EAAErC,YAAY,EAAE,IAAI,SAAS;YACtCoB,aAAa,EAAE,CAAAR,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEQ,aAAa,KAAID,oBAAoB;YAC7DmB,EAAE,EAAE,IAAAC,wCAAiB,GAAE;YACvBC,OAAO,EAAEvC,cAAc,EAAE;YACzBwC,cAAc,EAAEvC,iBAAiB;UACnC;QACF,CAAC;QAED,IAAIW,SAAS,EAAE;UACb;UACA,IAAM6B,OAAO,GAAG,IAAI,CAAClC,KAAK,CAACO,QAAQ,CAAC4B,iBAAiB,CAACC,GAAG,CAAC/B,SAAS,CAAC;UACpE,IAAI6B,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEG,WAAW,EAAE;YACxBxB,MAAM,CAACwB,WAAW,GAAGH,OAAO,CAACG,WAAW;UAC1C;QACF;QAEA,OAAOxB,MAAM;MACf;MAEA,MAAM,IAAIyB,KAAK,CAAC,iDAAiD,CAAC;IACpE;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,wBAAelC,OAA8B,EAAE;MAAA;MAC7C,IAAO8B,OAAO,GAAqC9B,OAAO,CAAnD8B,OAAO;QAAEK,gBAAgB,GAAmBnC,OAAO,CAA1CmC,gBAAgB;QAAEC,aAAa,GAAIpC,OAAO,CAAxBoC,aAAa;MAC/C,IAAMC,WAA0C,GAAG;QAACD,aAAa,EAAE;MAAS,CAAC;MAE7E,IAAIN,OAAO,EAAE;QACXO,WAAW,CAACD,aAAa,GAAGN,OAAO,CAACM,aAAa;MACnD;MAEA,IAAIA,aAAa,EAAE;QACjBC,WAAW,CAACD,aAAa,GAAGA,aAAa;MAC3C;MACA;MACA,IAAI,IAAI,CAACxC,KAAK,CAAC0C,QAAQ,EAAE;QACvB;QACA,IAAOC,MAAM,GAAI,IAAI,CAAC3C,KAAK,CAAC0C,QAAQ,CAA7BC,MAAM;QACbF,WAAW,CAACG,MAAM,GAAGD,MAAM,CAACC,MAAM;QAClCH,WAAW,CAACI,QAAQ,GAAGF,MAAM,CAACG,GAAG;QACjCL,WAAW,CAACM,KAAK,GAAGJ,MAAM,CAACI,KAAK;QAChC;QACAN,WAAW,CAACO,QAAQ,GAAG,IAAI,CAAChD,KAAK,CAAC0C,QAAQ,CAACO,QAAQ,CAACb,GAAG,CAAC,OAAO,CAAC;MAClE;MAEA,IAAIF,OAAO,aAAPA,OAAO,qCAAPA,OAAO,CAAEgB,SAAS,+CAAlB,mBAAoBC,SAAS,EAAE;QACjCV,WAAW,CAACO,QAAQ,GAAGd,OAAO,CAACc,QAAQ;QACvCP,WAAW,CAACW,OAAO,GAAGlB,OAAO,CAACc,QAAQ,IAAId,OAAO,CAACc,QAAQ,CAACK,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,EAAE;QAC3Eb,WAAW,CAACc,cAAc,GACxBrB,OAAO,CAACgB,SAAS,CAACC,SAAS,IAAIjB,OAAO,CAACgB,SAAS,CAACC,SAAS,CAACK,UAAU;MACzE;MAEA,IAAIjB,gBAAgB,EAAE;QAAA;QACpBE,WAAW,CAACgB,eAAe,GAAGlB,gBAAgB,aAAhBA,gBAAgB,6CAAhBA,gBAAgB,CAAG,CAAC,CAAC,uDAArB,mBAAuBkB,eAAe;QACpEhB,WAAW,CAACiB,iBAAiB,GAAGnB,gBAAgB,aAAhBA,gBAAgB,8CAAhBA,gBAAgB,CAAG,CAAC,CAAC,wDAArB,oBAAuBmB,iBAAiB;MAC1E;MAEA,IAAIjB,WAAW,CAACD,aAAa,KAAKZ,SAAS,EAAE;QAC3C,MAAM,IAAIU,KAAK,CAAC,oCAAoC,CAAC;MACvD;MAEA,OAAOG,WAAW;IACpB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,gCAAuBkB,SAAyB,EAAEvD,OAAY,EAAE;MAAA;MAC9D,IAAOC,SAAS,GAAID,OAAO,CAApBC,SAAS;MAChB,IAAMQ,MAAM,GAAG,IAAI,CAAC+C,SAAS,CAACxD,OAAO,EAAEC,SAAS,CAAC;MAEjD,IAAMwD,KAAY,GAAG;QACnBC,OAAO,EAAEC,aAAI,CAACC,EAAE,EAAE;QAClB5C,OAAO,EAAE,CAAC;QACVP,MAAM,EAANA,MAAM;QACNoD,UAAU,EAAE;UACVC,SAAS,EAAE,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;UACnC;UACAC,IAAI,EAAE;QACR,CAAC;QACD;QACAC,iBAAiB,4BAAE,IAAI,CAACtE,KAAK,CAACO,QAAQ,CAACmB,WAAW,2DAA/B,uBAAiC6C,WAAW;QAC/DV,KAAK,EAAEF;MACT,CAAC;;MAED;MACA;MACA;MACA,IAAIA,SAAS,CAAC7C,IAAI,KAAK,2BAA2B,EAAE;QAClD,IAAA0D,gDAAyB,EAACX,KAAK,CAAC;MAClC;MAEA,OAAOA,KAAK;IACd;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,8BAA4B;MAC1B,MAAMvB,KAAK,CAAC,iBAAiB,CAAC;IAChC;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,yBAQG;MAAA,IAPDxB,IAAI,QAAJA,IAAI;QACJ2D,OAAO,QAAPA,OAAO;QACPrE,OAAO,QAAPA,OAAO;MAMP,IAAOC,SAAS,GAAsBD,OAAO,CAAtCC,SAAS;QAAEkC,gBAAgB,GAAInC,OAAO,CAA3BmC,gBAAgB;;MAElC;MACA,IAAIlC,SAAS,EAAE;QACb;QACA,IAAM6B,OAAO,GAAG,IAAI,CAAClC,KAAK,CAACO,QAAQ,CAAC4B,iBAAiB,CAACC,GAAG,CAAC/B,SAAS,CAAC;QAEpE,IAAI,CAAC6B,OAAO,EAAE;UACZwC,OAAO,CAACC,IAAI,CACV,iDAAiD,mBACvC7D,IAAI,0BAAgBT,SAAS,EACxC;UACD;UACA,IAAI,CAACL,KAAK,CAAC0C,QAAQ,CAACjC,OAAO,CAACmE,mBAAmB,CAACC,6CAAoC,EAAE;YACpFC,MAAM,EAAE;cACNzE,SAAS,EAATA,SAAS;cACTS,IAAI,EAAJA;YACF;UACF,CAAC,CAAC;UAEF;QACF;;QAEA;QACA,IAAM2B,WAAW,GAAG,IAAI,CAACsC,cAAc,CAAC;UACtC7C,OAAO,EAAPA,OAAO;UACPK,gBAAgB,EAAEL,OAAO,CAACK,gBAAgB,IAAIA;QAChD,CAAC,CAAC;;QAEF;QACA,IAAIyC,iBAA+C,GAAG;UACpDlE,IAAI,EAAJA,IAAI;UACJmE,UAAU,EAAE,IAAI;UAChBxC,WAAW,EAAXA,WAAW;UACXkB,SAAS,EAAE;YACTuB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;UACnC,CAAC;UACDC,SAAS,EAAEb,OAAO,CAACa,SAAS;UAC5BC,cAAc,EAAE;YACdC,uBAAuB,EAAEjE,mBAAW;YACpC;YACAkE,0BAA0B,EAAE,IAAI,CAACzF,KAAK,CAACoB,OAAO;YAC9CsE,uBAAuB,EAAEjG,cAAc,EAAE,IAAI,SAAS;YACtDkG,0BAA0B,EAAEnG,YAAY,EAAE,IAAI,SAAS;YACvDoG,SAAS,EAAE,IAAIzB,IAAI,EAAE,CAACC,WAAW;UACnC;QACF,CAAC;;QAED;QACAY,iBAAiB,GAAG,qBAAMA,iBAAiB,EAAEP,OAAO,CAAC;;QAErD;QACA,IAAMoB,eAAe,GAAG,IAAI,CAACC,sBAAsB,CAACd,iBAAiB,EAAE5E,OAAO,CAAC;QAC/E,IAAI,CAAC2F,uBAAuB,CAACF,eAAe,CAAC;MAC/C,CAAC,MAAM;QACL,MAAM,IAAIvD,KAAK,CACb,6FAA6F,CAC9F;MACH;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,kDAMqB;MAAA,IALnB0D,eAAe,SAAfA,eAAe;QACfC,gBAAgB,SAAhBA,gBAAgB;MAKhB,IAAIC,KAAuB;MAE3B,IAAIF,eAAe,EAAE;QACnB,IAAMG,kBAAkB,GAAGC,2CAAkC,CAACJ,eAAe,CAAC;QAE9E,IAAIG,kBAAkB,EAAE;UACtBD,KAAK,GAAG,qBACN;YAACG,KAAK,EAAE,IAAI;YAAEC,WAAW,EAAE,KAAK;YAAExF,IAAI,EAAE,OAAO;YAAEyF,QAAQ,EAAE;UAAO,CAAC;UAAE;UACrE;YAACC,SAAS,EAAER;UAAe,CAAC,EAC5B;YAACC,gBAAgB,EAAhBA;UAAgB,CAAC,EAClBE,kBAAkB,CACnB;UAED,OAAOD,KAAK;QACd;MACF;MAEA,OAAOtE,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,yCAAgC6E,QAAa,EAAE;MAAA;MAC7C,IAAMR,gBAAgB,GAAG,CAAAQ,QAAQ,aAARA,QAAQ,yCAARA,QAAQ,CAAEC,IAAI,mDAAd,eAAgBF,SAAS,MAAIC,QAAQ,aAARA,QAAQ,0CAARA,QAAQ,CAAEC,IAAI,oDAAd,gBAAgBC,IAAI;MAC1E,IAAIV,gBAAgB,EAAE;QACpB,IAAMD,eAAe,GAAGY,sDAA6C,CAACX,gBAAgB,CAAC;QACvF,IAAID,eAAe,EAAE;UACnB,OAAO,IAAI,CAACa,iCAAiC,CAAC;YAACb,eAAe,EAAfA,eAAe;YAAEC,gBAAgB,EAAhBA;UAAgB,CAAC,CAAC;QACpF;;QAEA;QACA,IAAI,IAAAa,8CAAuB,EAACb,gBAAgB,CAAC,EAAE;UAC7C,OAAO,IAAI,CAACY,iCAAiC,CAAC;YAC5Cb,eAAe,EAAEe,oCAA2B;YAC5Cd,gBAAgB,EAAhBA;UACF,CAAC,CAAC;QACJ;;QAEA;QACA,OAAO,IAAI,CAACY,iCAAiC,CAAC;UAC5Cb,eAAe,EAAEgB,8CAAqC;UACtDf,gBAAgB,EAAhBA;QACF,CAAC,CAAC;MACJ;MAEA,OAAOrE,SAAS;IAClB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,iDAMG;MAAA,IALDd,IAAI,SAAJA,IAAI;QACJV,OAAO,SAAPA,OAAO;MAKP,IAAOC,SAAS,GAAgCD,OAAO,CAAhDC,SAAS;QAAEkC,gBAAgB,GAAcnC,OAAO,CAArCmC,gBAAgB;QAAEkE,QAAQ,GAAIrG,OAAO,CAAnBqG,QAAQ;;MAE5C;MACA,IAAMvE,OAAO,GAAG,IAAI,CAAClC,KAAK,CAACO,QAAQ,CAAC4B,iBAAiB,CAACC,GAAG,CAAC/B,SAAS,CAAC;MAEpE,IAAI,CAAC6B,OAAO,EAAE;QACZwC,OAAO,CAACC,IAAI,CACV,0DAA0D,mBAChD7D,IAAI,0BAAgBT,SAAS,EACxC;QACD;QACA,IAAI,CAACL,KAAK,CAAC0C,QAAQ,CAACjC,OAAO,CAACmE,mBAAmB,CAACC,6CAAoC,EAAE;UACpFC,MAAM,EAAE;YACNzE,SAAS,EAATA,SAAS;YACTS,IAAI,EAAJA;UACF;QACF,CAAC,CAAC;QAEF,OAAOc,SAAS;MAClB;;MAEA;MACA,IAAMa,WAAW,GAAG,IAAI,CAACsC,cAAc,CAAC;QACtC7C,OAAO,EAAPA,OAAO;QACPK,gBAAgB,EAAE,CAAAL,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEK,gBAAgB,KAAIA;MACjD,CAAC,CAAC;;MAEF;MACA,IAAM0E,MAAwC,GAAG,EAAE;MAEnD,IAAIR,QAAQ,EAAE;QACZ,IAAMS,cAAc,GAAG,IAAI,CAACC,+BAA+B,CAACV,QAAQ,CAAC;QACrE,IAAIS,cAAc,EAAE;UAClBD,MAAM,CAACG,IAAI,CAACF,cAAc,CAAC;QAC7B;MACF;;MAEA;MACA,IAAMlC,iBAAyC,GAAG;QAChDlE,IAAI,EAAJA,IAAI;QACJmE,UAAU,EAAE,IAAI;QAChBxC,WAAW,EAAXA,WAAW;QACXwE,MAAM,EAANA,MAAM;QACNtD,SAAS,EAAE;UACTuB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;QACnC,CAAC;QACDgC,QAAQ,EAAEnF,OAAO,CAACoF,cAAc,EAAE;QAClCC,SAAS,EAAE,IAAI,CAACC,eAAe;MACjC,CAAC;MAED,OAAOxC,iBAAiB;IAC1B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,kDAMG;MAAA,IALDlE,IAAI,SAAJA,IAAI;QACJV,OAAO,SAAPA,OAAO;MAKP,IAAOoC,aAAa,GAAIpC,OAAO,CAAxBoC,aAAa;;MAEpB;MACA,IAAMC,WAAW,GAAG,IAAI,CAACsC,cAAc,CAAC;QACtCvC,aAAa,EAAbA;MACF,CAAC,CAAC;;MAEF;MACA,IAAMwC,iBAAyC,GAAG;QAChDlE,IAAI,EAAJA,IAAI;QACJmE,UAAU,EAAE,IAAI;QAChBxC,WAAW,EAAXA,WAAW;QACXkB,SAAS,EAAE;UACTuB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;QACnC,CAAC;QACDkC,SAAS,EAAE,IAAI,CAACC,eAAe;MACjC,CAAC;MAED,OAAOxC,iBAAiB;IAC1B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAA;IAAA,OASA,mCAQG;MAAA,IAPDlE,IAAI,SAAJA,IAAI;QACJ2D,OAAO,SAAPA,OAAO;QACPrE,OAAO,SAAPA,OAAO;MAMP,IAAOC,SAAS,GAAmBD,OAAO,CAAnCC,SAAS;QAAEmC,aAAa,GAAIpC,OAAO,CAAxBoC,aAAa;MAC/B,IAAIwC,iBAAyC;;MAE7C;MACA,IAAI3E,SAAS,EAAE;QACb2E,iBAAiB,GAAG,IAAI,CAACyC,gCAAgC,CAAC;UAAC3G,IAAI,EAAJA,IAAI;UAAEV,OAAO,EAAPA;QAAO,CAAC,CAAC;MAC5E,CAAC,MAAM,IAAIoC,aAAa,EAAE;QACxB;QACAwC,iBAAiB,GAAG,IAAI,CAAC0C,iCAAiC,CAAC;UAAC5G,IAAI,EAAJA,IAAI;UAAEV,OAAO,EAAPA;QAAO,CAAC,CAAC;MAC7E,CAAC,MAAM;QACL,MAAM,IAAIkC,KAAK,CAAC,iBAAiB,CAAC;MACpC;;MAEA;MACA0C,iBAAiB,GAAG,qBAAMA,iBAAiB,EAAEP,OAAO,CAAC;;MAErD;MACA,IAAMoB,eAAe,GAAG,IAAI,CAACC,sBAAsB,CAACd,iBAAiB,EAAE5E,OAAO,CAAC;MAE/E,OAAOyF,eAAe;IACxB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EAPE;IAAA;IAAA,OAQA,kCAQG;MAAA,IAPD/E,IAAI,SAAJA,IAAI;QACJ2D,OAAO,SAAPA,OAAO;QACPrE,OAAO,SAAPA,OAAO;MAMP,IAAMyF,eAAe,GAAG,IAAI,CAAC8B,kBAAkB,CAAC;QAAC7G,IAAI,EAAJA,IAAI;QAAE2D,OAAO,EAAPA,OAAO;QAAErE,OAAO,EAAPA;MAAO,CAAC,CAAC;MAEzE,OAAO,IAAI,CAAC2F,uBAAuB,CAACF,eAAe,CAAC;IACtD;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,iCAAwBhC,KAAY,EAAgB;MAClD;MACA,IAAM+D,UAAU,GAAG;QACjBC,YAAY,EAAEhE,KAAK;QACnBiE,IAAI,EAAE,CAAC,kBAAkB;MAC3B,CAAC;MAED,OAAO,IAAI,CAACjI,2BAA2B,CAACkI,OAAO,CAACH,UAAU,CAAC;IAC7D;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAA;IAAA;MAAA,mHASA;QAAA;QAAA;UAAA;YAAA;cACE9G,IAAI,SAAJA,IAAI,EACJ2D,OAAO,SAAPA,OAAO,EACPrE,OAAO,SAAPA,OAAO;cAMD4H,WAAW,GAAG,IAAI,CAACL,kBAAkB,CAAC;gBAAC7G,IAAI,EAAJA,IAAI;gBAAE2D,OAAO,EAAPA,OAAO;gBAAErE,OAAO,EAAPA;cAAO,CAAC,CAAC,EAErE;cACA;cACMyF,eAAe,GAAG,IAAAoC,kDAA2B,EAAC,IAAI,CAACjI,KAAK,EAAE;gBAC9D6H,YAAY,EAAEG,WAAW;gBACzBF,IAAI,EAAE,CAAC,kBAAkB;cAC3B,CAAC,CAAC,EAEF;cAAA,iCACO,IAAI,CAAC9H,KAAK,CAACkI,mBAAmB,CAAC;gBACpCC,MAAM,EAAE,MAAM;gBACdC,OAAO,EAAE,SAAS;gBAClBC,QAAQ,EAAE,eAAe;gBACzB3B,IAAI,EAAE;kBACJjG,OAAO,EAAE,CAACoF,eAAe;gBAC3B;cACF,CAAC,CAAC;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CACH;MAAA;QAAA;MAAA;MAAA;IAAA;EAAA;EAAA;AAAA,EAlhBgDyC,+BAAoB;AAAA"}
1
+ {"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","webex","canAuthorize","credentials","isUnverifiedGuest","meetingId","meeting","meetings","meetingCollection","get","meetingInfo","enableConvergedArchitecture","undefined","options","defaultClientType","config","metrics","clientType","defaultSubClientType","subClientType","providedClientVersion","clientVersion","defaultSDKClientVersion","CLIENT_NAME","version","versionMetadata","extractVersionMetadata","origin","name","networkType","userAgent","userAgentToString","clientName","webexVersion","clientInfo","localNetworkPrefix","anonymizeIPAddress","geoHintInfo","clientAddress","osVersion","os","getOSNameInternal","browser","browserVersion","environment","Error","mediaConnections","correlationId","identifiers","internal","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","event","eventId","uuid","v4","originTime","triggered","Date","toISOString","sent","senderCountryCode","countryCode","clearEmptyKeysRecursively","payload","console","warn","submitClientMetrics","CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND","fields","getIdentifiers","clientEventObject","canProceed","webClientDomain","window","location","hostname","intervals","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","diagnosticEvent","prepareDiagnosticEvent","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","rawError","body","code","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","getErrorPayloadForClientErrorCode","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","errors","generatedError","generateClientEventErrorPayload","push","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","finalEvent","eventPayload","type","request","clientEvent","prepareDiagnosticMetricItem","prepareFetchOptions","method","service","resource","StatelessWebexPlugin"],"sources":["call-diagnostic-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport {BrowserDetection} from '@webex/common';\nimport uuid from 'uuid';\nimport {merge} from 'lodash';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\n\nimport {\n anonymizeIPAddress,\n clearEmptyKeysRecursively,\n isLocusServiceErrorCode,\n prepareDiagnosticMetricItem,\n userAgentToString,\n extractVersionMetadata,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n RecursivePartial,\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n} from '../metrics.types';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';\nimport {\n CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD,\n CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n} from './config';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n};\n\n/**\n * @description Util class to handle Call Analyzer Metrics\n * @export\n * @class CallDiagnosticMetrics\n */\nexport default class CallDiagnosticMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.callDiagnosticEventsBatcher = new CallDiagnosticEventsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the login type of the current user\n * @returns one of 'login-ci','unverified-guest', null\n */\n getCurLoginType() {\n // @ts-ignore\n if (this.webex.canAuthorize) {\n // @ts-ignore\n return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';\n }\n\n return null;\n }\n\n /**\n * Returns if the meeting has converged architecture enabled\n * @param options.meetingId\n */\n getIsConvergedArchitectureEnabled({meetingId}: {meetingId?: string}): boolean {\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n return meeting?.meetingInfo?.enableConvergedArchitecture;\n }\n\n return undefined;\n }\n\n /**\n * Get origin object for Call Diagnostic Event payload.\n * @param options\n * @param meetingId\n * @returns\n */\n getOrigin(options: GetOriginOptions, meetingId?: string) {\n const defaultClientType: ClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.clientType;\n const defaultSubClientType: SubClientType =\n // @ts-ignore\n this.webex.meetings.config?.metrics?.subClientType;\n // @ts-ignore\n const providedClientVersion: string = this.webex.meetings.config?.metrics?.clientVersion;\n // @ts-ignore\n const defaultSDKClientVersion = `${CLIENT_NAME}/${this.webex.version}`;\n\n let versionMetadata: Pick<ClientInfo, 'majorVersion' | 'minorVersion'> = {};\n\n // sdk version split doesn't really make sense for now...\n if (providedClientVersion) {\n versionMetadata = extractVersionMetadata(providedClientVersion);\n }\n\n if (\n (defaultClientType && defaultSubClientType) ||\n (options.clientType && options.subClientType)\n ) {\n const origin: Event['origin'] = {\n name: 'endpoint',\n networkType: options?.networkType || 'unknown',\n userAgent: userAgentToString({\n // @ts-ignore\n clientName: this.webex.meetings?.metrics?.clientName,\n // @ts-ignore\n webexVersion: this.webex.version,\n }),\n clientInfo: {\n clientType: options?.clientType || defaultClientType,\n clientVersion: providedClientVersion || defaultSDKClientVersion,\n ...versionMetadata,\n localNetworkPrefix:\n // @ts-ignore\n anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,\n osVersion: getOSVersion() || 'unknown',\n subClientType: options?.subClientType || defaultSubClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n };\n\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n if (meeting?.environment) {\n origin.environment = meeting.environment;\n }\n }\n\n return origin;\n }\n\n throw new Error(\"ClientType and SubClientType can't be undefined\");\n }\n\n /**\n * Gather identifier details for call diagnostic payload.\n * @throws Error if initialization fails.\n * @param options\n */\n getIdentifiers(options: GetIdentifiersOptions) {\n const {meeting, mediaConnections, correlationId} = options;\n const identifiers: Event['event']['identifiers'] = {correlationId: 'unknown'};\n\n if (meeting) {\n identifiers.correlationId = meeting.correlationId;\n }\n\n if (correlationId) {\n identifiers.correlationId = correlationId;\n }\n // @ts-ignore\n if (this.webex.internal) {\n // @ts-ignore\n const {device} = this.webex.internal;\n identifiers.userId = device.userId;\n identifiers.deviceId = device.url;\n identifiers.orgId = device.orgId;\n // @ts-ignore\n identifiers.locusUrl = this.webex.internal.services.get('locus');\n }\n\n if (meeting?.locusInfo?.fullState) {\n identifiers.locusUrl = meeting.locusUrl;\n identifiers.locusId = meeting.locusUrl && meeting.locusUrl.split('/').pop();\n identifiers.locusStartTime =\n meeting.locusInfo.fullState && meeting.locusInfo.fullState.lastActive;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (identifiers.correlationId === undefined) {\n throw new Error('Identifiers initialization failed.');\n }\n\n return identifiers;\n }\n\n /**\n * Create diagnostic event, which can hold client event, feature event or MQE event data.\n * This just initiates the shared properties that are required for all the 3 event categories.\n * @param eventData\n * @param options\n * @returns\n */\n prepareDiagnosticEvent(eventData: Event['event'], options: any) {\n const {meetingId} = options;\n const origin = this.getOrigin(options, meetingId);\n\n const event: Event = {\n eventId: uuid.v4(),\n version: 1,\n origin,\n originTime: {\n triggered: new Date().toISOString(),\n // is overridden in prepareRequest batcher\n sent: 'not_defined_yet',\n },\n // @ts-ignore\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: eventData,\n };\n\n // sanitize (remove empty properties, CA requires it)\n // but we don't want to sanitize MQE as most of the times\n // values will be 0, [] etc, and they are required.\n if (eventData.name !== 'client.mediaquality.event') {\n clearEmptyKeysRecursively(event);\n }\n\n return event;\n }\n\n /**\n * TODO: NOT IMPLEMENTED\n * Submit Feature Event\n * @returns\n */\n public submitFeatureEvent() {\n throw Error('Not implemented');\n }\n\n /**\n * Submit Media Quality Event\n * @param args - submit params\n * @param arg.name - event key\n * @param arg.payload - additional payload to be merge with the default payload\n * @param arg.options - options\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: SubmitMQEOptions;\n }) {\n const {meetingId, mediaConnections} = options;\n\n // events that will most likely happen in join phase\n if (meetingId) {\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send MQE but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return;\n }\n\n // merge identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting.mediaConnections || mediaConnections,\n });\n\n // create media quality event object\n let clientEventObject: MediaQualityEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n intervals: payload.intervals,\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n // @ts-ignore\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || 'unknown',\n startTime: new Date().toISOString(),\n },\n };\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append media quality event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n this.submitToCallDiagnostics(diagnosticEvent);\n } else {\n throw new Error(\n 'Media quality events cant be sent outside the context of a meeting. Meeting id is required.'\n );\n }\n }\n\n /**\n * Return Client Event payload by client error code\n * @param arg - get error arg\n * @param arg.clientErrorCode\n * @param arg.serviceErrorCode\n * @returns\n */\n public getErrorPayloadForClientErrorCode({\n clientErrorCode,\n serviceErrorCode,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n }): ClientEventError {\n let error: ClientEventError;\n\n if (clientErrorCode) {\n const partialParsedError = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n if (partialParsedError) {\n error = merge(\n {fatal: true, shownToUser: false, name: 'other', category: 'other'}, // default values\n {errorCode: clientErrorCode},\n {serviceErrorCode},\n partialParsedError\n );\n\n return error;\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate error payload for Client Event\n * @param rawError\n */\n generateClientEventErrorPayload(rawError: any) {\n const serviceErrorCode = rawError?.body?.errorCode || rawError?.body?.code;\n if (serviceErrorCode) {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n if (clientErrorCode) {\n return this.getErrorPayloadForClientErrorCode({clientErrorCode, serviceErrorCode});\n }\n\n // by default, if it is locus error, return nre locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n // otherwise return meeting info\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n return undefined;\n }\n\n /**\n * Create client event object for in meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - options\n * @returns object\n */\n private createClientEventObjectInMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, mediaConnections, rawError} = options;\n\n // @ts-ignore\n const meeting = this.webex.meetings.meetingCollection.get(meetingId);\n\n if (!meeting) {\n console.warn(\n 'Attempt to send client event but no meeting was found...',\n `event: ${name}, meetingId: ${meetingId}`\n );\n // @ts-ignore\n this.webex.internal.metrics.submitClientMetrics(CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND, {\n fields: {\n meetingId,\n name,\n },\n });\n\n return undefined;\n }\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n meeting,\n mediaConnections: meeting?.mediaConnections || mediaConnections,\n });\n\n // check if we need to generate errors\n const errors: ClientEvent['payload']['errors'] = [];\n\n if (rawError) {\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n }\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n errors,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n userType: meeting.getCurUserType(),\n loginType: this.getCurLoginType(),\n isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({\n meetingId,\n }),\n };\n\n return clientEventObject;\n }\n\n /**\n * Create client event object for pre meeting events\n * @param arg - create args\n * @param arg.event - event key\n * @param arg.options - payload\n * @returns object\n */\n private createClientEventObjectPreMeeting({\n name,\n options,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n }) {\n const {correlationId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n return clientEventObject;\n }\n\n /**\n * Prepare Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @returns {any} options to be with fetch\n * @throws\n */\n private prepareClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const {meetingId, correlationId} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options});\n } else {\n throw new Error('Not implemented');\n }\n\n // merge any new properties, or override existing ones\n clientEventObject = merge(clientEventObject, payload);\n\n // append client event data to the call diagnostic event\n const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);\n\n return diagnosticEvent;\n }\n\n /**\n * Submit Client Event CA event.\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - payload\n * @throws\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }) {\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n return this.submitToCallDiagnostics(diagnosticEvent);\n }\n\n /**\n * Prepare the event and send the request to metrics-a service.\n * @param event\n * @returns promise\n */\n submitToCallDiagnostics(event: Event): Promise<any> {\n // build metrics-a event type\n const finalEvent = {\n eventPayload: event,\n type: ['diagnostic-event'],\n };\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Builds a request options object to later be passed to fetch().\n * @param arg - submit params\n * @param arg.event - event key\n * @param arg.payload - additional payload to be merged with default payload\n * @param arg.options - client event options\n * @returns {Promise<any>}\n * @throws\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n const clientEvent = this.prepareClientEvent({name, payload, options});\n\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: clientEvent,\n type: ['diagnostic-event'],\n });\n\n // @ts-ignore\n return this.webex.prepareFetchOptions({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -5,10 +5,12 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
5
5
  _Object$defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.userAgentToString = exports.setMetricTimings = exports.prepareDiagnosticMetricItem = exports.isLocusServiceErrorCode = exports.getBuildType = exports.clearEmptyKeysRecursively = exports.anonymizeIPAddress = void 0;
8
+ exports.userAgentToString = exports.setMetricTimings = exports.prepareDiagnosticMetricItem = exports.isLocusServiceErrorCode = exports.getBuildType = exports.extractVersionMetadata = exports.clearEmptyKeysRecursively = exports.anonymizeIPAddress = void 0;
9
9
  var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
10
10
  var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
11
11
  var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
12
+ var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));
13
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
12
14
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
13
15
  var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));
14
16
  var _merge2 = _interopRequireDefault(require("lodash/merge"));
@@ -222,4 +224,16 @@ var setMetricTimings = function setMetricTimings(options) {
222
224
  return options;
223
225
  };
224
226
  exports.setMetricTimings = setMetricTimings;
227
+ var extractVersionMetadata = function extractVersionMetadata(version) {
228
+ // extract major and minor version
229
+ var _version$split = version.split('.'),
230
+ _version$split2 = (0, _slicedToArray2.default)(_version$split, 2),
231
+ majorVersion = _version$split2[0],
232
+ minorVersion = _version$split2[1];
233
+ return {
234
+ majorVersion: (0, _parseInt2.default)(majorVersion, 10),
235
+ minorVersion: (0, _parseInt2.default)(minorVersion, 10)
236
+ };
237
+ };
238
+ exports.extractVersionMetadata = extractVersionMetadata;
225
239
  //# sourceMappingURL=call-diagnostic-metrics.util.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","getBuildType","webClientDomain","includes","prepareDiagnosticMetricItem","webex","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","setMetricTimings","options","body","metrics","now","Date","toISOString","metric","originTime","triggered","sent"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (webClientDomain): Event['origin']['buildType'] => {\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body?.metrics) {\n const now = new Date().toISOString();\n options.body.metrics.forEach((metric) => {\n if (metric.eventPayload) {\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n }\n\n return options;\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","getBuildType","webClientDomain","includes","prepareDiagnosticMetricItem","webex","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","setMetricTimings","options","body","metrics","now","Date","toISOString","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (webClientDomain): Event['origin']['buildType'] => {\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body?.metrics) {\n const now = new Date().toISOString();\n options.body.metrics.forEach((metric) => {\n if (metric.eventPayload) {\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n"],"mappings":"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"}
package/dist/metrics.js CHANGED
@@ -161,7 +161,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
161
161
  });
162
162
  });
163
163
  },
164
- version: "3.0.0-beta.212"
164
+ version: "3.0.0-beta.213"
165
165
  });
166
166
  var _default = Metrics;
167
167
  exports.default = _default;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {ClientEvent as RawClientEvent} from './call-diagnostic/generated-types-temp/ClientEvent';\nimport {Event as RawEvent} from './call-diagnostic/generated-types-temp/Event';\nimport {MediaQualityEvent as RawMediaQualityEvent} from './call-diagnostic/generated-types-temp/MediaQualityEvent';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n showToUser?: boolean;\n correlationId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.interstitial-window.launched'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton';\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options?: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {ClientEvent as RawClientEvent} from './call-diagnostic/generated-types-temp/ClientEvent';\nimport {Event as RawEvent} from './call-diagnostic/generated-types-temp/Event';\nimport {MediaQualityEvent as RawMediaQualityEvent} from './call-diagnostic/generated-types-temp/MediaQualityEvent';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n showToUser?: boolean;\n correlationId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.interstitial-window.launched'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton';\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options?: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n"],"mappings":""}
@@ -27,6 +27,13 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
27
27
  * @returns one of 'login-ci','unverified-guest', null
28
28
  */
29
29
  getCurLoginType(): "login-ci" | "unverified-guest";
30
+ /**
31
+ * Returns if the meeting has converged architecture enabled
32
+ * @param options.meetingId
33
+ */
34
+ getIsConvergedArchitectureEnabled({ meetingId }: {
35
+ meetingId?: string;
36
+ }): boolean;
30
37
  /**
31
38
  * Get origin object for Call Diagnostic Event payload.
32
39
  * @param options
@@ -51,3 +51,7 @@ export declare const prepareDiagnosticMetricItem: (webex: any, item: any) => any
51
51
  * @returns {any} the updated options object
52
52
  */
53
53
  export declare const setMetricTimings: (options: any) => any;
54
+ export declare const extractVersionMetadata: (version: string) => {
55
+ majorVersion: number;
56
+ minorVersion: number;
57
+ };
@@ -51,6 +51,7 @@ export type RecursivePartial<T> = {
51
51
  [P in keyof T]?: T[P] extends (infer U)[] ? RecursivePartial<U>[] : T[P] extends object ? RecursivePartial<T[P]> : T[P];
52
52
  };
53
53
  export type MetricEventNames = InternalEvent['name'] | ClientEvent['name'] | BehavioralEvent['name'] | OperationalEvent['name'] | FeatureEvent['name'] | MediaQualityEvent['name'];
54
+ export type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;
54
55
  export type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];
55
56
  export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];
56
57
  export type NetworkType = NonNullable<RawEvent['origin']>['networkType'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-metrics",
3
- "version": "3.0.0-beta.212",
3
+ "version": "3.0.0-beta.213",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -28,12 +28,12 @@
28
28
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
29
29
  },
30
30
  "dependencies": {
31
- "@webex/common": "3.0.0-beta.212",
32
- "@webex/common-timers": "3.0.0-beta.212",
33
- "@webex/internal-plugin-device": "3.0.0-beta.212",
34
- "@webex/internal-plugin-metrics": "3.0.0-beta.212",
35
- "@webex/test-helper-chai": "3.0.0-beta.212",
36
- "@webex/test-helper-mock-webex": "3.0.0-beta.212",
37
- "@webex/webex-core": "3.0.0-beta.212"
31
+ "@webex/common": "3.0.0-beta.213",
32
+ "@webex/common-timers": "3.0.0-beta.213",
33
+ "@webex/internal-plugin-device": "3.0.0-beta.213",
34
+ "@webex/internal-plugin-metrics": "3.0.0-beta.213",
35
+ "@webex/test-helper-chai": "3.0.0-beta.213",
36
+ "@webex/test-helper-mock-webex": "3.0.0-beta.213",
37
+ "@webex/webex-core": "3.0.0-beta.213"
38
38
  }
39
39
  }
@@ -13,6 +13,7 @@ import {
13
13
  isLocusServiceErrorCode,
14
14
  prepareDiagnosticMetricItem,
15
15
  userAgentToString,
16
+ extractVersionMetadata,
16
17
  } from './call-diagnostic-metrics.util';
17
18
  import {CLIENT_NAME} from '../config';
18
19
  import {
@@ -28,6 +29,7 @@ import {
28
29
  SubmitMQEPayload,
29
30
  ClientEventError,
30
31
  ClientEventPayload,
32
+ ClientInfo,
31
33
  } from '../metrics.types';
32
34
  import CallDiagnosticEventsBatcher from './call-diagnostic-metrics-batcher';
33
35
  import {
@@ -85,6 +87,21 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
85
87
  return null;
86
88
  }
87
89
 
90
+ /**
91
+ * Returns if the meeting has converged architecture enabled
92
+ * @param options.meetingId
93
+ */
94
+ getIsConvergedArchitectureEnabled({meetingId}: {meetingId?: string}): boolean {
95
+ if (meetingId) {
96
+ // @ts-ignore
97
+ const meeting = this.webex.meetings.meetingCollection.get(meetingId);
98
+
99
+ return meeting?.meetingInfo?.enableConvergedArchitecture;
100
+ }
101
+
102
+ return undefined;
103
+ }
104
+
88
105
  /**
89
106
  * Get origin object for Call Diagnostic Event payload.
90
107
  * @param options
@@ -98,6 +115,17 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
98
115
  const defaultSubClientType: SubClientType =
99
116
  // @ts-ignore
100
117
  this.webex.meetings.config?.metrics?.subClientType;
118
+ // @ts-ignore
119
+ const providedClientVersion: string = this.webex.meetings.config?.metrics?.clientVersion;
120
+ // @ts-ignore
121
+ const defaultSDKClientVersion = `${CLIENT_NAME}/${this.webex.version}`;
122
+
123
+ let versionMetadata: Pick<ClientInfo, 'majorVersion' | 'minorVersion'> = {};
124
+
125
+ // sdk version split doesn't really make sense for now...
126
+ if (providedClientVersion) {
127
+ versionMetadata = extractVersionMetadata(providedClientVersion);
128
+ }
101
129
 
102
130
  if (
103
131
  (defaultClientType && defaultSubClientType) ||
@@ -114,8 +142,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
114
142
  }),
115
143
  clientInfo: {
116
144
  clientType: options?.clientType || defaultClientType,
117
- // @ts-ignore
118
- clientVersion: `${CLIENT_NAME}/${this.webex.version}`,
145
+ clientVersion: providedClientVersion || defaultSDKClientVersion,
146
+ ...versionMetadata,
119
147
  localNetworkPrefix:
120
148
  // @ts-ignore
121
149
  anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress) || undefined,
@@ -434,6 +462,9 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
434
462
  },
435
463
  userType: meeting.getCurUserType(),
436
464
  loginType: this.getCurLoginType(),
465
+ isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({
466
+ meetingId,
467
+ }),
437
468
  };
438
469
 
439
470
  return clientEventObject;
@@ -232,3 +232,13 @@ export const setMetricTimings = (options) => {
232
232
 
233
233
  return options;
234
234
  };
235
+
236
+ export const extractVersionMetadata = (version: string) => {
237
+ // extract major and minor version
238
+ const [majorVersion, minorVersion] = version.split('.');
239
+
240
+ return {
241
+ majorVersion: parseInt(majorVersion, 10),
242
+ minorVersion: parseInt(minorVersion, 10),
243
+ };
244
+ };
@@ -83,6 +83,7 @@ export type MetricEventNames =
83
83
  | FeatureEvent['name']
84
84
  | MediaQualityEvent['name'];
85
85
 
86
+ export type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;
86
87
  export type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];
87
88
  export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];
88
89
  export type NetworkType = NonNullable<RawEvent['origin']>['networkType'];
@@ -32,6 +32,7 @@ describe('internal-plugin-metrics', () => {
32
32
  lastActive: 'lastActive',
33
33
  },
34
34
  },
35
+ meetingInfo: {},
35
36
  getCurUserType: () => 'host',
36
37
  };
37
38
 
@@ -144,6 +145,35 @@ describe('internal-plugin-metrics', () => {
144
145
  userAgent,
145
146
  });
146
147
  });
148
+
149
+ it('builds origin correctly, when overriding clientVersion', () => {
150
+ webex.meetings.config.metrics.clientVersion = '43.9.0.1234';
151
+
152
+ //@ts-ignore
153
+ const res = cd.getOrigin(
154
+ {subClientType: 'WEB_APP', clientType: 'TEAMS_CLIENT'},
155
+ fakeMeeting.id
156
+ );
157
+
158
+ assert.deepEqual(res, {
159
+ clientInfo: {
160
+ browser: getBrowserName(),
161
+ browserVersion: getBrowserVersion(),
162
+ clientType: 'TEAMS_CLIENT',
163
+ "clientVersion": "43.9.0.1234",
164
+ "localNetworkPrefix": "1.3.4.0",
165
+ "majorVersion": 43,
166
+ "minorVersion": 9,
167
+ os: getOSNameInternal(),
168
+ osVersion: getOSVersion(),
169
+ subClientType: 'WEB_APP',
170
+ },
171
+ environment: 'meeting_evn',
172
+ name: 'endpoint',
173
+ networkType: 'unknown',
174
+ userAgent,
175
+ });
176
+ })
147
177
  });
148
178
 
149
179
  describe('#getIdentifiers', () => {
@@ -274,6 +304,7 @@ describe('internal-plugin-metrics', () => {
274
304
  loginType: 'login-ci',
275
305
  name: 'client.alert.displayed',
276
306
  userType: 'host',
307
+ isConvergedArchitectureEnabled: undefined,
277
308
  },
278
309
  options
279
310
  );
@@ -297,6 +328,7 @@ describe('internal-plugin-metrics', () => {
297
328
  loginType: 'login-ci',
298
329
  name: 'client.alert.displayed',
299
330
  userType: 'host',
331
+ isConvergedArchitectureEnabled: undefined,
300
332
  },
301
333
  eventId: 'my-fake-id',
302
334
  origin: {
@@ -430,6 +462,7 @@ describe('internal-plugin-metrics', () => {
430
462
  loginType: 'login-ci',
431
463
  name: 'client.alert.displayed',
432
464
  userType: 'host',
465
+ isConvergedArchitectureEnabled: undefined,
433
466
  },
434
467
  eventId: 'my-fake-id',
435
468
  origin: {
@@ -496,6 +529,7 @@ describe('internal-plugin-metrics', () => {
496
529
  loginType: 'login-ci',
497
530
  name: 'client.alert.displayed',
498
531
  userType: 'host',
532
+ isConvergedArchitectureEnabled: undefined,
499
533
  },
500
534
  eventId: 'my-fake-id',
501
535
  origin: {
@@ -743,6 +777,22 @@ describe('internal-plugin-metrics', () => {
743
777
  });
744
778
  });
745
779
 
780
+ describe('#getIsConvergedArchitectureEnabled', () => {
781
+ it('returns true if converged architecture is enabled', () => {
782
+ fakeMeeting.meetingInfo = {enableConvergedArchitecture: true};
783
+ assert.deepEqual(cd.getIsConvergedArchitectureEnabled({meetingId: fakeMeeting.id}), true);
784
+ });
785
+ it('returns false if converged architecture is not enabled', () => {
786
+ fakeMeeting.meetingInfo = {enableConvergedArchitecture: false};
787
+ assert.deepEqual(cd.getIsConvergedArchitectureEnabled({meetingId: fakeMeeting.id}), false);
788
+
789
+ });
790
+ it('returns undefined if converged architecture is not defined', () => {
791
+ fakeMeeting.meetingInfo = {};
792
+ assert.deepEqual(cd.getIsConvergedArchitectureEnabled({meetingId: fakeMeeting.id}), undefined);
793
+ });
794
+ })
795
+
746
796
  describe('#buildClientEventFetchRequestOptions', () => {
747
797
  it('returns expected options', async () => {
748
798
  const options = {
@@ -779,6 +829,7 @@ describe('internal-plugin-metrics', () => {
779
829
  name: 'client.exit.app',
780
830
  trigger: 'user-interaction',
781
831
  userType: 'host',
832
+ isConvergedArchitectureEnabled: undefined,
782
833
  },
783
834
  eventId: 'my-fake-id',
784
835
  origin: {
@@ -2,6 +2,7 @@ import {assert} from '@webex/test-helper-chai';
2
2
  import sinon from 'sinon';
3
3
  import {
4
4
  clearEmptyKeysRecursively,
5
+ extractVersionMetadata,
5
6
  getBuildType,
6
7
  isLocusServiceErrorCode,
7
8
  prepareDiagnosticMetricItem,
@@ -333,4 +334,22 @@ describe('internal-plugin-metrics', () => {
333
334
  check(options, expectedOptions);
334
335
  });
335
336
  });
337
+
338
+ describe('extractVersionMetadata', () => {
339
+ [
340
+ ['1.2.3', {majorVersion: 1, minorVersion: 2}],
341
+ ['0.0.1', {majorVersion: 0, minorVersion: 0}],
342
+ ['0.0.0', {majorVersion: 0, minorVersion: 0}],
343
+ ['1.2', {majorVersion: 1, minorVersion: 2}],
344
+ ['1', {majorVersion: 1, minorVersion: NaN}],
345
+ ['foo', {majorVersion: NaN, minorVersion: NaN}],
346
+ ['1.foo', {majorVersion: 1, minorVersion: NaN}],
347
+ ['foo.1', {majorVersion: NaN, minorVersion: 1}],
348
+ ['foo.bar', {majorVersion: NaN, minorVersion: NaN}],
349
+ ].forEach(([version, expected]) => {
350
+ it(`returns expected result for ${version}`, () => {
351
+ assert.deepEqual(extractVersionMetadata(version as string), expected);
352
+ });
353
+ });
354
+ });
336
355
  });