@webex/internal-plugin-metrics 3.0.0-beta.282 → 3.0.0-beta.284

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/batcher.js CHANGED
@@ -42,7 +42,8 @@ var MetricsBatcher = _webexCore.Batcher.extend({
42
42
  resource: 'metrics',
43
43
  body: {
44
44
  metrics: payload
45
- }
45
+ },
46
+ waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout
46
47
  });
47
48
  },
48
49
  handleHttpSuccess: function handleHttpSuccess(res) {
@@ -1 +1 @@
1
- {"version":3,"names":["sym","MetricsBatcher","Batcher","extend","namespace","prepareItem","item","env","process","NODE_ENV","appType","config","time","version","webex","resolve","prepareRequest","queue","map","postTime","submitHttpRequest","payload","request","method","service","resource","body","metrics","handleHttpSuccess","res","all","options","acceptItem","handleHttpError","reason","WebexHttpError","NetworkOrCORSError","logger","warn","delay","nextDelay","batcherRetryPlateau","safeSetTimeout","rerequest","prototype","getDeferredForRequest","then","defer","req","enqueue","bounce","catch","reject","fingerprintRequest","fingerprintResponse"],"sources":["batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Batcher, WebexHttpError} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\n\nconst sym = Symbol('metric id');\n\nconst MetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Keep non-prod data out of metrics\n const env = process.env.NODE_ENV === 'production' ? null : 'TEST';\n\n item.appType = item.appType || this.config.appType;\n item.env = item.env || env;\n item.time = item.time || Date.now();\n item.version = item.version || this.webex.version;\n\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(\n queue.map((item) => {\n item.postTime = item.postTime || Date.now();\n\n return item;\n })\n );\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'metrics',\n body: {\n metrics: payload,\n },\n });\n },\n\n handleHttpSuccess(res) {\n return Promise.all(res.options.body.metrics.map((item) => this.acceptItem(item)));\n },\n\n handleHttpError(reason) {\n if (reason instanceof WebexHttpError.NetworkOrCORSError) {\n this.logger.warn(\n 'metrics-batcher: received network error submitting metrics, reenqueuing payload'\n );\n\n return Promise.all(\n reason.options.body.metrics.map(\n (item) =>\n new Promise((resolve) => {\n const delay = item[sym].nextDelay;\n\n if (delay < this.config.batcherRetryPlateau) {\n item[sym].nextDelay *= 2;\n }\n safeSetTimeout(() => {\n resolve(this.rerequest(item));\n }, delay);\n })\n )\n );\n }\n\n return Reflect.apply(Batcher.prototype.handleHttpError, this, [reason]);\n },\n\n rerequest(item) {\n return Promise.all([this.getDeferredForRequest(item), this.prepareItem(item)]).then(\n ([defer, req]) => {\n this.enqueue(req)\n .then(() => this.bounce())\n .catch((reason) => defer.reject(reason));\n }\n );\n },\n\n fingerprintRequest(item) {\n item[sym] = item[sym] || {\n nextDelay: 1000,\n };\n\n return Promise.resolve(item[sym]);\n },\n\n fingerprintResponse(item) {\n return Promise.resolve(item[sym]);\n },\n});\n\nexport default MetricsBatcher;\n"],"mappings":"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"}
1
+ {"version":3,"names":["sym","MetricsBatcher","Batcher","extend","namespace","prepareItem","item","env","process","NODE_ENV","appType","config","time","version","webex","resolve","prepareRequest","queue","map","postTime","submitHttpRequest","payload","request","method","service","resource","body","metrics","waitForServiceTimeout","handleHttpSuccess","res","all","options","acceptItem","handleHttpError","reason","WebexHttpError","NetworkOrCORSError","logger","warn","delay","nextDelay","batcherRetryPlateau","safeSetTimeout","rerequest","prototype","getDeferredForRequest","then","defer","req","enqueue","bounce","catch","reject","fingerprintRequest","fingerprintResponse"],"sources":["batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Batcher, WebexHttpError} from '@webex/webex-core';\nimport {safeSetTimeout} from '@webex/common-timers';\n\nconst sym = Symbol('metric id');\n\nconst MetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Keep non-prod data out of metrics\n const env = process.env.NODE_ENV === 'production' ? null : 'TEST';\n\n item.appType = item.appType || this.config.appType;\n item.env = item.env || env;\n item.time = item.time || Date.now();\n item.version = item.version || this.webex.version;\n\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(\n queue.map((item) => {\n item.postTime = item.postTime || Date.now();\n\n return item;\n })\n );\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'metrics',\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n });\n },\n\n handleHttpSuccess(res) {\n return Promise.all(res.options.body.metrics.map((item) => this.acceptItem(item)));\n },\n\n handleHttpError(reason) {\n if (reason instanceof WebexHttpError.NetworkOrCORSError) {\n this.logger.warn(\n 'metrics-batcher: received network error submitting metrics, reenqueuing payload'\n );\n\n return Promise.all(\n reason.options.body.metrics.map(\n (item) =>\n new Promise((resolve) => {\n const delay = item[sym].nextDelay;\n\n if (delay < this.config.batcherRetryPlateau) {\n item[sym].nextDelay *= 2;\n }\n safeSetTimeout(() => {\n resolve(this.rerequest(item));\n }, delay);\n })\n )\n );\n }\n\n return Reflect.apply(Batcher.prototype.handleHttpError, this, [reason]);\n },\n\n rerequest(item) {\n return Promise.all([this.getDeferredForRequest(item), this.prepareItem(item)]).then(\n ([defer, req]) => {\n this.enqueue(req)\n .then(() => this.bounce())\n .catch((reason) => defer.reject(reason));\n }\n );\n },\n\n fingerprintRequest(item) {\n item[sym] = item[sym] || {\n nextDelay: 1000,\n };\n\n return Promise.resolve(item[sym]);\n },\n\n fingerprintResponse(item) {\n return Promise.resolve(item[sym]);\n },\n});\n\nexport default MetricsBatcher;\n"],"mappings":"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"}
@@ -50,7 +50,8 @@ var CallDiagnosticEventsBatcher = _batcher.default.extend({
50
50
  resource: 'clientmetrics',
51
51
  body: {
52
52
  metrics: payload
53
- }
53
+ },
54
+ waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout
54
55
  }).then(function (res) {
55
56
  _this.webex.logger.log(_config.CALL_DIAGNOSTIC_LOG_IDENTIFIER, "CallDiagnosticEventsBatcher: @submitHttpRequest#".concat(batchId, ". Request successful:"), "response:", res);
56
57
  return res;
@@ -1 +1 @@
1
- {"version":3,"names":["CallDiagnosticEventsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareDiagnosticMetricItem","webex","prepareRequest","queue","forEach","eventPayload","originTime","sent","Date","toISOString","submitHttpRequest","payload","batchId","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","request","method","service","resource","body","metrics","then","res","catch","err","error","generateCommonErrorMetadata","reject"],"sources":["call-diagnostic-metrics-batcher.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {uniqueId} from 'lodash';\nimport Batcher from '../batcher';\nimport {prepareDiagnosticMetricItem} from './call-diagnostic-metrics.util';\nimport {CALL_DIAGNOSTIC_LOG_IDENTIFIER} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * Prepare item\n * @param item\n * @returns\n */\n prepareItem(item) {\n return Promise.resolve(prepareDiagnosticMetricItem(this.webex, item));\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param queue\n * @returns\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param payload\n * @returns\n */\n submitHttpRequest(payload) {\n const batchId = uniqueId('call-diagnostic-metrics-batch-');\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Sending the request:`,\n 'payload:',\n payload\n );\n\n return this.webex\n .request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n })\n .then((res) => {\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request successful:`,\n `response:`,\n res\n );\n\n return res;\n })\n .catch((err) => {\n this.webex.logger.error(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request failed:`,\n `error: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":";;;;;;;;;;AAIA;AACA;AACA;AACA;AAEA,IAAMA,2BAA2B,GAAGC,gBAAO,CAACC,MAAM,CAAC;EACjDC,SAAS,EAAE,SAAS;EAEpB;AACF;AACA;AACA;AACA;EACEC,WAAW,uBAACC,IAAI,EAAE;IAChB,OAAO,iBAAQC,OAAO,CAAC,IAAAC,kDAA2B,EAAC,IAAI,CAACC,KAAK,EAAEH,IAAI,CAAC,CAAC;EACvE,CAAC;EAED;AACF;AACA;AACA;AACA;EACEI,cAAc,0BAACC,KAAK,EAAE;IACpB;IACAA,KAAK,CAACC,OAAO,CAAC,UAACN,IAAI,EAAK;MACtBA,IAAI,CAACO,YAAY,CAACC,UAAU,GAAGR,IAAI,CAACO,YAAY,CAACC,UAAU,IAAI,CAAC,CAAC;MACjER,IAAI,CAACO,YAAY,CAACC,UAAU,CAACC,IAAI,GAAG,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;IAC9D,CAAC,CAAC;IAEF,OAAO,iBAAQV,OAAO,CAACI,KAAK,CAAC;EAC/B,CAAC;EAED;AACF;AACA;AACA;AACA;EACEO,iBAAiB,6BAACC,OAAO,EAAE;IAAA;IACzB,IAAMC,OAAO,GAAG,wBAAS,gCAAgC,CAAC;IAC1D,IAAI,CAACX,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,6BAC1D,UAAU,EACVD,OAAO,CACR;IAED,OAAO,IAAI,CAACV,KAAK,CACde,OAAO,CAAC;MACPC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEV;MACX;IACF,CAAC,CAAC,CACDW,IAAI,CAAC,UAACC,GAAG,EAAK;MACb,KAAI,CAACtB,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,yCAE1DW,GAAG,CACJ;MAED,OAAOA,GAAG;IACZ,CAAC,CAAC,CACDC,KAAK,CAAC,UAACC,GAAG,EAAK;MACd,KAAI,CAACxB,KAAK,CAACY,MAAM,CAACa,KAAK,CACrBX,sCAA8B,4DACqBH,OAAO,yCAChD,IAAAe,kCAA2B,EAACF,GAAG,CAAC,EAC3C;MAED,OAAO,iBAAQG,MAAM,CAACH,GAAG,CAAC;IAC5B,CAAC,CAAC;EACN;AACF,CAAC,CAAC;AAAC,eAEYhC,2BAA2B;AAAA"}
1
+ {"version":3,"names":["CallDiagnosticEventsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareDiagnosticMetricItem","webex","prepareRequest","queue","forEach","eventPayload","originTime","sent","Date","toISOString","submitHttpRequest","payload","batchId","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","request","method","service","resource","body","metrics","waitForServiceTimeout","config","then","res","catch","err","error","generateCommonErrorMetadata","reject"],"sources":["call-diagnostic-metrics-batcher.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {uniqueId} from 'lodash';\nimport Batcher from '../batcher';\nimport {prepareDiagnosticMetricItem} from './call-diagnostic-metrics.util';\nimport {CALL_DIAGNOSTIC_LOG_IDENTIFIER} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * Prepare item\n * @param item\n * @returns\n */\n prepareItem(item) {\n return Promise.resolve(prepareDiagnosticMetricItem(this.webex, item));\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param queue\n * @returns\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param payload\n * @returns\n */\n submitHttpRequest(payload) {\n const batchId = uniqueId('call-diagnostic-metrics-batch-');\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Sending the request:`,\n 'payload:',\n payload\n );\n\n return this.webex\n .request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n })\n .then((res) => {\n this.webex.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request successful:`,\n `response:`,\n res\n );\n\n return res;\n })\n .catch((err) => {\n this.webex.logger.error(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request failed:`,\n `error: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":";;;;;;;;;;AAIA;AACA;AACA;AACA;AAEA,IAAMA,2BAA2B,GAAGC,gBAAO,CAACC,MAAM,CAAC;EACjDC,SAAS,EAAE,SAAS;EAEpB;AACF;AACA;AACA;AACA;EACEC,WAAW,uBAACC,IAAI,EAAE;IAChB,OAAO,iBAAQC,OAAO,CAAC,IAAAC,kDAA2B,EAAC,IAAI,CAACC,KAAK,EAAEH,IAAI,CAAC,CAAC;EACvE,CAAC;EAED;AACF;AACA;AACA;AACA;EACEI,cAAc,0BAACC,KAAK,EAAE;IACpB;IACAA,KAAK,CAACC,OAAO,CAAC,UAACN,IAAI,EAAK;MACtBA,IAAI,CAACO,YAAY,CAACC,UAAU,GAAGR,IAAI,CAACO,YAAY,CAACC,UAAU,IAAI,CAAC,CAAC;MACjER,IAAI,CAACO,YAAY,CAACC,UAAU,CAACC,IAAI,GAAG,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;IAC9D,CAAC,CAAC;IAEF,OAAO,iBAAQV,OAAO,CAACI,KAAK,CAAC;EAC/B,CAAC;EAED;AACF;AACA;AACA;AACA;EACEO,iBAAiB,6BAACC,OAAO,EAAE;IAAA;IACzB,IAAMC,OAAO,GAAG,wBAAS,gCAAgC,CAAC;IAC1D,IAAI,CAACX,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,6BAC1D,UAAU,EACVD,OAAO,CACR;IAED,OAAO,IAAI,CAACV,KAAK,CACde,OAAO,CAAC;MACPC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEV;MACX,CAAC;MACDW,qBAAqB,EAAE,IAAI,CAACrB,KAAK,CAACsB,MAAM,CAACF,OAAO,CAACC;IACnD,CAAC,CAAC,CACDE,IAAI,CAAC,UAACC,GAAG,EAAK;MACb,KAAI,CAACxB,KAAK,CAACY,MAAM,CAACC,GAAG,CACnBC,sCAA8B,4DACqBH,OAAO,yCAE1Da,GAAG,CACJ;MAED,OAAOA,GAAG;IACZ,CAAC,CAAC,CACDC,KAAK,CAAC,UAACC,GAAG,EAAK;MACd,KAAI,CAAC1B,KAAK,CAACY,MAAM,CAACe,KAAK,CACrBb,sCAA8B,4DACqBH,OAAO,yCAChD,IAAAiB,kCAA2B,EAACF,GAAG,CAAC,EAC3C;MAED,OAAO,iBAAQG,MAAM,CAACH,GAAG,CAAC;IAC5B,CAAC,CAAC;EACN;AACF,CAAC,CAAC;AAAC,eAEYlC,2BAA2B;AAAA"}
@@ -13,6 +13,7 @@ _Object$defineProperty(exports, "__esModule", {
13
13
  });
14
14
  exports.default = void 0;
15
15
  var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
16
+ var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));
16
17
  var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
17
18
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
18
19
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
@@ -51,6 +52,8 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
51
52
  // @ts-ignore
52
53
 
53
54
  // to avoid adding @ts-ignore everywhere
55
+ // the default validator before piping an event to the batcher
56
+ // this function can be overridden by the user
54
57
 
55
58
  /**
56
59
  * Constructor
@@ -66,6 +69,12 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
66
69
  // @ts-ignore
67
70
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "callDiagnosticEventsBatcher", void 0);
68
71
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "logger", void 0);
72
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "validator", function (options) {
73
+ return _promise.default.resolve({
74
+ event: options === null || options === void 0 ? void 0 : options.event,
75
+ valid: true
76
+ });
77
+ });
69
78
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "submitToCallDiagnosticsPreLogin", function (event, preLoginId) {
70
79
  // build metrics-a event type
71
80
  // @ts-ignore
@@ -232,7 +241,7 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
232
241
  }
233
242
  if (meeting !== null && meeting !== void 0 && (_meeting$meetingInfo2 = meeting.meetingInfo) !== null && _meeting$meetingInfo2 !== void 0 && _meeting$meetingInfo2.confID) {
234
243
  var _meeting$meetingInfo3;
235
- identifiers.webexConferenceIdStr = (_meeting$meetingInfo3 = meeting.meetingInfo) === null || _meeting$meetingInfo3 === void 0 ? void 0 : _meeting$meetingInfo3.confID;
244
+ identifiers.webexConferenceIdStr = "".concat((_meeting$meetingInfo3 = meeting.meetingInfo) === null || _meeting$meetingInfo3 === void 0 ? void 0 : _meeting$meetingInfo3.confID);
236
245
  }
237
246
  if (meeting !== null && meeting !== void 0 && (_meeting$meetingInfo4 = meeting.meetingInfo) !== null && _meeting$meetingInfo4 !== void 0 && _meeting$meetingInfo4.meetingId) {
238
247
  var _meeting$meetingInfo5;
@@ -244,7 +253,7 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
244
253
  identifiers.mediaAgentGroupId = mediaConnections === null || mediaConnections === void 0 ? void 0 : (_mediaConnections$2 = mediaConnections[0]) === null || _mediaConnections$2 === void 0 ? void 0 : _mediaConnections$2.mediaAgentGroupId;
245
254
  }
246
255
  if (!(identifiers !== null && identifiers !== void 0 && identifiers.webexConferenceIdStr) && webexConferenceIdStr) {
247
- identifiers.webexConferenceIdStr = webexConferenceIdStr;
256
+ identifiers.webexConferenceIdStr = "".concat(webexConferenceIdStr);
248
257
  }
249
258
  if (!(identifiers !== null && identifiers !== void 0 && identifiers.globalMeetingId) && globalMeetingId) {
250
259
  identifiers.globalMeetingId = globalMeetingId;
@@ -368,6 +377,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
368
377
 
369
378
  // append media quality event data to the call diagnostic event
370
379
  var diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);
380
+ this.validator({
381
+ type: 'mqe',
382
+ event: diagnosticEvent
383
+ });
371
384
  this.submitToCallDiagnostics(diagnosticEvent);
372
385
  } else {
373
386
  throw new Error('Media quality events cant be sent outside the context of a meeting. Meeting id is required.');
@@ -670,6 +683,10 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
670
683
  if (options !== null && options !== void 0 && options.preLoginId) {
671
684
  return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options === null || options === void 0 ? void 0 : options.preLoginId);
672
685
  }
686
+ this.validator({
687
+ type: 'ce',
688
+ event: diagnosticEvent
689
+ });
673
690
  return this.submitToCallDiagnostics(diagnosticEvent);
674
691
  }
675
692
 
@@ -733,7 +750,9 @@ var CallDiagnosticMetrics = /*#__PURE__*/function (_StatelessWebexPlugin) {
733
750
  body: {
734
751
  metrics: [diagnosticEvent]
735
752
  },
736
- headers: {}
753
+ headers: {},
754
+ // @ts-ignore
755
+ waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout
737
756
  };
738
757
  if (options.preLoginId) {
739
758
  request.headers = {
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","event","preLoginId","diagnosticEvent","prepareDiagnosticMetricItem","webex","eventPayload","type","originTime","sent","Date","toISOString","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","internal","newMetrics","postPreLoginMetric","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","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","newEnvironment","clientLaunchMethod","Error","mediaConnections","correlationId","webexConferenceIdStr","globalMeetingId","identifiers","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","confID","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","eventId","uuid","v4","triggered","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","prepareDiagnosticEvent","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","serviceErrorName","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","errorData","errorName","rawError","isBrowserMediaErrorName","getErrorPayloadForClientErrorCode","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","body","code","reason","reasonCode","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","isMeetingInfoServiceError","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","isNetworkError","NETWORK_ERROR","errorDescription","message","isUnauthorizedError","AUTHENTICATION_FAILED_CODE","UNKNOWN_ERROR","errors","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","rawErrorMessage","generateCommonErrorMetadata","generatedError","generateClientEventErrorPayload","push","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","submitToCallDiagnosticsPreLogin","finalEvent","request","clientEvent","method","service","resource","headers","authorization","prepareFetchOptions","clientErrorPayload","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 isMeetingInfoServiceError,\n isBrowserMediaErrorName,\n isNetworkError,\n isUnauthorizedError,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n EnvironmentType,\n NewEnvironmentType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientLaunchMethodType,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n ClientEventPayloadError,\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 NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n UNKNOWN_ERROR,\n BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n NETWORK_ERROR,\n AUTHENTICATION_FAILED_CODE,\n} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n clientLaunchMethod?: ClientLaunchMethodType;\n environment?: EnvironmentType;\n newEnvironment?: NewEnvironmentType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n preLoginId?: string;\n globalMeetingId?: string;\n webexConferenceIdStr?: 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 private logger: any; // to avoid adding @ts-ignore everywhere\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.logger = this.webex.logger;\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?.config?.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 if (options?.environment) {\n origin.environment = options.environment;\n }\n\n if (options?.newEnvironment) {\n origin.newEnvironment = options.newEnvironment;\n }\n\n if (options?.clientLaunchMethod) {\n origin.clientInfo.clientLaunchMethod = options.clientLaunchMethod;\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 {\n meeting,\n mediaConnections,\n correlationId,\n webexConferenceIdStr,\n globalMeetingId,\n preLoginId,\n } = options;\n const identifiers: Event['event']['identifiers'] = {\n correlationId: 'unknown',\n };\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 || preLoginId;\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 (meeting?.meetingInfo?.confID) {\n identifiers.webexConferenceIdStr = meeting.meetingInfo?.confID;\n }\n\n if (meeting?.meetingInfo?.meetingId) {\n identifiers.globalMeetingId = meeting.meetingInfo?.meetingId;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (!identifiers?.webexConferenceIdStr && webexConferenceIdStr) {\n identifiers.webexConferenceIdStr = webexConferenceIdStr;\n }\n\n if (!identifiers?.globalMeetingId && globalMeetingId) {\n identifiers.globalMeetingId = globalMeetingId;\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, webexConferenceIdStr, globalMeetingId} = 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 webexConferenceIdStr,\n globalMeetingId,\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 serviceErrorName,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n serviceErrorName?: 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 serviceErrorName ? {errorData: {errorName: serviceErrorName}} : {},\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 if (rawError.name) {\n if (isBrowserMediaErrorName(rawError.name)) {\n return this.getErrorPayloadForClientErrorCode({\n serviceErrorCode: undefined,\n clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],\n serviceErrorName: rawError.name,\n });\n }\n }\n\n const serviceErrorCode =\n rawError?.error?.body?.errorCode ||\n rawError?.body?.errorCode ||\n rawError?.body?.code ||\n rawError?.body?.reason?.reasonCode;\n\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 new locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n }\n\n if (isMeetingInfoServiceError(rawError)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n if (isNetworkError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NETWORK_ERROR,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n if (isUnauthorizedError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: AUTHENTICATION_FAILED_CODE,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n // otherwise return unkown error\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: UNKNOWN_ERROR,\n serviceErrorCode: UNKNOWN_ERROR,\n });\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 errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectInMeeting. Creating in meeting event object.',\n `name: ${name}`\n );\n const {meetingId, mediaConnections, globalMeetingId, webexConferenceIdStr} = 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 `name: ${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 webexConferenceIdStr,\n globalMeetingId,\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 if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\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 errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectPreMeeting. Creating pre meeting event object.',\n `name: ${name}`\n );\n const {correlationId, globalMeetingId, webexConferenceIdStr, preLoginId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n preLoginId,\n globalMeetingId,\n webexConferenceIdStr,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n errors,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\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, rawError} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // check if we need to generate errors\n const errors: ClientEventPayloadError = [];\n\n if (rawError) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Error detected, attempting to map and attach it to the event...',\n `name: ${name}`,\n `rawError: ${generateCommonErrorMetadata(rawError)}`\n );\n\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',\n `generatedError: ${JSON.stringify(generatedError)}`\n );\n }\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options, errors});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options, errors});\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 this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n if (options?.preLoginId) {\n return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);\n }\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 this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitToCallDiagnostics. Preparing to send the request',\n `finalEvent: ${JSON.stringify(finalEvent)}`\n );\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Pre login events are not batched. We make the request directly.\n * @param event\n * @param preLoginId\n * @returns\n */\n public submitToCallDiagnosticsPreLogin = (event: Event, preLoginId?: string): Promise<any> => {\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: event,\n type: ['diagnostic-event'],\n });\n\n // append sent timestamp\n diagnosticEvent.eventPayload.originTime.sent = new Date().toISOString();\n\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticMetrics: @submitToCallDiagnosticsPreLogin. Sending the request:`,\n `diagnosticEvent: ${JSON.stringify(diagnosticEvent)}`\n );\n\n // @ts-ignore\n return this.webex.internal.newMetrics.postPreLoginMetric(diagnosticEvent, preLoginId);\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 this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n\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 const request = {\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n headers: {},\n };\n\n if (options.preLoginId) {\n request.headers = {\n authorization: false,\n 'x-prelogin-userid': options.preLoginId,\n };\n request.resource = 'clientmetrics-prelogin';\n }\n\n // @ts-ignore\n return this.webex.prepareFetchOptions(request);\n }\n\n /**\n * Returns true if the specified serviceErrorCode maps to an expected error.\n * @param {number} serviceErrorCode the service error code\n * @returns {boolean}\n */\n public isServiceErrorExpected(serviceErrorCode: number): boolean {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n const clientErrorPayload = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n return clientErrorPayload?.category === 'expected';\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","CallDiagnosticMetrics","args","options","resolve","event","valid","preLoginId","diagnosticEvent","prepareDiagnosticMetricItem","webex","eventPayload","type","originTime","sent","Date","toISOString","logger","log","CALL_DIAGNOSTIC_LOG_IDENTIFIER","internal","newMetrics","postPreLoginMetric","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","parent","canAuthorize","credentials","isUnverifiedGuest","meetingId","meeting","meetings","meetingCollection","get","meetingInfo","enableConvergedArchitecture","undefined","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","newEnvironment","clientLaunchMethod","Error","mediaConnections","correlationId","webexConferenceIdStr","globalMeetingId","identifiers","device","userId","deviceId","url","orgId","locusUrl","services","locusInfo","fullState","locusId","split","pop","locusStartTime","lastActive","confID","mediaAgentAlias","mediaAgentGroupId","eventData","getOrigin","eventId","uuid","v4","triggered","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","prepareDiagnosticEvent","validator","submitToCallDiagnostics","clientErrorCode","serviceErrorCode","serviceErrorName","error","partialParsedError","CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD","fatal","shownToUser","category","errorCode","errorData","errorName","rawError","isBrowserMediaErrorName","getErrorPayloadForClientErrorCode","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","body","code","reason","reasonCode","SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP","isLocusServiceErrorCode","NEW_LOCUS_ERROR_CLIENT_CODE","isMeetingInfoServiceError","MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE","isNetworkError","NETWORK_ERROR","errorDescription","message","isUnauthorizedError","AUTHENTICATION_FAILED_CODE","UNKNOWN_ERROR","errors","userType","getCurUserType","loginType","getCurLoginType","isConvergedArchitectureEnabled","getIsConvergedArchitectureEnabled","rawErrorMessage","generateCommonErrorMetadata","generatedError","generateClientEventErrorPayload","push","createClientEventObjectInMeeting","createClientEventObjectPreMeeting","prepareClientEvent","submitToCallDiagnosticsPreLogin","finalEvent","request","clientEvent","method","service","resource","headers","waitForServiceTimeout","authorization","prepareFetchOptions","clientErrorPayload","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 isMeetingInfoServiceError,\n isBrowserMediaErrorName,\n isNetworkError,\n isUnauthorizedError,\n} from './call-diagnostic-metrics.util';\nimport {CLIENT_NAME} from '../config';\nimport {\n Event,\n ClientType,\n SubClientType,\n NetworkType,\n EnvironmentType,\n NewEnvironmentType,\n ClientEvent,\n SubmitClientEventOptions,\n MediaQualityEvent,\n SubmitMQEOptions,\n SubmitMQEPayload,\n ClientLaunchMethodType,\n ClientEventError,\n ClientEventPayload,\n ClientInfo,\n ClientEventPayloadError,\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 NEW_LOCUS_ERROR_CLIENT_CODE,\n SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP,\n UNKNOWN_ERROR,\n BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,\n MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n NETWORK_ERROR,\n AUTHENTICATION_FAILED_CODE,\n} from './config';\nimport {generateCommonErrorMetadata} from '../utils';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\ntype GetOriginOptions = {\n clientType: ClientType;\n subClientType: SubClientType;\n networkType?: NetworkType;\n clientLaunchMethod?: ClientLaunchMethodType;\n environment?: EnvironmentType;\n newEnvironment?: NewEnvironmentType;\n};\n\ntype GetIdentifiersOptions = {\n meeting?: any;\n mediaConnections?: any[];\n correlationId?: string;\n preLoginId?: string;\n globalMeetingId?: string;\n webexConferenceIdStr?: 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 private logger: any; // to avoid adding @ts-ignore everywhere\n // the default validator before piping an event to the batcher\n // this function can be overridden by the user\n public validator: (options: {\n type: 'mqe' | 'ce';\n event: Event;\n }) => Promise<{event: Event; valid: boolean}> = (options: {type: 'mqe' | 'ce'; event: Event}) =>\n Promise.resolve({event: options?.event, valid: true});\n\n /**\n * Constructor\n * @param args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.logger = this.webex.logger;\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?.config?.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 if (options?.environment) {\n origin.environment = options.environment;\n }\n\n if (options?.newEnvironment) {\n origin.newEnvironment = options.newEnvironment;\n }\n\n if (options?.clientLaunchMethod) {\n origin.clientInfo.clientLaunchMethod = options.clientLaunchMethod;\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 {\n meeting,\n mediaConnections,\n correlationId,\n webexConferenceIdStr,\n globalMeetingId,\n preLoginId,\n } = options;\n const identifiers: Event['event']['identifiers'] = {\n correlationId: 'unknown',\n };\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 || preLoginId;\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 (meeting?.meetingInfo?.confID) {\n identifiers.webexConferenceIdStr = `${meeting.meetingInfo?.confID}`;\n }\n\n if (meeting?.meetingInfo?.meetingId) {\n identifiers.globalMeetingId = meeting.meetingInfo?.meetingId;\n }\n\n if (mediaConnections) {\n identifiers.mediaAgentAlias = mediaConnections?.[0]?.mediaAgentAlias;\n identifiers.mediaAgentGroupId = mediaConnections?.[0]?.mediaAgentGroupId;\n }\n\n if (!identifiers?.webexConferenceIdStr && webexConferenceIdStr) {\n identifiers.webexConferenceIdStr = `${webexConferenceIdStr}`;\n }\n\n if (!identifiers?.globalMeetingId && globalMeetingId) {\n identifiers.globalMeetingId = globalMeetingId;\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, webexConferenceIdStr, globalMeetingId} = 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 webexConferenceIdStr,\n globalMeetingId,\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.validator({type: 'mqe', event: diagnosticEvent});\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 serviceErrorName,\n }: {\n clientErrorCode: number;\n serviceErrorCode: any;\n serviceErrorName?: 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 serviceErrorName ? {errorData: {errorName: serviceErrorName}} : {},\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 if (rawError.name) {\n if (isBrowserMediaErrorName(rawError.name)) {\n return this.getErrorPayloadForClientErrorCode({\n serviceErrorCode: undefined,\n clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],\n serviceErrorName: rawError.name,\n });\n }\n }\n\n const serviceErrorCode =\n rawError?.error?.body?.errorCode ||\n rawError?.body?.errorCode ||\n rawError?.body?.code ||\n rawError?.body?.reason?.reasonCode;\n\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 new locus err\n if (isLocusServiceErrorCode(serviceErrorCode)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n }\n\n if (isMeetingInfoServiceError(rawError)) {\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,\n serviceErrorCode,\n });\n }\n\n if (isNetworkError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: NETWORK_ERROR,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n if (isUnauthorizedError(rawError)) {\n const payload = this.getErrorPayloadForClientErrorCode({\n clientErrorCode: AUTHENTICATION_FAILED_CODE,\n serviceErrorCode,\n });\n payload.errorDescription = rawError.message;\n\n return payload;\n }\n\n // otherwise return unkown error\n return this.getErrorPayloadForClientErrorCode({\n clientErrorCode: UNKNOWN_ERROR,\n serviceErrorCode: UNKNOWN_ERROR,\n });\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 errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectInMeeting. Creating in meeting event object.',\n `name: ${name}`\n );\n const {meetingId, mediaConnections, globalMeetingId, webexConferenceIdStr} = 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 `name: ${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 webexConferenceIdStr,\n globalMeetingId,\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 if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\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 errors,\n }: {\n name: ClientEvent['name'];\n options?: SubmitClientEventOptions;\n errors?: ClientEventPayloadError;\n }) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @createClientEventObjectPreMeeting. Creating pre meeting event object.',\n `name: ${name}`\n );\n const {correlationId, globalMeetingId, webexConferenceIdStr, preLoginId} = options;\n\n // grab identifiers\n const identifiers = this.getIdentifiers({\n correlationId,\n preLoginId,\n globalMeetingId,\n webexConferenceIdStr,\n });\n\n // create client event object\n const clientEventObject: ClientEvent['payload'] = {\n name,\n errors,\n canProceed: true,\n identifiers,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n loginType: this.getCurLoginType(),\n };\n\n if (options?.rawError?.message) {\n // @ts-ignore\n clientEventObject.eventData.rawErrorMessage = options?.rawError?.message;\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, rawError} = options;\n let clientEventObject: ClientEvent['payload'];\n\n // check if we need to generate errors\n const errors: ClientEventPayloadError = [];\n\n if (rawError) {\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Error detected, attempting to map and attach it to the event...',\n `name: ${name}`,\n `rawError: ${generateCommonErrorMetadata(rawError)}`\n );\n\n const generatedError = this.generateClientEventErrorPayload(rawError);\n if (generatedError) {\n errors.push(generatedError);\n }\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',\n `generatedError: ${JSON.stringify(generatedError)}`\n );\n }\n\n // events that will most likely happen in join phase\n if (meetingId) {\n clientEventObject = this.createClientEventObjectInMeeting({name, options, errors});\n } else if (correlationId) {\n // any pre join events or events that are outside the meeting.\n clientEventObject = this.createClientEventObjectPreMeeting({name, options, errors});\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 this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitClientEvent. Submit Client Event CA event.',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n const diagnosticEvent = this.prepareClientEvent({name, payload, options});\n\n if (options?.preLoginId) {\n return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);\n }\n\n this.validator({type: 'ce', event: diagnosticEvent});\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 this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @submitToCallDiagnostics. Preparing to send the request',\n `finalEvent: ${JSON.stringify(finalEvent)}`\n );\n\n return this.callDiagnosticEventsBatcher.request(finalEvent);\n }\n\n /**\n * Pre login events are not batched. We make the request directly.\n * @param event\n * @param preLoginId\n * @returns\n */\n public submitToCallDiagnosticsPreLogin = (event: Event, preLoginId?: string): Promise<any> => {\n // build metrics-a event type\n // @ts-ignore\n const diagnosticEvent = prepareDiagnosticMetricItem(this.webex, {\n eventPayload: event,\n type: ['diagnostic-event'],\n });\n\n // append sent timestamp\n diagnosticEvent.eventPayload.originTime.sent = new Date().toISOString();\n\n this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n `CallDiagnosticMetrics: @submitToCallDiagnosticsPreLogin. Sending the request:`,\n `diagnosticEvent: ${JSON.stringify(diagnosticEvent)}`\n );\n\n // @ts-ignore\n return this.webex.internal.newMetrics.postPreLoginMetric(diagnosticEvent, preLoginId);\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 this.logger.log(\n CALL_DIAGNOSTIC_LOG_IDENTIFIER,\n 'CallDiagnosticMetrics: @buildClientEventFetchRequestOptions. Building request options object for fetch()...',\n `name: ${name}`,\n `payload: ${JSON.stringify(payload)}`,\n `options: ${JSON.stringify(options)}`\n );\n\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 const request = {\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: [diagnosticEvent],\n },\n headers: {},\n // @ts-ignore\n waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout,\n };\n\n if (options.preLoginId) {\n request.headers = {\n authorization: false,\n 'x-prelogin-userid': options.preLoginId,\n };\n request.resource = 'clientmetrics-prelogin';\n }\n\n // @ts-ignore\n return this.webex.prepareFetchOptions(request);\n }\n\n /**\n * Returns true if the specified serviceErrorCode maps to an expected error.\n * @param {number} serviceErrorCode the service error code\n * @returns {boolean}\n */\n public isServiceErrorExpected(serviceErrorCode: number): boolean {\n const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];\n const clientErrorPayload = CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD[clientErrorCode];\n\n return clientErrorPayload?.category === 'expected';\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;AACA;AACA;AAEA;AAEA;AAYA;AAmBA;AACA;AAYA;AAAqD;AAAA;AAAA;AAAA;AAErD,wBAA0D,IAAAA,wBAAgB,GAAE;EAArEC,YAAY,qBAAZA,YAAY;EAAEC,cAAc,qBAAdA,cAAc;EAAEC,iBAAiB,qBAAjBA,iBAAiB;AAoBtD;AACA;AACA;AACA;AACA;AAJA,IAKqBC,qBAAqB;EAAA;EAAA;EACxC;;EAEqB;EACrB;EACA;;EAOA;AACF;AACA;AACA;EACE,iCAAqB;IAAA;IAAA;IAAA,kCAANC,IAAI;MAAJA,IAAI;IAAA;IACjB,gDAASA,IAAI;IACb;IAAA;IAAA;IAAA,wFAT8C,UAACC,OAA2C;MAAA,OAC1F,iBAAQC,OAAO,CAAC;QAACC,KAAK,EAAEF,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEE,KAAK;QAAEC,KAAK,EAAE;MAAI,CAAC,CAAC;IAAA;IAAA,8GAiqBd,UAACD,KAAY,EAAEE,UAAmB,EAAmB;MAC5F;MACA;MACA,IAAMC,eAAe,GAAG,IAAAC,kDAA2B,EAAC,MAAKC,KAAK,EAAE;QAC9DC,YAAY,EAAEN,KAAK;QACnBO,IAAI,EAAE,CAAC,kBAAkB;MAC3B,CAAC,CAAC;;MAEF;MACAJ,eAAe,CAACG,YAAY,CAACE,UAAU,CAACC,IAAI,GAAG,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;MAEvE,MAAKC,MAAM,CAACC,GAAG,CACbC,uCAA8B,8GAEV,wBAAeX,eAAe,CAAC,EACpD;;MAED;MACA,OAAO,MAAKE,KAAK,CAACU,QAAQ,CAACC,UAAU,CAACC,kBAAkB,CAACd,eAAe,EAAED,UAAU,CAAC;IACvF,CAAC;IA3qBC,MAAKU,MAAM,GAAG,MAAKP,KAAK,CAACO,MAAM;IAC/B;IACA,MAAKM,2BAA2B,GAAG,IAAIC,qCAA2B,CAAC,CAAC,CAAC,EAAE;MAACC,MAAM,EAAE,MAAKf;IAAK,CAAC,CAAC;IAAC;EAC/F;;EAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,2BAAkB;MAChB;MACA,IAAI,IAAI,CAACA,KAAK,CAACgB,YAAY,EAAE;QAC3B;QACA,OAAO,IAAI,CAAChB,KAAK,CAACiB,WAAW,CAACC,iBAAiB,GAAG,kBAAkB,GAAG,UAAU;MACnF;MAEA,OAAO,IAAI;IACb;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,iDAA8E;MAAA,IAA3CC,SAAS,QAATA,SAAS;MAC1C,IAAIA,SAAS,EAAE;QAAA;QACb;QACA,IAAMC,OAAO,GAAG,IAAI,CAACpB,KAAK,CAACqB,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;QAEpE,OAAOC,OAAO,aAAPA,OAAO,+CAAPA,OAAO,CAAEI,WAAW,yDAApB,qBAAsBC,2BAA2B;MAC1D;MAEA,OAAOC,SAAS;IAClB;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA,OAMA,mBAAUjC,OAAyB,EAAE0B,SAAkB,EAAE;MAAA;MACvD,IAAMQ,iBAA6B,GACjC;MAAA,yBACA,IAAI,CAAC3B,KAAK,CAACqB,QAAQ,CAACO,MAAM,oFAA1B,sBAA4BC,OAAO,2DAAnC,uBAAqCC,UAAU;MACjD,IAAMC,oBAAmC,GACvC;MAAA,0BACA,IAAI,CAAC/B,KAAK,CAACqB,QAAQ,CAACO,MAAM,qFAA1B,uBAA4BC,OAAO,2DAAnC,uBAAqCG,aAAa;MACpD;MACA,IAAMC,qBAA6B,6BAAG,IAAI,CAACjC,KAAK,CAACqB,QAAQ,CAACO,MAAM,qFAA1B,uBAA4BC,OAAO,2DAAnC,uBAAqCK,aAAa;MACxF;MACA,IAAMC,uBAAuB,aAAMC,mBAAW,cAAI,IAAI,CAACpC,KAAK,CAACqC,OAAO,CAAE;MAEtE,IAAIC,eAAkE,GAAG,CAAC,CAAC;;MAE3E;MACA,IAAIL,qBAAqB,EAAE;QACzBK,eAAe,GAAG,IAAAC,6CAAsB,EAACN,qBAAqB,CAAC;MACjE;MAEA,IACGN,iBAAiB,IAAII,oBAAoB,IACzCtC,OAAO,CAACqC,UAAU,IAAIrC,OAAO,CAACuC,aAAc,EAC7C;QAAA;QACA,IAAMQ,MAAuB,GAAG;UAC9BC,IAAI,EAAE,UAAU;UAChBC,WAAW,EAAE,CAAAjD,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEiD,WAAW,KAAI,SAAS;UAC9CC,SAAS,EAAE,IAAAC,wCAAiB,EAAC;YAC3B;YACAC,UAAU,0BAAE,IAAI,CAAC7C,KAAK,CAACqB,QAAQ,mFAAnB,qBAAqBO,MAAM,qFAA3B,uBAA6BC,OAAO,2DAApC,uBAAsCgB,UAAU;YAC5D;YACAC,YAAY,EAAE,IAAI,CAAC9C,KAAK,CAACqC;UAC3B,CAAC,CAAC;UACFU,UAAU;YACRjB,UAAU,EAAE,CAAArC,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEqC,UAAU,KAAIH,iBAAiB;YACpDO,aAAa,EAAED,qBAAqB,IAAIE;UAAuB,GAC5DG,eAAe;YAClBU,kBAAkB;YAChB;YACA,IAAAC,yCAAkB,4BAAC,IAAI,CAACjD,KAAK,CAACqB,QAAQ,CAAC6B,WAAW,2DAA/B,uBAAiCC,aAAa,CAAC,IAAIzB,SAAS;YACjF0B,SAAS,EAAEhE,YAAY,EAAE,IAAI,SAAS;YACtC4C,aAAa,EAAE,CAAAvC,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEuC,aAAa,KAAID,oBAAoB;YAC7DsB,EAAE,EAAE,IAAAC,wCAAiB,GAAE;YACvBC,OAAO,EAAElE,cAAc,EAAE;YACzBmE,cAAc,EAAElE,iBAAiB;UAAE;QAEvC,CAAC;QAED,IAAI6B,SAAS,EAAE;UACb;UACA,IAAMC,OAAO,GAAG,IAAI,CAACpB,KAAK,CAACqB,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;UACpE,IAAIC,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEqC,WAAW,EAAE;YACxBjB,MAAM,CAACiB,WAAW,GAAGrC,OAAO,CAACqC,WAAW;UAC1C;QACF;QAEA,IAAIhE,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEgE,WAAW,EAAE;UACxBjB,MAAM,CAACiB,WAAW,GAAGhE,OAAO,CAACgE,WAAW;QAC1C;QAEA,IAAIhE,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEiE,cAAc,EAAE;UAC3BlB,MAAM,CAACkB,cAAc,GAAGjE,OAAO,CAACiE,cAAc;QAChD;QAEA,IAAIjE,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEkE,kBAAkB,EAAE;UAC/BnB,MAAM,CAACO,UAAU,CAACY,kBAAkB,GAAGlE,OAAO,CAACkE,kBAAkB;QACnE;QAEA,OAAOnB,MAAM;MACf;MAEA,MAAM,IAAIoB,KAAK,CAAC,iDAAiD,CAAC;IACpE;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,wBAAenE,OAA8B,EAAE;MAAA;MAC7C,IACE2B,OAAO,GAML3B,OAAO,CANT2B,OAAO;QACPyC,gBAAgB,GAKdpE,OAAO,CALToE,gBAAgB;QAChBC,aAAa,GAIXrE,OAAO,CAJTqE,aAAa;QACbC,oBAAoB,GAGlBtE,OAAO,CAHTsE,oBAAoB;QACpBC,eAAe,GAEbvE,OAAO,CAFTuE,eAAe;QACfnE,UAAU,GACRJ,OAAO,CADTI,UAAU;MAEZ,IAAMoE,WAA0C,GAAG;QACjDH,aAAa,EAAE;MACjB,CAAC;MAED,IAAI1C,OAAO,EAAE;QACX6C,WAAW,CAACH,aAAa,GAAG1C,OAAO,CAAC0C,aAAa;MACnD;MAEA,IAAIA,aAAa,EAAE;QACjBG,WAAW,CAACH,aAAa,GAAGA,aAAa;MAC3C;MACA;MACA,IAAI,IAAI,CAAC9D,KAAK,CAACU,QAAQ,EAAE;QACvB;QACA,IAAOwD,MAAM,GAAI,IAAI,CAAClE,KAAK,CAACU,QAAQ,CAA7BwD,MAAM;QACbD,WAAW,CAACE,MAAM,GAAGD,MAAM,CAACC,MAAM,IAAItE,UAAU;QAChDoE,WAAW,CAACG,QAAQ,GAAGF,MAAM,CAACG,GAAG;QACjCJ,WAAW,CAACK,KAAK,GAAGJ,MAAM,CAACI,KAAK;QAChC;QACAL,WAAW,CAACM,QAAQ,GAAG,IAAI,CAACvE,KAAK,CAACU,QAAQ,CAAC8D,QAAQ,CAACjD,GAAG,CAAC,OAAO,CAAC;MAClE;MAEA,IAAIH,OAAO,aAAPA,OAAO,qCAAPA,OAAO,CAAEqD,SAAS,+CAAlB,mBAAoBC,SAAS,EAAE;QACjCT,WAAW,CAACM,QAAQ,GAAGnD,OAAO,CAACmD,QAAQ;QACvCN,WAAW,CAACU,OAAO,GAAGvD,OAAO,CAACmD,QAAQ,IAAInD,OAAO,CAACmD,QAAQ,CAACK,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,EAAE;QAC3EZ,WAAW,CAACa,cAAc,GACxB1D,OAAO,CAACqD,SAAS,CAACC,SAAS,IAAItD,OAAO,CAACqD,SAAS,CAACC,SAAS,CAACK,UAAU;MACzE;MAEA,IAAI3D,OAAO,aAAPA,OAAO,wCAAPA,OAAO,CAAEI,WAAW,kDAApB,sBAAsBwD,MAAM,EAAE;QAAA;QAChCf,WAAW,CAACF,oBAAoB,sCAAM3C,OAAO,CAACI,WAAW,0DAAnB,sBAAqBwD,MAAM,CAAE;MACrE;MAEA,IAAI5D,OAAO,aAAPA,OAAO,wCAAPA,OAAO,CAAEI,WAAW,kDAApB,sBAAsBL,SAAS,EAAE;QAAA;QACnC8C,WAAW,CAACD,eAAe,4BAAG5C,OAAO,CAACI,WAAW,0DAAnB,sBAAqBL,SAAS;MAC9D;MAEA,IAAI0C,gBAAgB,EAAE;QAAA;QACpBI,WAAW,CAACgB,eAAe,GAAGpB,gBAAgB,aAAhBA,gBAAgB,6CAAhBA,gBAAgB,CAAG,CAAC,CAAC,uDAArB,mBAAuBoB,eAAe;QACpEhB,WAAW,CAACiB,iBAAiB,GAAGrB,gBAAgB,aAAhBA,gBAAgB,8CAAhBA,gBAAgB,CAAG,CAAC,CAAC,wDAArB,oBAAuBqB,iBAAiB;MAC1E;MAEA,IAAI,EAACjB,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEF,oBAAoB,KAAIA,oBAAoB,EAAE;QAC9DE,WAAW,CAACF,oBAAoB,aAAMA,oBAAoB,CAAE;MAC9D;MAEA,IAAI,EAACE,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAED,eAAe,KAAIA,eAAe,EAAE;QACpDC,WAAW,CAACD,eAAe,GAAGA,eAAe;MAC/C;MAEA,IAAIC,WAAW,CAACH,aAAa,KAAKpC,SAAS,EAAE;QAC3C,MAAM,IAAIkC,KAAK,CAAC,oCAAoC,CAAC;MACvD;MAEA,OAAOK,WAAW;IACpB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,gCAAuBkB,SAAyB,EAAE1F,OAAY,EAAE;MAAA;MAC9D,IAAO0B,SAAS,GAAI1B,OAAO,CAApB0B,SAAS;MAChB,IAAMqB,MAAM,GAAG,IAAI,CAAC4C,SAAS,CAAC3F,OAAO,EAAE0B,SAAS,CAAC;MAEjD,IAAMxB,KAAY,GAAG;QACnB0F,OAAO,EAAEC,aAAI,CAACC,EAAE,EAAE;QAClBlD,OAAO,EAAE,CAAC;QACVG,MAAM,EAANA,MAAM;QACNrC,UAAU,EAAE;UACVqF,SAAS,EAAE,IAAInF,IAAI,EAAE,CAACC,WAAW,EAAE;UACnC;UACAF,IAAI,EAAE;QACR,CAAC;QACD;QACAqF,iBAAiB,6BAAE,IAAI,CAACzF,KAAK,CAACqB,QAAQ,CAAC6B,WAAW,4DAA/B,wBAAiCwC,WAAW;QAC/D/F,KAAK,EAAEwF;MACT,CAAC;;MAED;MACA;MACA;MACA,IAAIA,SAAS,CAAC1C,IAAI,KAAK,2BAA2B,EAAE;QAClD,IAAAkD,gDAAyB,EAAChG,KAAK,CAAC;MAClC;MAEA,OAAOA,KAAK;IACd;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,8BAA4B;MAC1B,MAAMiE,KAAK,CAAC,iBAAiB,CAAC;IAChC;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,0BAQG;MAAA,IAPDnB,IAAI,SAAJA,IAAI;QACJmD,OAAO,SAAPA,OAAO;QACPnG,OAAO,SAAPA,OAAO;MAMP,IAAO0B,SAAS,GAA6D1B,OAAO,CAA7E0B,SAAS;QAAE0C,gBAAgB,GAA2CpE,OAAO,CAAlEoE,gBAAgB;QAAEE,oBAAoB,GAAqBtE,OAAO,CAAhDsE,oBAAoB;QAAEC,eAAe,GAAIvE,OAAO,CAA1BuE,eAAe;;MAEzE;MACA,IAAI7C,SAAS,EAAE;QACb;QACA,IAAMC,OAAO,GAAG,IAAI,CAACpB,KAAK,CAACqB,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;QAEpE,IAAI,CAACC,OAAO,EAAE;UACZyE,OAAO,CAACC,IAAI,CACV,iDAAiD,mBACvCrD,IAAI,0BAAgBtB,SAAS,EACxC;UACD;UACA,IAAI,CAACnB,KAAK,CAACU,QAAQ,CAACmB,OAAO,CAACkE,mBAAmB,CAACC,6CAAoC,EAAE;YACpFC,MAAM,EAAE;cACN9E,SAAS,EAATA,SAAS;cACTsB,IAAI,EAAJA;YACF;UACF,CAAC,CAAC;UAEF;QACF;;QAEA;QACA,IAAMwB,WAAW,GAAG,IAAI,CAACiC,cAAc,CAAC;UACtC9E,OAAO,EAAPA,OAAO;UACPyC,gBAAgB,EAAEzC,OAAO,CAACyC,gBAAgB,IAAIA,gBAAgB;UAC9DE,oBAAoB,EAApBA,oBAAoB;UACpBC,eAAe,EAAfA;QACF,CAAC,CAAC;;QAEF;QACA,IAAImC,iBAA+C,GAAG;UACpD1D,IAAI,EAAJA,IAAI;UACJ2D,UAAU,EAAE,IAAI;UAChBnC,WAAW,EAAXA,WAAW;UACXkB,SAAS,EAAE;YACTkB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;UACnC,CAAC;UACDC,SAAS,EAAEb,OAAO,CAACa,SAAS;UAC5BC,cAAc,EAAE;YACdC,uBAAuB,EAAEvE,mBAAW;YACpC;YACAwE,0BAA0B,EAAE,IAAI,CAAC5G,KAAK,CAACqC,OAAO;YAC9CwE,uBAAuB,EAAExH,cAAc,EAAE,IAAI,SAAS;YACtDyH,0BAA0B,EAAE1H,YAAY,EAAE,IAAI,SAAS;YACvD2H,SAAS,EAAE,IAAI1G,IAAI,EAAE,CAACC,WAAW;UACnC;QACF,CAAC;;QAED;QACA6F,iBAAiB,GAAG,qBAAMA,iBAAiB,EAAEP,OAAO,CAAC;;QAErD;QACA,IAAM9F,eAAe,GAAG,IAAI,CAACkH,sBAAsB,CAACb,iBAAiB,EAAE1G,OAAO,CAAC;QAC/E,IAAI,CAACwH,SAAS,CAAC;UAAC/G,IAAI,EAAE,KAAK;UAAEP,KAAK,EAAEG;QAAe,CAAC,CAAC;QACrD,IAAI,CAACoH,uBAAuB,CAACpH,eAAe,CAAC;MAC/C,CAAC,MAAM;QACL,MAAM,IAAI8D,KAAK,CACb,6FAA6F,CAC9F;MACH;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,kDAQqB;MAAA,IAPnBuD,eAAe,SAAfA,eAAe;QACfC,gBAAgB,SAAhBA,gBAAgB;QAChBC,gBAAgB,SAAhBA,gBAAgB;MAMhB,IAAIC,KAAuB;MAE3B,IAAIH,eAAe,EAAE;QACnB,IAAMI,kBAAkB,GAAGC,2CAAkC,CAACL,eAAe,CAAC;QAE9E,IAAII,kBAAkB,EAAE;UACtBD,KAAK,GAAG,qBACN;YAACG,KAAK,EAAE,IAAI;YAAEC,WAAW,EAAE,KAAK;YAAEjF,IAAI,EAAE,OAAO;YAAEkF,QAAQ,EAAE;UAAO,CAAC;UAAE;UACrE;YAACC,SAAS,EAAET;UAAe,CAAC,EAC5BE,gBAAgB,GAAG;YAACQ,SAAS,EAAE;cAACC,SAAS,EAAET;YAAgB;UAAC,CAAC,GAAG,CAAC,CAAC,EAClE;YAACD,gBAAgB,EAAhBA;UAAgB,CAAC,EAClBG,kBAAkB,CACnB;UAED,OAAOD,KAAK;QACd;MACF;MAEA,OAAO5F,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,yCAAgCqG,QAAa,EAAE;MAAA;MAC7C,IAAIA,QAAQ,CAACtF,IAAI,EAAE;QACjB,IAAI,IAAAuF,8CAAuB,EAACD,QAAQ,CAACtF,IAAI,CAAC,EAAE;UAC1C,OAAO,IAAI,CAACwF,iCAAiC,CAAC;YAC5Cb,gBAAgB,EAAE1F,SAAS;YAC3ByF,eAAe,EAAEe,2DAAkD,CAACH,QAAQ,CAACtF,IAAI,CAAC;YAClF4E,gBAAgB,EAAEU,QAAQ,CAACtF;UAC7B,CAAC,CAAC;QACJ;MACF;MAEA,IAAM2E,gBAAgB,GACpB,CAAAW,QAAQ,aAARA,QAAQ,0CAARA,QAAQ,CAAET,KAAK,4EAAf,gBAAiBa,IAAI,yDAArB,qBAAuBP,SAAS,MAChCG,QAAQ,aAARA,QAAQ,yCAARA,QAAQ,CAAEI,IAAI,mDAAd,eAAgBP,SAAS,MACzBG,QAAQ,aAARA,QAAQ,0CAARA,QAAQ,CAAEI,IAAI,oDAAd,gBAAgBC,IAAI,MACpBL,QAAQ,aAARA,QAAQ,0CAARA,QAAQ,CAAEI,IAAI,6EAAd,gBAAgBE,MAAM,0DAAtB,sBAAwBC,UAAU;MAEpC,IAAIlB,gBAAgB,EAAE;QACpB,IAAMD,eAAe,GAAGoB,sDAA6C,CAACnB,gBAAgB,CAAC;QACvF,IAAID,eAAe,EAAE;UACnB,OAAO,IAAI,CAACc,iCAAiC,CAAC;YAACd,eAAe,EAAfA,eAAe;YAAEC,gBAAgB,EAAhBA;UAAgB,CAAC,CAAC;QACpF;;QAEA;QACA,IAAI,IAAAoB,8CAAuB,EAACpB,gBAAgB,CAAC,EAAE;UAC7C,OAAO,IAAI,CAACa,iCAAiC,CAAC;YAC5Cd,eAAe,EAAEsB,oCAA2B;YAC5CrB,gBAAgB,EAAhBA;UACF,CAAC,CAAC;QACJ;MACF;MAEA,IAAI,IAAAsB,gDAAyB,EAACX,QAAQ,CAAC,EAAE;QACvC,OAAO,IAAI,CAACE,iCAAiC,CAAC;UAC5Cd,eAAe,EAAEwB,8CAAqC;UACtDvB,gBAAgB,EAAhBA;QACF,CAAC,CAAC;MACJ;MAEA,IAAI,IAAAwB,qCAAc,EAACb,QAAQ,CAAC,EAAE;QAC5B,IAAMnC,OAAO,GAAG,IAAI,CAACqC,iCAAiC,CAAC;UACrDd,eAAe,EAAE0B,sBAAa;UAC9BzB,gBAAgB,EAAhBA;QACF,CAAC,CAAC;QACFxB,OAAO,CAACkD,gBAAgB,GAAGf,QAAQ,CAACgB,OAAO;QAE3C,OAAOnD,OAAO;MAChB;MAEA,IAAI,IAAAoD,0CAAmB,EAACjB,QAAQ,CAAC,EAAE;QACjC,IAAMnC,QAAO,GAAG,IAAI,CAACqC,iCAAiC,CAAC;UACrDd,eAAe,EAAE8B,mCAA0B;UAC3C7B,gBAAgB,EAAhBA;QACF,CAAC,CAAC;QACFxB,QAAO,CAACkD,gBAAgB,GAAGf,QAAQ,CAACgB,OAAO;QAE3C,OAAOnD,QAAO;MAChB;;MAEA;MACA,OAAO,IAAI,CAACqC,iCAAiC,CAAC;QAC5Cd,eAAe,EAAE+B,sBAAa;QAC9B9B,gBAAgB,EAAE8B;MACpB,CAAC,CAAC;IACJ;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,iDAQG;MAAA;MAAA,IAPDzG,IAAI,SAAJA,IAAI;QACJhD,OAAO,SAAPA,OAAO;QACP0J,MAAM,SAANA,MAAM;MAMN,IAAI,CAAC5I,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,6FAA6F,kBACpFgC,IAAI,EACd;MACD,IAAOtB,SAAS,GAA6D1B,OAAO,CAA7E0B,SAAS;QAAE0C,gBAAgB,GAA2CpE,OAAO,CAAlEoE,gBAAgB;QAAEG,eAAe,GAA0BvE,OAAO,CAAhDuE,eAAe;QAAED,oBAAoB,GAAItE,OAAO,CAA/BsE,oBAAoB;;MAEzE;MACA,IAAM3C,OAAO,GAAG,IAAI,CAACpB,KAAK,CAACqB,QAAQ,CAACC,iBAAiB,CAACC,GAAG,CAACJ,SAAS,CAAC;MAEpE,IAAI,CAACC,OAAO,EAAE;QACZyE,OAAO,CAACC,IAAI,CACV,0DAA0D,kBACjDrD,IAAI,0BAAgBtB,SAAS,EACvC;QACD;QACA,IAAI,CAACnB,KAAK,CAACU,QAAQ,CAACmB,OAAO,CAACkE,mBAAmB,CAACC,6CAAoC,EAAE;UACpFC,MAAM,EAAE;YACN9E,SAAS,EAATA,SAAS;YACTsB,IAAI,EAAJA;UACF;QACF,CAAC,CAAC;QAEF,OAAOf,SAAS;MAClB;;MAEA;MACA,IAAMuC,WAAW,GAAG,IAAI,CAACiC,cAAc,CAAC;QACtC9E,OAAO,EAAPA,OAAO;QACPyC,gBAAgB,EAAE,CAAAzC,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEyC,gBAAgB,KAAIA,gBAAgB;QAC/DE,oBAAoB,EAApBA,oBAAoB;QACpBC,eAAe,EAAfA;MACF,CAAC,CAAC;;MAEF;MACA,IAAMmC,iBAAyC,GAAG;QAChD1D,IAAI,EAAJA,IAAI;QACJ2D,UAAU,EAAE,IAAI;QAChBnC,WAAW,EAAXA,WAAW;QACXkF,MAAM,EAANA,MAAM;QACNhE,SAAS,EAAE;UACTkB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;QACnC,CAAC;QACD4C,QAAQ,EAAEhI,OAAO,CAACiI,cAAc,EAAE;QAClCC,SAAS,EAAE,IAAI,CAACC,eAAe,EAAE;QACjCC,8BAA8B,EAAE,IAAI,CAACC,iCAAiC,CAAC;UACrEtI,SAAS,EAATA;QACF,CAAC;MACH,CAAC;MAED,IAAI1B,OAAO,aAAPA,OAAO,oCAAPA,OAAO,CAAEsI,QAAQ,8CAAjB,kBAAmBgB,OAAO,EAAE;QAAA;QAC9B;QACA5C,iBAAiB,CAAChB,SAAS,CAACuE,eAAe,GAAGjK,OAAO,aAAPA,OAAO,6CAAPA,OAAO,CAAEsI,QAAQ,uDAAjB,mBAAmBgB,OAAO;MAC1E;MAEA,OAAO5C,iBAAiB;IAC1B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,kDAQG;MAAA;MAAA,IAPD1D,IAAI,SAAJA,IAAI;QACJhD,OAAO,SAAPA,OAAO;QACP0J,MAAM,SAANA,MAAM;MAMN,IAAI,CAAC5I,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,+FAA+F,kBACtFgC,IAAI,EACd;MACD,IAAOqB,aAAa,GAAuDrE,OAAO,CAA3EqE,aAAa;QAAEE,eAAe,GAAsCvE,OAAO,CAA5DuE,eAAe;QAAED,oBAAoB,GAAgBtE,OAAO,CAA3CsE,oBAAoB;QAAElE,UAAU,GAAIJ,OAAO,CAArBI,UAAU;;MAEvE;MACA,IAAMoE,WAAW,GAAG,IAAI,CAACiC,cAAc,CAAC;QACtCpC,aAAa,EAAbA,aAAa;QACbjE,UAAU,EAAVA,UAAU;QACVmE,eAAe,EAAfA,eAAe;QACfD,oBAAoB,EAApBA;MACF,CAAC,CAAC;;MAEF;MACA,IAAMoC,iBAAyC,GAAG;QAChD1D,IAAI,EAAJA,IAAI;QACJ0G,MAAM,EAANA,MAAM;QACN/C,UAAU,EAAE,IAAI;QAChBnC,WAAW,EAAXA,WAAW;QACXkB,SAAS,EAAE;UACTkB,eAAe,EAAEC,MAAM,CAACC,QAAQ,CAACC;QACnC,CAAC;QACD8C,SAAS,EAAE,IAAI,CAACC,eAAe;MACjC,CAAC;MAED,IAAI9J,OAAO,aAAPA,OAAO,qCAAPA,OAAO,CAAEsI,QAAQ,+CAAjB,mBAAmBgB,OAAO,EAAE;QAAA;QAC9B;QACA5C,iBAAiB,CAAChB,SAAS,CAACuE,eAAe,GAAGjK,OAAO,aAAPA,OAAO,6CAAPA,OAAO,CAAEsI,QAAQ,uDAAjB,mBAAmBgB,OAAO;MAC1E;MAEA,OAAO5C,iBAAiB;IAC1B;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EARE;IAAA;IAAA,OASA,mCAQG;MAAA,IAPD1D,IAAI,SAAJA,IAAI;QACJmD,OAAO,SAAPA,OAAO;QACPnG,OAAO,SAAPA,OAAO;MAMP,IAAO0B,SAAS,GAA6B1B,OAAO,CAA7C0B,SAAS;QAAE2C,aAAa,GAAcrE,OAAO,CAAlCqE,aAAa;QAAEiE,QAAQ,GAAItI,OAAO,CAAnBsI,QAAQ;MACzC,IAAI5B,iBAAyC;;MAE7C;MACA,IAAMgD,MAA+B,GAAG,EAAE;MAE1C,IAAIpB,QAAQ,EAAE;QACZ,IAAI,CAACxH,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,6GAA6G,kBACpGgC,IAAI,uBACA,IAAAkH,kCAA2B,EAAC5B,QAAQ,CAAC,EACnD;QAED,IAAM6B,cAAc,GAAG,IAAI,CAACC,+BAA+B,CAAC9B,QAAQ,CAAC;QACrE,IAAI6B,cAAc,EAAE;UAClBT,MAAM,CAACW,IAAI,CAACF,cAAc,CAAC;QAC7B;QACA,IAAI,CAACrJ,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,+DAA+D,4BAC5C,wBAAemJ,cAAc,CAAC,EAClD;MACH;;MAEA;MACA,IAAIzI,SAAS,EAAE;QACbgF,iBAAiB,GAAG,IAAI,CAAC4D,gCAAgC,CAAC;UAACtH,IAAI,EAAJA,IAAI;UAAEhD,OAAO,EAAPA,OAAO;UAAE0J,MAAM,EAANA;QAAM,CAAC,CAAC;MACpF,CAAC,MAAM,IAAIrF,aAAa,EAAE;QACxB;QACAqC,iBAAiB,GAAG,IAAI,CAAC6D,iCAAiC,CAAC;UAACvH,IAAI,EAAJA,IAAI;UAAEhD,OAAO,EAAPA,OAAO;UAAE0J,MAAM,EAANA;QAAM,CAAC,CAAC;MACrF,CAAC,MAAM;QACL,MAAM,IAAIvF,KAAK,CAAC,iBAAiB,CAAC;MACpC;;MAEA;MACAuC,iBAAiB,GAAG,qBAAMA,iBAAiB,EAAEP,OAAO,CAAC;;MAErD;MACA,IAAM9F,eAAe,GAAG,IAAI,CAACkH,sBAAsB,CAACb,iBAAiB,EAAE1G,OAAO,CAAC;MAE/E,OAAOK,eAAe;IACxB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EAPE;IAAA;IAAA,OAQA,kCAQG;MAAA,IAPD2C,IAAI,SAAJA,IAAI;QACJmD,OAAO,SAAPA,OAAO;QACPnG,OAAO,SAAPA,OAAO;MAMP,IAAI,CAACc,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,0EAA0E,kBACjEgC,IAAI,sBACD,wBAAemD,OAAO,CAAC,sBACvB,wBAAenG,OAAO,CAAC,EACpC;MACD,IAAMK,eAAe,GAAG,IAAI,CAACmK,kBAAkB,CAAC;QAACxH,IAAI,EAAJA,IAAI;QAAEmD,OAAO,EAAPA,OAAO;QAAEnG,OAAO,EAAPA;MAAO,CAAC,CAAC;MAEzE,IAAIA,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEI,UAAU,EAAE;QACvB,OAAO,IAAI,CAACqK,+BAA+B,CAACpK,eAAe,EAAEL,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEI,UAAU,CAAC;MACnF;MAEA,IAAI,CAACoH,SAAS,CAAC;QAAC/G,IAAI,EAAE,IAAI;QAAEP,KAAK,EAAEG;MAAe,CAAC,CAAC;MAEpD,OAAO,IAAI,CAACoH,uBAAuB,CAACpH,eAAe,CAAC;IACtD;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,iCAAwBH,KAAY,EAAgB;MAClD;MACA,IAAMwK,UAAU,GAAG;QACjBlK,YAAY,EAAEN,KAAK;QACnBO,IAAI,EAAE,CAAC,kBAAkB;MAC3B,CAAC;MAED,IAAI,CAACK,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,gFAAgF,wBACjE,wBAAe0J,UAAU,CAAC,EAC1C;MAED,OAAO,IAAI,CAACtJ,2BAA2B,CAACuJ,OAAO,CAACD,UAAU,CAAC;IAC7D;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA;IA2BA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IARE;MAAA,mHASA;QAAA;QAAA;UAAA;YAAA;cACE1H,IAAI,SAAJA,IAAI,EACJmD,OAAO,SAAPA,OAAO,EACPnG,OAAO,SAAPA,OAAO;cAMP,IAAI,CAACc,MAAM,CAACC,GAAG,CACbC,uCAA8B,EAC9B,6GAA6G,kBACpGgC,IAAI,sBACD,wBAAemD,OAAO,CAAC,sBACvB,wBAAenG,OAAO,CAAC,EACpC;cAEK4K,WAAW,GAAG,IAAI,CAACJ,kBAAkB,CAAC;gBAACxH,IAAI,EAAJA,IAAI;gBAAEmD,OAAO,EAAPA,OAAO;gBAAEnG,OAAO,EAAPA;cAAO,CAAC,CAAC,EAErE;cACA;cACMK,eAAe,GAAG,IAAAC,kDAA2B,EAAC,IAAI,CAACC,KAAK,EAAE;gBAC9DC,YAAY,EAAEoK,WAAW;gBACzBnK,IAAI,EAAE,CAAC,kBAAkB;cAC3B,CAAC,CAAC;cAEIkK,OAAO,GAAG;gBACdE,MAAM,EAAE,MAAM;gBACdC,OAAO,EAAE,SAAS;gBAClBC,QAAQ,EAAE,eAAe;gBACzBrC,IAAI,EAAE;kBACJtG,OAAO,EAAE,CAAC/B,eAAe;gBAC3B,CAAC;gBACD2K,OAAO,EAAE,CAAC,CAAC;gBACX;gBACAC,qBAAqB,EAAE,IAAI,CAAC1K,KAAK,CAACU,QAAQ,CAACmB,OAAO,CAACD,MAAM,CAAC8I;cAC5D,CAAC;cAED,IAAIjL,OAAO,CAACI,UAAU,EAAE;gBACtBuK,OAAO,CAACK,OAAO,GAAG;kBAChBE,aAAa,EAAE,KAAK;kBACpB,mBAAmB,EAAElL,OAAO,CAACI;gBAC/B,CAAC;gBACDuK,OAAO,CAACI,QAAQ,GAAG,wBAAwB;cAC7C;;cAEA;cAAA,iCACO,IAAI,CAACxK,KAAK,CAAC4K,mBAAmB,CAACR,OAAO,CAAC;YAAA;YAAA;cAAA;UAAA;QAAA;MAAA,CAC/C;MAAA;QAAA;MAAA;MAAA;IAAA;IAED;AACF;AACA;AACA;AACA;EAJE;IAAA;IAAA,OAKA,gCAA8BhD,gBAAwB,EAAW;MAC/D,IAAMD,eAAe,GAAGoB,sDAA6C,CAACnB,gBAAgB,CAAC;MACvF,IAAMyD,kBAAkB,GAAGrD,2CAAkC,CAACL,eAAe,CAAC;MAE9E,OAAO,CAAA0D,kBAAkB,aAAlBA,kBAAkB,uBAAlBA,kBAAkB,CAAElD,QAAQ,MAAK,UAAU;IACpD;EAAC;EAAA;AAAA,EArwBgDmD,+BAAoB;AAAA"}
@@ -28,7 +28,8 @@ var ClientMetricsBatcher = _batcher.default.extend({
28
28
  resource: 'clientmetrics',
29
29
  body: {
30
30
  metrics: payload
31
- }
31
+ },
32
+ waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout
32
33
  });
33
34
  }
34
35
  });
@@ -1 +1 @@
1
- {"version":3,"names":["ClientMetricsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareRequest","queue","submitHttpRequest","payload","webex","request","method","service","resource","body","metrics"],"sources":["client-metrics-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport Batcher from './batcher';\n\nconst ClientMetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Add more defaults to payload when the clientmetrics endpoint evolves to support richer payloads\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(queue);\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n });\n },\n});\n\nexport default ClientMetricsBatcher;\n"],"mappings":";;;;;;;;;AAIA;AAJA;AACA;AACA;;AAIA,IAAMA,oBAAoB,GAAGC,gBAAO,CAACC,MAAM,CAAC;EAC1CC,SAAS,EAAE,SAAS;EAEpBC,WAAW,uBAACC,IAAI,EAAE;IAChB;IACA,OAAO,iBAAQC,OAAO,CAACD,IAAI,CAAC;EAC9B,CAAC;EAEDE,cAAc,0BAACC,KAAK,EAAE;IACpB,OAAO,iBAAQF,OAAO,CAACE,KAAK,CAAC;EAC/B,CAAC;EAEDC,iBAAiB,6BAACC,OAAO,EAAE;IACzB,OAAO,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;MACxBC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEP;MACX;IACF,CAAC,CAAC;EACJ;AACF,CAAC,CAAC;AAAC,eAEYV,oBAAoB;AAAA"}
1
+ {"version":3,"names":["ClientMetricsBatcher","Batcher","extend","namespace","prepareItem","item","resolve","prepareRequest","queue","submitHttpRequest","payload","webex","request","method","service","resource","body","metrics","waitForServiceTimeout","config"],"sources":["client-metrics-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport Batcher from './batcher';\n\nconst ClientMetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n prepareItem(item) {\n // Add more defaults to payload when the clientmetrics endpoint evolves to support richer payloads\n return Promise.resolve(item);\n },\n\n prepareRequest(queue) {\n return Promise.resolve(queue);\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n });\n },\n});\n\nexport default ClientMetricsBatcher;\n"],"mappings":";;;;;;;;;AAIA;AAJA;AACA;AACA;;AAIA,IAAMA,oBAAoB,GAAGC,gBAAO,CAACC,MAAM,CAAC;EAC1CC,SAAS,EAAE,SAAS;EAEpBC,WAAW,uBAACC,IAAI,EAAE;IAChB;IACA,OAAO,iBAAQC,OAAO,CAACD,IAAI,CAAC;EAC9B,CAAC;EAEDE,cAAc,0BAACC,KAAK,EAAE;IACpB,OAAO,iBAAQF,OAAO,CAACE,KAAK,CAAC;EAC/B,CAAC;EAEDC,iBAAiB,6BAACC,OAAO,EAAE;IACzB,OAAO,IAAI,CAACC,KAAK,CAACC,OAAO,CAAC;MACxBC,MAAM,EAAE,MAAM;MACdC,OAAO,EAAE,SAAS;MAClBC,QAAQ,EAAE,eAAe;MACzBC,IAAI,EAAE;QACJC,OAAO,EAAEP;MACX,CAAC;MACDQ,qBAAqB,EAAE,IAAI,CAACP,KAAK,CAACQ,MAAM,CAACF,OAAO,CAACC;IACnD,CAAC,CAAC;EACJ;AACF,CAAC,CAAC;AAAC,eAEYlB,oBAAoB;AAAA"}
package/dist/config.js CHANGED
@@ -24,7 +24,8 @@ var _default = {
24
24
  batcherWait: 500,
25
25
  batcherMaxCalls: 50,
26
26
  batcherMaxWait: 1500,
27
- batcherRetryPlateau: 32000
27
+ batcherRetryPlateau: 32000,
28
+ waitForServiceTimeout: 15
28
29
  }
29
30
  };
30
31
  exports.default = _default;
@@ -1 +1 @@
1
- {"version":3,"names":["CLIENT_NAME","device","preDiscoveryServices","metricsServiceUrl","process","env","METRICS_SERVICE_URL","metrics","appType","inBrowser","batcherWait","batcherMaxCalls","batcherMaxWait","batcherRetryPlateau","OS_NAME","WINDOWS","MAC","IOS","ANDROID","CHROME","LINUX","OTHERS","OSMap","macOS","Windows","iOS","Android","Linux"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {inBrowser} from '@webex/common';\n\nexport const CLIENT_NAME = 'webex-js-sdk';\nexport default {\n device: {\n preDiscoveryServices: {\n metricsServiceUrl:\n process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n },\n },\n metrics: {\n appType: inBrowser ? 'browser' : 'nodejs',\n batcherWait: 500,\n batcherMaxCalls: 50,\n batcherMaxWait: 1500,\n batcherRetryPlateau: 32000,\n },\n};\n\nexport const OS_NAME = {\n WINDOWS: 'windows',\n MAC: 'mac',\n IOS: 'ios',\n ANDROID: 'android',\n CHROME: 'chrome',\n LINUX: 'linux',\n OTHERS: 'other',\n};\n\nexport const OSMap = {\n 'Chrome OS': OS_NAME.CHROME,\n macOS: OS_NAME.MAC,\n Windows: OS_NAME.WINDOWS,\n iOS: OS_NAME.IOS,\n Android: OS_NAME.ANDROID,\n Linux: OS_NAME.LINUX,\n};\n"],"mappings":";;;;;;;AAIA;AAJA;AACA;AACA;;AAIO,IAAMA,WAAW,GAAG,cAAc;AAAC;AAAA,eAC3B;EACbC,MAAM,EAAE;IACNC,oBAAoB,EAAE;MACpBC,iBAAiB,EACfC,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI,2CAA2C;MAChFC,OAAO,EAAEH,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI;IAC9C;EACF,CAAC;EACDC,OAAO,EAAE;IACPC,OAAO,EAAEC,iBAAS,GAAG,SAAS,GAAG,QAAQ;IACzCC,WAAW,EAAE,GAAG;IAChBC,eAAe,EAAE,EAAE;IACnBC,cAAc,EAAE,IAAI;IACpBC,mBAAmB,EAAE;EACvB;AACF,CAAC;AAAA;AAEM,IAAMC,OAAO,GAAG;EACrBC,OAAO,EAAE,SAAS;EAClBC,GAAG,EAAE,KAAK;EACVC,GAAG,EAAE,KAAK;EACVC,OAAO,EAAE,SAAS;EAClBC,MAAM,EAAE,QAAQ;EAChBC,KAAK,EAAE,OAAO;EACdC,MAAM,EAAE;AACV,CAAC;AAAC;AAEK,IAAMC,KAAK,GAAG;EACnB,WAAW,EAAER,OAAO,CAACK,MAAM;EAC3BI,KAAK,EAAET,OAAO,CAACE,GAAG;EAClBQ,OAAO,EAAEV,OAAO,CAACC,OAAO;EACxBU,GAAG,EAAEX,OAAO,CAACG,GAAG;EAChBS,OAAO,EAAEZ,OAAO,CAACI,OAAO;EACxBS,KAAK,EAAEb,OAAO,CAACM;AACjB,CAAC;AAAC"}
1
+ {"version":3,"names":["CLIENT_NAME","device","preDiscoveryServices","metricsServiceUrl","process","env","METRICS_SERVICE_URL","metrics","appType","inBrowser","batcherWait","batcherMaxCalls","batcherMaxWait","batcherRetryPlateau","waitForServiceTimeout","OS_NAME","WINDOWS","MAC","IOS","ANDROID","CHROME","LINUX","OTHERS","OSMap","macOS","Windows","iOS","Android","Linux"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {inBrowser} from '@webex/common';\n\nexport const CLIENT_NAME = 'webex-js-sdk';\nexport default {\n device: {\n preDiscoveryServices: {\n metricsServiceUrl:\n process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',\n },\n },\n metrics: {\n appType: inBrowser ? 'browser' : 'nodejs',\n batcherWait: 500,\n batcherMaxCalls: 50,\n batcherMaxWait: 1500,\n batcherRetryPlateau: 32000,\n waitForServiceTimeout: 15,\n },\n};\n\nexport const OS_NAME = {\n WINDOWS: 'windows',\n MAC: 'mac',\n IOS: 'ios',\n ANDROID: 'android',\n CHROME: 'chrome',\n LINUX: 'linux',\n OTHERS: 'other',\n};\n\nexport const OSMap = {\n 'Chrome OS': OS_NAME.CHROME,\n macOS: OS_NAME.MAC,\n Windows: OS_NAME.WINDOWS,\n iOS: OS_NAME.IOS,\n Android: OS_NAME.ANDROID,\n Linux: OS_NAME.LINUX,\n};\n"],"mappings":";;;;;;;AAIA;AAJA;AACA;AACA;;AAIO,IAAMA,WAAW,GAAG,cAAc;AAAC;AAAA,eAC3B;EACbC,MAAM,EAAE;IACNC,oBAAoB,EAAE;MACpBC,iBAAiB,EACfC,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI,2CAA2C;MAChFC,OAAO,EAAEH,OAAO,CAACC,GAAG,CAACC,mBAAmB,IAAI;IAC9C;EACF,CAAC;EACDC,OAAO,EAAE;IACPC,OAAO,EAAEC,iBAAS,GAAG,SAAS,GAAG,QAAQ;IACzCC,WAAW,EAAE,GAAG;IAChBC,eAAe,EAAE,EAAE;IACnBC,cAAc,EAAE,IAAI;IACpBC,mBAAmB,EAAE,KAAK;IAC1BC,qBAAqB,EAAE;EACzB;AACF,CAAC;AAAA;AAEM,IAAMC,OAAO,GAAG;EACrBC,OAAO,EAAE,SAAS;EAClBC,GAAG,EAAE,KAAK;EACVC,GAAG,EAAE,KAAK;EACVC,OAAO,EAAE,SAAS;EAClBC,MAAM,EAAE,QAAQ;EAChBC,KAAK,EAAE,OAAO;EACdC,MAAM,EAAE;AACV,CAAC;AAAC;AAEK,IAAMC,KAAK,GAAG;EACnB,WAAW,EAAER,OAAO,CAACK,MAAM;EAC3BI,KAAK,EAAET,OAAO,CAACE,GAAG;EAClBQ,OAAO,EAAEV,OAAO,CAACC,OAAO;EACxBU,GAAG,EAAEX,OAAO,CAACG,GAAG;EAChBS,OAAO,EAAEZ,OAAO,CAACI,OAAO;EACxBS,KAAK,EAAEb,OAAO,CAACM;AACjB,CAAC;AAAC"}
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.282"
164
+ version: "3.0.0-beta.284"
165
165
  });
166
166
  var _default = Metrics;
167
167
  exports.default = _default;
@@ -24,6 +24,13 @@ type GetIdentifiersOptions = {
24
24
  export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
25
25
  private callDiagnosticEventsBatcher;
26
26
  private logger;
27
+ validator: (options: {
28
+ type: 'mqe' | 'ce';
29
+ event: Event;
30
+ }) => Promise<{
31
+ event: Event;
32
+ valid: boolean;
33
+ }>;
27
34
  /**
28
35
  * Constructor
29
36
  * @param args
@@ -67,13 +74,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
67
74
  macAddress?: string;
68
75
  localNetworkPrefix?: string;
69
76
  publicNetworkPrefix?: string;
70
- browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient";
77
+ browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient" | "switch-to-web" | "switch-to-native";
71
78
  clientLaunchMethod?: "url-handler" | "universal-link" | "voice-command" | "notification" | "manual" | "teams-cross-launch" | "mc-cross-launch";
72
79
  browser?: string;
73
80
  browserVersion?: string;
74
81
  clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC";
75
82
  subClientType?: "TEAMS_DEVICE" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MOBILE_APP" | "MOBILE_NETWORK" | "VDI_APP" | "WEB_APP";
76
83
  clientVersion?: string;
84
+ clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
77
85
  localClientVersion?: string;
78
86
  modelNumber?: string;
79
87
  joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
@@ -12,6 +12,7 @@ declare namespace _default {
12
12
  const batcherMaxCalls: number;
13
13
  const batcherMaxWait: number;
14
14
  const batcherRetryPlateau: number;
15
+ const waitForServiceTimeout: number;
15
16
  }
16
17
  export { metrics_1 as metrics };
17
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-metrics",
3
- "version": "3.0.0-beta.282",
3
+ "version": "3.0.0-beta.284",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -28,13 +28,13 @@
28
28
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
29
29
  },
30
30
  "dependencies": {
31
- "@webex/common": "3.0.0-beta.282",
32
- "@webex/common-timers": "3.0.0-beta.282",
33
- "@webex/event-dictionary-ts": "^1.0.1290",
34
- "@webex/internal-plugin-device": "3.0.0-beta.282",
35
- "@webex/internal-plugin-metrics": "3.0.0-beta.282",
36
- "@webex/test-helper-chai": "3.0.0-beta.282",
37
- "@webex/test-helper-mock-webex": "3.0.0-beta.282",
38
- "@webex/webex-core": "3.0.0-beta.282"
31
+ "@webex/common": "3.0.0-beta.284",
32
+ "@webex/common-timers": "3.0.0-beta.284",
33
+ "@webex/event-dictionary-ts": "^1.0.1313",
34
+ "@webex/internal-plugin-device": "3.0.0-beta.284",
35
+ "@webex/internal-plugin-metrics": "3.0.0-beta.284",
36
+ "@webex/test-helper-chai": "3.0.0-beta.284",
37
+ "@webex/test-helper-mock-webex": "3.0.0-beta.284",
38
+ "@webex/webex-core": "3.0.0-beta.284"
39
39
  }
40
40
  }
package/src/batcher.js CHANGED
@@ -40,6 +40,7 @@ const MetricsBatcher = Batcher.extend({
40
40
  body: {
41
41
  metrics: payload,
42
42
  },
43
+ waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,
43
44
  });
44
45
  },
45
46
 
@@ -56,6 +56,7 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
56
56
  body: {
57
57
  metrics: payload,
58
58
  },
59
+ waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,
59
60
  })
60
61
  .then((res) => {
61
62
  this.webex.logger.log(
@@ -82,6 +82,13 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
82
82
  // @ts-ignore
83
83
  private callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher;
84
84
  private logger: any; // to avoid adding @ts-ignore everywhere
85
+ // the default validator before piping an event to the batcher
86
+ // this function can be overridden by the user
87
+ public validator: (options: {
88
+ type: 'mqe' | 'ce';
89
+ event: Event;
90
+ }) => Promise<{event: Event; valid: boolean}> = (options: {type: 'mqe' | 'ce'; event: Event}) =>
91
+ Promise.resolve({event: options?.event, valid: true});
85
92
 
86
93
  /**
87
94
  * Constructor
@@ -247,7 +254,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
247
254
  }
248
255
 
249
256
  if (meeting?.meetingInfo?.confID) {
250
- identifiers.webexConferenceIdStr = meeting.meetingInfo?.confID;
257
+ identifiers.webexConferenceIdStr = `${meeting.meetingInfo?.confID}`;
251
258
  }
252
259
 
253
260
  if (meeting?.meetingInfo?.meetingId) {
@@ -260,7 +267,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
260
267
  }
261
268
 
262
269
  if (!identifiers?.webexConferenceIdStr && webexConferenceIdStr) {
263
- identifiers.webexConferenceIdStr = webexConferenceIdStr;
270
+ identifiers.webexConferenceIdStr = `${webexConferenceIdStr}`;
264
271
  }
265
272
 
266
273
  if (!identifiers?.globalMeetingId && globalMeetingId) {
@@ -389,6 +396,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
389
396
 
390
397
  // append media quality event data to the call diagnostic event
391
398
  const diagnosticEvent = this.prepareDiagnosticEvent(clientEventObject, options);
399
+ this.validator({type: 'mqe', event: diagnosticEvent});
392
400
  this.submitToCallDiagnostics(diagnosticEvent);
393
401
  } else {
394
402
  throw new Error(
@@ -721,6 +729,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
721
729
  return this.submitToCallDiagnosticsPreLogin(diagnosticEvent, options?.preLoginId);
722
730
  }
723
731
 
732
+ this.validator({type: 'ce', event: diagnosticEvent});
733
+
724
734
  return this.submitToCallDiagnostics(diagnosticEvent);
725
735
  }
726
736
 
@@ -815,6 +825,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
815
825
  metrics: [diagnosticEvent],
816
826
  },
817
827
  headers: {},
828
+ // @ts-ignore
829
+ waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout,
818
830
  };
819
831
 
820
832
  if (options.preLoginId) {
@@ -24,6 +24,7 @@ const ClientMetricsBatcher = Batcher.extend({
24
24
  body: {
25
25
  metrics: payload,
26
26
  },
27
+ waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,
27
28
  });
28
29
  },
29
30
  });
package/src/config.js CHANGED
@@ -19,6 +19,7 @@ export default {
19
19
  batcherMaxCalls: 50,
20
20
  batcherMaxWait: 1500,
21
21
  batcherRetryPlateau: 32000,
22
+ waitForServiceTimeout: 15,
22
23
  },
23
24
  };
24
25
 
@@ -37,6 +37,7 @@ describe('plugin-metrics', () => {
37
37
  return Promise.resolve({
38
38
  statusCode: 204,
39
39
  body: undefined,
40
+ waitForServiceTimeout: 15,
40
41
  options,
41
42
  });
42
43
  };
@@ -97,6 +98,7 @@ describe('plugin-metrics', () => {
97
98
  return Promise.resolve({
98
99
  statusCode: 204,
99
100
  body: undefined,
101
+ waitForServiceTimeout: 15,
100
102
  options,
101
103
  });
102
104
  });
@@ -9,7 +9,7 @@ import MockWebex from '@webex/test-helper-mock-webex';
9
9
  import sinon from 'sinon';
10
10
  import FakeTimers from '@sinonjs/fake-timers';
11
11
  import {NewMetrics} from '@webex/internal-plugin-metrics';
12
- import { uniqueId } from 'lodash';
12
+ import {uniqueId} from 'lodash';
13
13
 
14
14
  const flushPromises = () => new Promise(setImmediate);
15
15
 
@@ -24,14 +24,12 @@ function promiseTick(count) {
24
24
  return promise;
25
25
  }
26
26
 
27
-
28
27
  describe('plugin-metrics', () => {
29
28
  describe('CallDiagnosticEventsBatcher', () => {
30
29
  let webex;
31
30
  let clock;
32
31
  let now;
33
32
 
34
-
35
33
  beforeEach(() => {
36
34
  now = new Date();
37
35
  clock = FakeTimers.install({now});
@@ -39,14 +37,15 @@ describe('plugin-metrics', () => {
39
37
  //@ts-ignore
40
38
  webex = new MockWebex({
41
39
  children: {
42
- newMetrics: NewMetrics
43
- }
40
+ newMetrics: NewMetrics,
41
+ },
44
42
  });
45
43
 
46
- webex.request = (options) => Promise.resolve({body: {items: []}, options});
44
+ webex.request = (options) =>
45
+ Promise.resolve({body: {items: []}, waitForServiceTimeout: 15, options});
47
46
  sinon.spy(webex, 'request');
48
47
 
49
- webex.emit("ready");
48
+ webex.emit('ready');
50
49
 
51
50
  webex.config.metrics = config.metrics;
52
51
  });
@@ -70,7 +69,10 @@ describe('plugin-metrics', () => {
70
69
 
71
70
  //@ts-ignore
72
71
  assert.calledOnce(webex.request);
73
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
72
+ assert.lengthOf(
73
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
74
+ 0
75
+ );
74
76
  });
75
77
 
76
78
  it('doesnt include any joinTimes for other events', async () => {
@@ -88,12 +90,19 @@ describe('plugin-metrics', () => {
88
90
  assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
89
91
  name: 'client.alert.displayed',
90
92
  });
91
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
93
+ assert.lengthOf(
94
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
95
+ 0
96
+ );
92
97
  });
93
98
 
94
99
  it('appends the correct join times to the request for client.interstitial-window.launched', async () => {
95
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
96
- webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon.stub().returns(10);
100
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
101
+ .stub()
102
+ .returns(10);
103
+ webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
104
+ .stub()
105
+ .returns(10);
97
106
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
98
107
  //@ts-ignore
99
108
  {event: {name: 'client.interstitial-window.launched'}}
@@ -112,11 +121,16 @@ describe('plugin-metrics', () => {
112
121
  meetingInfoReqResp: 10,
113
122
  },
114
123
  });
115
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
124
+ assert.lengthOf(
125
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
126
+ 0
127
+ );
116
128
  });
117
129
 
118
130
  it('appends the correct join times to the request for client.call.initiated', async () => {
119
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
131
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
132
+ .stub()
133
+ .returns(10);
120
134
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
121
135
  //@ts-ignore
122
136
  {event: {name: 'client.call.initiated'}}
@@ -134,16 +148,27 @@ describe('plugin-metrics', () => {
134
148
  showInterstitialTime: 10,
135
149
  },
136
150
  });
137
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
151
+ assert.lengthOf(
152
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
153
+ 0
154
+ );
138
155
  });
139
156
 
140
157
  it('appends the correct join times to the request for client.locus.join.response', async () => {
141
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
142
- webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon.stub().returns(20);
158
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
159
+ .stub()
160
+ .returns(10);
161
+ webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon
162
+ .stub()
163
+ .returns(20);
143
164
  webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);
144
165
  webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);
145
- webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon.stub().returns(10);
146
- webex.internal.newMetrics.callDiagnosticLatencies.getCallInitJoinReq = sinon.stub().returns(10);
166
+ webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
167
+ .stub()
168
+ .returns(10);
169
+ webex.internal.newMetrics.callDiagnosticLatencies.getCallInitJoinReq = sinon
170
+ .stub()
171
+ .returns(10);
147
172
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
148
173
  //@ts-ignore
149
174
  {event: {name: 'client.locus.join.response'}}
@@ -169,11 +194,16 @@ describe('plugin-metrics', () => {
169
194
  clientJmt: 5,
170
195
  },
171
196
  });
172
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
197
+ assert.lengthOf(
198
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
199
+ 0
200
+ );
173
201
  });
174
202
 
175
203
  it('appends the correct join times to the request for client.ice.end', async () => {
176
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
204
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
205
+ .stub()
206
+ .returns(10);
177
207
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
178
208
  //@ts-ignore
179
209
  {event: {name: 'client.ice.end'}}
@@ -194,11 +224,16 @@ describe('plugin-metrics', () => {
194
224
  videoICESetupTime: 10,
195
225
  },
196
226
  });
197
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
227
+ assert.lengthOf(
228
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
229
+ 0
230
+ );
198
231
  });
199
232
 
200
233
  it('appends the correct join times to the request for client.media.rx.start', async () => {
201
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
234
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
235
+ .stub()
236
+ .returns(10);
202
237
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
203
238
  //@ts-ignore
204
239
  {event: {name: 'client.media.rx.start'}}
@@ -216,13 +251,22 @@ describe('plugin-metrics', () => {
216
251
  localSDPGenRemoteSDPRecv: 10,
217
252
  },
218
253
  });
219
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
254
+ assert.lengthOf(
255
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
256
+ 0
257
+ );
220
258
  });
221
259
 
222
260
  it('appends the correct join times to the request for client.media-engine.ready', async () => {
223
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
224
- webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon.stub().returns(10);
225
- webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon.stub().returns(10);
261
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
262
+ .stub()
263
+ .returns(10);
264
+ webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon
265
+ .stub()
266
+ .returns(10);
267
+ webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
268
+ .stub()
269
+ .returns(10);
226
270
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
227
271
  //@ts-ignore
228
272
  {event: {name: 'client.media-engine.ready'}}
@@ -243,11 +287,16 @@ describe('plugin-metrics', () => {
243
287
  stayLobbyTime: 10,
244
288
  },
245
289
  });
246
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
290
+ assert.lengthOf(
291
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
292
+ 0
293
+ );
247
294
  });
248
295
 
249
296
  it('appends the correct audio and video setup delays to the request for client.mediaquality.event', async () => {
250
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
297
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
298
+ .stub()
299
+ .returns(10);
251
300
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
252
301
  //@ts-ignore
253
302
  {event: {name: 'client.mediaquality.event'}}
@@ -268,9 +317,12 @@ describe('plugin-metrics', () => {
268
317
  videoSetupDelay: {
269
318
  joinRespRxStart: 10,
270
319
  joinRespTxStart: 10,
271
- }
320
+ },
272
321
  });
273
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
322
+ assert.lengthOf(
323
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
324
+ 0
325
+ );
274
326
  });
275
327
 
276
328
  it('doesnt include audioSetup and videoSetup delays for other events', async () => {
@@ -285,10 +337,19 @@ describe('plugin-metrics', () => {
285
337
 
286
338
  //@ts-ignore
287
339
  assert.calledOnce(webex.request);
288
- assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.audioSetupDelay, undefined);
289
- assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.videoSetupDelay, undefined);
290
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
291
- })
340
+ assert.deepEqual(
341
+ webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.audioSetupDelay,
342
+ undefined
343
+ );
344
+ assert.deepEqual(
345
+ webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event.videoSetupDelay,
346
+ undefined
347
+ );
348
+ assert.lengthOf(
349
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
350
+ 0
351
+ );
352
+ });
292
353
  });
293
354
 
294
355
  describe('when the request fails', () => {
@@ -329,7 +390,10 @@ describe('plugin-metrics', () => {
329
390
  // This is horrific, but stubbing lodash is proving difficult
330
391
  const expectedBatchId = parseInt(uniqueId()) - 1;
331
392
 
332
- assert.deepEqual(JSON.stringify(loggerLogCalls[1].args), `["call-diagnostic-events -> ","CallDiagnosticEventsBatcher: @submitHttpRequest#call-diagnostic-metrics-batch-${expectedBatchId}. Sending the request:","payload:",[{"eventPayload":{"event":"my.event","origin":{"buildType":"test","networkType":"unknown"}},"type":["diagnostic-event"]}]]`);
393
+ assert.deepEqual(
394
+ JSON.stringify(loggerLogCalls[1].args),
395
+ `["call-diagnostic-events -> ","CallDiagnosticEventsBatcher: @submitHttpRequest#call-diagnostic-metrics-batch-${expectedBatchId}. Sending the request:","payload:",[{"eventPayload":{"event":"my.event","origin":{"buildType":"test","networkType":"unknown"}},"type":["diagnostic-event"]}]]`
396
+ );
333
397
 
334
398
  // check that promise was rejected with the original error of the webex.request
335
399
  assert.deepEqual(err, error);
@@ -340,7 +404,10 @@ describe('plugin-metrics', () => {
340
404
  `CallDiagnosticEventsBatcher: @submitHttpRequest#call-diagnostic-metrics-batch-${expectedBatchId}. Request failed:`,
341
405
  `error: formattedError`
342
406
  );
343
- assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
407
+ assert.lengthOf(
408
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue,
409
+ 0
410
+ );
344
411
  });
345
412
  });
346
413
  });
@@ -349,10 +416,16 @@ describe('plugin-metrics', () => {
349
416
  it('calls prepareDiagnosticMetricItem correctly', async () => {
350
417
  // avoid setting .sent timestamp
351
418
  webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.prepareRequest =
352
- (q) => Promise.resolve(q);
419
+ (q) => Promise.resolve(q);
353
420
 
354
- const prepareItemSpy = sinon.spy(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher, 'prepareItem');
355
- const prepareDiagnosticMetricItemSpy = sinon.spy(CallDiagnosticUtils, 'prepareDiagnosticMetricItem');
421
+ const prepareItemSpy = sinon.spy(
422
+ webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher,
423
+ 'prepareItem'
424
+ );
425
+ const prepareDiagnosticMetricItemSpy = sinon.spy(
426
+ CallDiagnosticUtils,
427
+ 'prepareDiagnosticMetricItem'
428
+ );
356
429
 
357
430
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics({
358
431
  event: 'my.event',
@@ -374,8 +447,7 @@ describe('plugin-metrics', () => {
374
447
 
375
448
  assert.deepEqual(calls.args[0].type, ['diagnostic-event']);
376
449
 
377
-
378
- const prepareDiagnosticMetricItemCalls = prepareDiagnosticMetricItemSpy.getCalls()
450
+ const prepareDiagnosticMetricItemCalls = prepareDiagnosticMetricItemSpy.getCalls();
379
451
 
380
452
  // second argument (item) also gets assigned a delay property but the key is a Symbol and haven't been able to test that..
381
453
  assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[0], webex);
@@ -387,8 +459,7 @@ describe('plugin-metrics', () => {
387
459
  },
388
460
  });
389
461
  assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].type, ['diagnostic-event']);
390
-
391
- })
392
- })
462
+ });
463
+ });
393
464
  });
394
465
  });
@@ -9,6 +9,7 @@ import {BrowserDetection} from '@webex/common';
9
9
  import {getOSNameInternal} from '@webex/internal-plugin-metrics';
10
10
  import uuid from 'uuid';
11
11
  import {omit} from 'lodash';
12
+ import CONFIG from '../../../../src/config';
12
13
 
13
14
  //@ts-ignore
14
15
  global.window = {location: {hostname: 'whatever'}};
@@ -50,6 +51,7 @@ describe('internal-plugin-metrics', () => {
50
51
  },
51
52
  metrics: {
52
53
  submitClientMetrics: sinon.stub(),
54
+ config: {...CONFIG.metrics}
53
55
  },
54
56
  newMetrics: {
55
57
  postPreLoginMetric: sinon.stub(),
@@ -102,6 +104,12 @@ describe('internal-plugin-metrics', () => {
102
104
  sinon.restore();
103
105
  });
104
106
 
107
+ describe('#validator', () => {
108
+ it('should have a validator function defined', () => {
109
+ assert.isDefined(cd.validator);
110
+ });
111
+ });
112
+
105
113
  describe('#getOrigin', () => {
106
114
  it('should build origin correctly', () => {
107
115
  sinon.stub(Utils, 'anonymizeIPAddress').returns('1.1.1.1');
@@ -408,6 +416,7 @@ describe('internal-plugin-metrics', () => {
408
416
  const generateClientEventErrorPayloadSpy = sinon.spy(cd, 'generateClientEventErrorPayload');
409
417
  const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
410
418
  sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
419
+ const validatorSpy = sinon.spy(cd, 'validator');
411
420
  const options = {
412
421
  meetingId: fakeMeeting.id,
413
422
  mediaConnections: [{mediaAgentAlias: 'alias', mediaAgentGroupId: '1'}],
@@ -483,6 +492,39 @@ describe('internal-plugin-metrics', () => {
483
492
  senderCountryCode: 'UK',
484
493
  version: 1,
485
494
  });
495
+ assert.calledWith(validatorSpy, {type: 'ce', event: {
496
+ event: {
497
+ canProceed: true,
498
+ eventData: {
499
+ webClientDomain: 'whatever',
500
+ },
501
+ identifiers: {
502
+ correlationId: 'correlationId',
503
+ deviceId: 'deviceUrl',
504
+ locusId: 'url',
505
+ locusStartTime: 'lastActive',
506
+ locusUrl: 'locus/url',
507
+ mediaAgentAlias: 'alias',
508
+ mediaAgentGroupId: '1',
509
+ orgId: 'orgId',
510
+ userId: 'userId',
511
+ },
512
+ loginType: 'login-ci',
513
+ name: 'client.alert.displayed',
514
+ userType: 'host',
515
+ isConvergedArchitectureEnabled: undefined,
516
+ },
517
+ eventId: 'my-fake-id',
518
+ origin: {
519
+ origin: 'fake-origin',
520
+ },
521
+ originTime: {
522
+ sent: 'not_defined_yet',
523
+ triggered: now.toISOString(),
524
+ },
525
+ senderCountryCode: 'UK',
526
+ version: 1,
527
+ }})
486
528
 
487
529
  const webexLoggerLogCalls = webex.logger.log.getCalls();
488
530
  assert.deepEqual(webexLoggerLogCalls[0].args, [
@@ -1211,6 +1253,7 @@ describe('internal-plugin-metrics', () => {
1211
1253
  cd,
1212
1254
  'getErrorPayloadForClientErrorCode'
1213
1255
  );
1256
+ const validatorSpy = sinon.spy(cd, 'validator');
1214
1257
  const getIdentifiersSpy = sinon.spy(cd, 'getIdentifiers');
1215
1258
  sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
1216
1259
  const options = {
@@ -1265,6 +1308,38 @@ describe('internal-plugin-metrics', () => {
1265
1308
  options
1266
1309
  );
1267
1310
 
1311
+ assert.calledWith(validatorSpy, {type: 'mqe', event: {
1312
+ eventId: 'my-fake-id',
1313
+ version: 1,
1314
+ origin: {origin: 'fake-origin'},
1315
+ originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
1316
+ senderCountryCode: 'UK',
1317
+ event: {
1318
+ name: 'client.mediaquality.event',
1319
+ canProceed: true,
1320
+ identifiers: {
1321
+ correlationId: 'correlationId',
1322
+ webexConferenceIdStr: 'webexConferenceIdStr1',
1323
+ globalMeetingId: 'globalMeetingId1',
1324
+ userId: 'userId',
1325
+ deviceId: 'deviceUrl',
1326
+ orgId: 'orgId',
1327
+ locusUrl: 'locus/url',
1328
+ locusId: 'url',
1329
+ locusStartTime: 'lastActive',
1330
+ },
1331
+ eventData: {webClientDomain: 'whatever'},
1332
+ intervals: [{}],
1333
+ sourceMetadata: {
1334
+ applicationSoftwareType: 'webex-js-sdk',
1335
+ applicationSoftwareVersion: 'webex-version',
1336
+ mediaEngineSoftwareType: 'browser',
1337
+ mediaEngineSoftwareVersion: getOSVersion(),
1338
+ startTime: now.toISOString(),
1339
+ },
1340
+ },
1341
+ }});
1342
+
1268
1343
  assert.calledWith(submitToCallDiagnosticsSpy, {
1269
1344
  eventId: 'my-fake-id',
1270
1345
  version: 1,
@@ -1690,6 +1765,7 @@ describe('internal-plugin-metrics', () => {
1690
1765
  method: 'POST',
1691
1766
  resource: 'clientmetrics-prelogin',
1692
1767
  service: 'metrics',
1768
+ waitForServiceTimeout: CONFIG.metrics.waitForServiceTimeout,
1693
1769
  headers: {
1694
1770
  authorization: false,
1695
1771
  'x-prelogin-userid': preLoginId,
@@ -1701,7 +1777,8 @@ describe('internal-plugin-metrics', () => {
1701
1777
  method: 'POST',
1702
1778
  resource: 'clientmetrics',
1703
1779
  service: 'metrics',
1704
- headers: {}
1780
+ headers: {},
1781
+ waitForServiceTimeout: CONFIG.metrics.waitForServiceTimeout,
1705
1782
  })
1706
1783
  }
1707
1784
 
@@ -37,6 +37,7 @@ describe('plugin-metrics', () => {
37
37
  return Promise.resolve({
38
38
  statusCode: 204,
39
39
  body: undefined,
40
+ waitForServiceTimeout: 15,
40
41
  options,
41
42
  });
42
43
  };
@@ -97,6 +98,7 @@ describe('plugin-metrics', () => {
97
98
  return Promise.resolve({
98
99
  statusCode: 204,
99
100
  body: undefined,
101
+ waitForServiceTimeout: 15,
100
102
  options,
101
103
  });
102
104
  });
@@ -85,6 +85,7 @@ describe('plugin-metrics', () => {
85
85
  return Promise.resolve({
86
86
  statusCode: 204,
87
87
  body: undefined,
88
+ waitForServiceTimeout: 15,
88
89
  options,
89
90
  });
90
91
  };
@@ -152,7 +152,7 @@ describe('internal-plugin-metrics', () => {
152
152
  resource: 'clientmetrics',
153
153
  headers: { 'x-prelogin-userid': 'my-id' },
154
154
  body: {},
155
- qs: { alias: true }
155
+ qs: { alias: true },
156
156
  });
157
157
  assert.calledWith(
158
158
  webex.logger.log,