@thoughtspot/visual-embed-sdk 1.26.0-token-cache.0 → 1.26.0-token-cache.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/cjs/package.json +2 -2
  2. package/cjs/src/auth.d.ts.map +1 -1
  3. package/cjs/src/auth.js.map +1 -1
  4. package/cjs/src/auth.spec.d.ts.map +1 -1
  5. package/cjs/src/auth.spec.js +1 -1
  6. package/cjs/src/auth.spec.js.map +1 -1
  7. package/cjs/src/authToken.d.ts.map +1 -1
  8. package/cjs/src/authToken.js +3 -3
  9. package/cjs/src/authToken.js.map +1 -1
  10. package/cjs/src/embed/base.d.ts +0 -8
  11. package/cjs/src/embed/base.d.ts.map +1 -1
  12. package/cjs/src/embed/base.js +21 -45
  13. package/cjs/src/embed/base.js.map +1 -1
  14. package/cjs/src/embed/base.spec.js +12 -13
  15. package/cjs/src/embed/base.spec.js.map +1 -1
  16. package/cjs/src/embed/embedConfig.d.ts +18 -0
  17. package/cjs/src/embed/embedConfig.d.ts.map +1 -0
  18. package/cjs/src/embed/embedConfig.js +25 -0
  19. package/cjs/src/embed/embedConfig.js.map +1 -0
  20. package/cjs/src/embed/search.d.ts.map +1 -1
  21. package/cjs/src/embed/search.js +3 -2
  22. package/cjs/src/embed/search.js.map +1 -1
  23. package/cjs/src/embed/searchEmbed-basic-auth.spec.js +3 -2
  24. package/cjs/src/embed/searchEmbed-basic-auth.spec.js.map +1 -1
  25. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  26. package/cjs/src/embed/ts-embed.js +2 -1
  27. package/cjs/src/embed/ts-embed.js.map +1 -1
  28. package/cjs/src/embed/ts-embed.spec.js +11 -13
  29. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  30. package/cjs/src/index.d.ts +2 -1
  31. package/cjs/src/index.d.ts.map +1 -1
  32. package/cjs/src/index.js +2 -1
  33. package/cjs/src/index.js.map +1 -1
  34. package/cjs/src/tokenizedFetch.d.ts.map +1 -1
  35. package/cjs/src/tokenizedFetch.js +4 -4
  36. package/cjs/src/tokenizedFetch.js.map +1 -1
  37. package/cjs/src/utils/authService/authService.d.ts +45 -0
  38. package/cjs/src/utils/authService/authService.d.ts.map +1 -0
  39. package/cjs/src/utils/authService/authService.js +115 -0
  40. package/cjs/src/utils/authService/authService.js.map +1 -0
  41. package/cjs/src/utils/authService/authService.spec.d.ts +2 -0
  42. package/cjs/src/utils/authService/authService.spec.d.ts.map +1 -0
  43. package/cjs/src/utils/authService/authService.spec.js +82 -0
  44. package/cjs/src/utils/authService/authService.spec.js.map +1 -0
  45. package/cjs/src/utils/authService/index.d.ts +3 -0
  46. package/cjs/src/utils/authService/index.d.ts.map +1 -0
  47. package/cjs/src/utils/authService/index.js +14 -0
  48. package/cjs/src/utils/authService/index.js.map +1 -0
  49. package/cjs/src/utils/authService/tokenisedAuthSerice.d.ts +11 -0
  50. package/cjs/src/utils/authService/tokenisedAuthSerice.d.ts.map +1 -0
  51. package/cjs/src/utils/authService/tokenisedAuthSerice.js +44 -0
  52. package/cjs/src/utils/authService/tokenisedAuthSerice.js.map +1 -0
  53. package/cjs/src/utils/graphql/answerService/answerService.spec.js +2 -2
  54. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  55. package/cjs/src/utils/processData.js +4 -3
  56. package/cjs/src/utils/processData.js.map +1 -1
  57. package/cjs/src/utils/processData.spec.js +8 -7
  58. package/cjs/src/utils/processData.spec.js.map +1 -1
  59. package/dist/src/auth.d.ts.map +1 -1
  60. package/dist/src/auth.spec.d.ts.map +1 -1
  61. package/dist/src/authToken.d.ts.map +1 -1
  62. package/dist/src/embed/base.d.ts +0 -8
  63. package/dist/src/embed/base.d.ts.map +1 -1
  64. package/dist/src/embed/embedConfig.d.ts +18 -0
  65. package/dist/src/embed/embedConfig.d.ts.map +1 -0
  66. package/dist/src/embed/search.d.ts.map +1 -1
  67. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  68. package/dist/src/index.d.ts +2 -1
  69. package/dist/src/index.d.ts.map +1 -1
  70. package/dist/src/tokenizedFetch.d.ts.map +1 -1
  71. package/dist/src/utils/authService/authService.d.ts +45 -0
  72. package/dist/src/utils/authService/authService.d.ts.map +1 -0
  73. package/dist/src/utils/authService/authService.spec.d.ts +2 -0
  74. package/dist/src/utils/authService/authService.spec.d.ts.map +1 -0
  75. package/dist/src/utils/authService/index.d.ts +3 -0
  76. package/dist/src/utils/authService/index.d.ts.map +1 -0
  77. package/dist/src/utils/authService/tokenisedAuthSerice.d.ts +11 -0
  78. package/dist/src/utils/authService/tokenisedAuthSerice.d.ts.map +1 -0
  79. package/dist/tsembed-react.es.js +1228 -1212
  80. package/dist/tsembed-react.js +1463 -1447
  81. package/dist/tsembed.es.js +1632 -1621
  82. package/dist/tsembed.js +1622 -1611
  83. package/dist/visual-embed-sdk-react-full.d.ts +17 -8
  84. package/dist/visual-embed-sdk-react.d.ts +17 -8
  85. package/dist/visual-embed-sdk.d.ts +17 -8
  86. package/lib/package.json +2 -2
  87. package/lib/src/auth.d.ts.map +1 -1
  88. package/lib/src/auth.js.map +1 -1
  89. package/lib/src/auth.spec.d.ts.map +1 -1
  90. package/lib/src/auth.spec.js +1 -1
  91. package/lib/src/auth.spec.js.map +1 -1
  92. package/lib/src/authToken.d.ts.map +1 -1
  93. package/lib/src/authToken.js +3 -3
  94. package/lib/src/authToken.js.map +1 -1
  95. package/lib/src/embed/base.d.ts +0 -8
  96. package/lib/src/embed/base.d.ts.map +1 -1
  97. package/lib/src/embed/base.js +20 -43
  98. package/lib/src/embed/base.js.map +1 -1
  99. package/lib/src/embed/base.spec.js +12 -13
  100. package/lib/src/embed/base.spec.js.map +1 -1
  101. package/lib/src/embed/embedConfig.d.ts +18 -0
  102. package/lib/src/embed/embedConfig.d.ts.map +1 -0
  103. package/lib/src/embed/embedConfig.js +20 -0
  104. package/lib/src/embed/embedConfig.js.map +1 -0
  105. package/lib/src/embed/search.d.ts.map +1 -1
  106. package/lib/src/embed/search.js +2 -1
  107. package/lib/src/embed/search.js.map +1 -1
  108. package/lib/src/embed/searchEmbed-basic-auth.spec.js +3 -2
  109. package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -1
  110. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  111. package/lib/src/embed/ts-embed.js +2 -1
  112. package/lib/src/embed/ts-embed.js.map +1 -1
  113. package/lib/src/embed/ts-embed.spec.js +11 -13
  114. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  115. package/lib/src/index.d.ts +2 -1
  116. package/lib/src/index.d.ts.map +1 -1
  117. package/lib/src/index.js +2 -1
  118. package/lib/src/index.js.map +1 -1
  119. package/lib/src/tokenizedFetch.d.ts.map +1 -1
  120. package/lib/src/tokenizedFetch.js +3 -3
  121. package/lib/src/tokenizedFetch.js.map +1 -1
  122. package/lib/src/utils/authService/authService.d.ts +45 -0
  123. package/lib/src/utils/authService/authService.d.ts.map +1 -0
  124. package/lib/src/utils/authService/authService.js +107 -0
  125. package/lib/src/utils/authService/authService.js.map +1 -0
  126. package/lib/src/utils/authService/authService.spec.d.ts +2 -0
  127. package/lib/src/utils/authService/authService.spec.d.ts.map +1 -0
  128. package/lib/src/utils/authService/authService.spec.js +80 -0
  129. package/lib/src/utils/authService/authService.spec.js.map +1 -0
  130. package/lib/src/utils/authService/index.d.ts +3 -0
  131. package/lib/src/utils/authService/index.d.ts.map +1 -0
  132. package/lib/src/utils/authService/index.js +3 -0
  133. package/lib/src/utils/authService/index.js.map +1 -0
  134. package/lib/src/utils/authService/tokenisedAuthSerice.d.ts +11 -0
  135. package/lib/src/utils/authService/tokenisedAuthSerice.d.ts.map +1 -0
  136. package/lib/src/utils/authService/tokenisedAuthSerice.js +39 -0
  137. package/lib/src/utils/authService/tokenisedAuthSerice.js.map +1 -0
  138. package/lib/src/utils/graphql/answerService/answerService.spec.js +2 -2
  139. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  140. package/lib/src/utils/processData.js +2 -1
  141. package/lib/src/utils/processData.js.map +1 -1
  142. package/lib/src/utils/processData.spec.js +8 -7
  143. package/lib/src/utils/processData.spec.js.map +1 -1
  144. package/lib/src/visual-embed-sdk.d.ts +22 -9
  145. package/package.json +2 -2
  146. package/src/auth.spec.ts +29 -28
  147. package/src/auth.ts +1 -5
  148. package/src/authToken.ts +11 -3
  149. package/src/embed/base.spec.ts +13 -13
  150. package/src/embed/base.ts +26 -50
  151. package/src/embed/embedConfig.ts +23 -0
  152. package/src/embed/search.ts +9 -10
  153. package/src/embed/searchEmbed-basic-auth.spec.ts +3 -2
  154. package/src/embed/ts-embed.spec.ts +34 -36
  155. package/src/embed/ts-embed.ts +9 -19
  156. package/src/index.ts +8 -2
  157. package/src/tokenizedFetch.ts +6 -4
  158. package/src/utils/{authService.spec.ts → authService/authService.spec.ts} +1 -1
  159. package/src/utils/{authService.ts → authService/authService.ts} +0 -24
  160. package/src/utils/authService/index.ts +9 -0
  161. package/src/utils/authService/tokenisedAuthSerice.ts +40 -0
  162. package/src/utils/graphql/answerService/answerService.spec.ts +2 -2
  163. package/src/utils/processData.spec.ts +19 -16
  164. package/src/utils/processData.ts +1 -1
@@ -5137,15 +5137,6 @@ function failureLoggedFetch(url, options = {}) {
5137
5137
  return r;
5138
5138
  });
5139
5139
  }
5140
- /**
5141
- *
5142
- * @param authVerificationUrl
5143
- */
5144
- function fetchSessionInfoService(authVerificationUrl) {
5145
- return failureLoggedFetch(authVerificationUrl, {
5146
- credentials: 'include',
5147
- });
5148
- }
5149
5140
  /**
5150
5141
  * Service to validate a auth token against a ThoughtSpot host.
5151
5142
  *
@@ -5228,6 +5219,53 @@ async function fetchBasicAuthService(thoughtSpotHost, username, password) {
5228
5219
  });
5229
5220
  }
5230
5221
 
5222
+ let config = {};
5223
+ /**
5224
+ * Gets the configuration embed was initialized with.
5225
+ *
5226
+ * @returns {@link EmbedConfig} The configuration embed was initialized with.
5227
+ * @version SDK: 1.19.0 | ThoughtSpot: *
5228
+ * @group Global methods
5229
+ */
5230
+ const getEmbedConfig = () => config;
5231
+
5232
+ const tokenizedFetch = async (input, init) => {
5233
+ const embedConfig = getEmbedConfig();
5234
+ if (embedConfig.authType !== AuthType.TrustedAuthTokenCookieless) {
5235
+ return fetch(input, init);
5236
+ }
5237
+ const req = new Request(input, init);
5238
+ const authToken = await getAuthenticationToken(embedConfig);
5239
+ if (authToken) {
5240
+ req.headers.append('Authorization', `Bearer ${authToken}`);
5241
+ }
5242
+ return fetch(req);
5243
+ };
5244
+
5245
+ /**
5246
+ *
5247
+ * @param url
5248
+ * @param options
5249
+ */
5250
+ function tokenisedFailureLoggedFetch(url, options = {}) {
5251
+ return tokenizedFetch(url, options).then(async (r) => {
5252
+ var _a;
5253
+ if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
5254
+ console.error('Failure', await ((_a = r.text) === null || _a === void 0 ? void 0 : _a.call(r)));
5255
+ }
5256
+ return r;
5257
+ });
5258
+ }
5259
+ /**
5260
+ *
5261
+ * @param authVerificationUrl
5262
+ */
5263
+ function fetchSessionInfoService(authVerificationUrl) {
5264
+ return tokenisedFailureLoggedFetch(authVerificationUrl, {
5265
+ credentials: 'include',
5266
+ });
5267
+ }
5268
+
5231
5269
  const DUPLICATE_TOKEN_ERR = 'Duplicate token, please issue a new token every time getAuthToken callback is called.'
5232
5270
  + 'See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.';
5233
5271
  const INVALID_TOKEN_ERR = 'Invalid token received form token callback or authToken endpoint.';
@@ -5236,7 +5274,7 @@ let cachedAuthToken = null;
5236
5274
  const getAuthenticationToken = async (embedConfig) => {
5237
5275
  if (cachedAuthToken) {
5238
5276
  try {
5239
- const isCachedTokenStillValid = await validateAuthToken(embedConfig, cachedAuthToken);
5277
+ const isCachedTokenStillValid = await validateAuthToken(embedConfig, cachedAuthToken, true);
5240
5278
  if (isCachedTokenStillValid)
5241
5279
  return cachedAuthToken;
5242
5280
  }
@@ -5258,7 +5296,7 @@ const getAuthenticationToken = async (embedConfig) => {
5258
5296
  cachedAuthToken = authToken;
5259
5297
  return authToken;
5260
5298
  };
5261
- const validateAuthToken = async (embedConfig, authToken) => {
5299
+ const validateAuthToken = async (embedConfig, authToken, suppressAlert) => {
5262
5300
  try {
5263
5301
  const isTokenValid = await verifyTokenService(embedConfig.thoughtSpotHost, authToken);
5264
5302
  if (isTokenValid)
@@ -5268,7 +5306,7 @@ const validateAuthToken = async (embedConfig, authToken) => {
5268
5306
  return false;
5269
5307
  }
5270
5308
  if (cachedAuthToken && cachedAuthToken === authToken) {
5271
- if (!embedConfig.suppressErrorAlerts) {
5309
+ if (!embedConfig.suppressErrorAlerts && !suppressAlert) {
5272
5310
  // eslint-disable-next-line no-alert
5273
5311
  alert(DUPLICATE_TOKEN_ERR);
5274
5312
  }
@@ -5279,442 +5317,453 @@ const validateAuthToken = async (embedConfig, authToken) => {
5279
5317
  }
5280
5318
  };
5281
5319
 
5282
- var eventemitter3 = createCommonjsModule(function (module) {
5283
-
5284
- var has = Object.prototype.hasOwnProperty
5285
- , prefix = '~';
5286
-
5287
- /**
5288
- * Constructor to create a storage for our `EE` objects.
5289
- * An `Events` instance is a plain object whose properties are event names.
5290
- *
5291
- * @constructor
5292
- * @private
5293
- */
5294
- function Events() {}
5295
-
5296
- //
5297
- // We try to not inherit from `Object.prototype`. In some engines creating an
5298
- // instance in this way is faster than calling `Object.create(null)` directly.
5299
- // If `Object.create(null)` is not supported we prefix the event names with a
5300
- // character to make sure that the built-in object properties are not
5301
- // overridden or used as an attack vector.
5302
- //
5303
- if (Object.create) {
5304
- Events.prototype = Object.create(null);
5305
-
5306
- //
5307
- // This hack is needed because the `__proto__` property is still inherited in
5308
- // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
5309
- //
5310
- if (!new Events().__proto__) prefix = false;
5311
- }
5312
-
5313
- /**
5314
- * Representation of a single event listener.
5315
- *
5316
- * @param {Function} fn The listener function.
5317
- * @param {*} context The context to invoke the listener with.
5318
- * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
5319
- * @constructor
5320
- * @private
5321
- */
5322
- function EE(fn, context, once) {
5323
- this.fn = fn;
5324
- this.context = context;
5325
- this.once = once || false;
5326
- }
5327
-
5328
- /**
5329
- * Add a listener for a given event.
5330
- *
5331
- * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
5332
- * @param {(String|Symbol)} event The event name.
5333
- * @param {Function} fn The listener function.
5334
- * @param {*} context The context to invoke the listener with.
5335
- * @param {Boolean} once Specify if the listener is a one-time listener.
5336
- * @returns {EventEmitter}
5337
- * @private
5338
- */
5339
- function addListener(emitter, event, fn, context, once) {
5340
- if (typeof fn !== 'function') {
5341
- throw new TypeError('The listener must be a function');
5342
- }
5343
-
5344
- var listener = new EE(fn, context || emitter, once)
5345
- , evt = prefix ? prefix + event : event;
5346
-
5347
- if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
5348
- else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
5349
- else emitter._events[evt] = [emitter._events[evt], listener];
5350
-
5351
- return emitter;
5320
+ /**
5321
+ *
5322
+ * @param root0
5323
+ * @param root0.query
5324
+ * @param root0.variables
5325
+ * @param root0.thoughtSpotHost
5326
+ * @param root0.isCompositeQuery
5327
+ */
5328
+ async function graphqlQuery({ query, variables, thoughtSpotHost, isCompositeQuery = false, }) {
5329
+ const operationName = getOperationNameFromQuery(query);
5330
+ try {
5331
+ const response = await fetch(`${thoughtSpotHost}/prism/?op=${operationName}`, {
5332
+ method: 'POST',
5333
+ headers: {
5334
+ 'content-type': 'application/json;charset=UTF-8',
5335
+ 'x-requested-by': 'ThoughtSpot',
5336
+ accept: '*/*',
5337
+ 'accept-language': 'en-us',
5338
+ },
5339
+ body: JSON.stringify({
5340
+ operationName,
5341
+ query,
5342
+ variables,
5343
+ }),
5344
+ credentials: 'include',
5345
+ });
5346
+ const result = await response.json();
5347
+ const dataValues = Object.values(result.data);
5348
+ return (isCompositeQuery) ? result.data : dataValues[0];
5349
+ }
5350
+ catch (error) {
5351
+ return error;
5352
+ }
5352
5353
  }
5353
5354
 
5354
- /**
5355
- * Clear event by name.
5356
- *
5357
- * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
5358
- * @param {(String|Symbol)} evt The Event name.
5359
- * @private
5360
- */
5361
- function clearEvent(emitter, evt) {
5362
- if (--emitter._eventsCount === 0) emitter._events = new Events();
5363
- else delete emitter._events[evt];
5355
+ const getSourceDetailQuery = `
5356
+ query GetSourceDetail($ids: [GUID!]!) {
5357
+ getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {
5358
+ id
5359
+ name
5360
+ description
5361
+ authorName
5362
+ authorDisplayName
5363
+ isExternal
5364
+ type
5365
+ created
5366
+ modified
5367
+ columns {
5368
+ id
5369
+ name
5370
+ author
5371
+ authorDisplayName
5372
+ description
5373
+ dataType
5374
+ type
5375
+ modified
5376
+ ownerName
5377
+ owner
5378
+ dataRecency
5379
+ sources {
5380
+ tableId
5381
+ tableName
5382
+ columnId
5383
+ columnName
5384
+ __typename
5385
+ }
5386
+ synonyms
5387
+ cohortAnswerId
5388
+ __typename
5389
+ }
5390
+ relationships
5391
+ destinationRelationships
5392
+ dataSourceId
5393
+ __typename
5394
+ }
5395
+ }
5396
+ `;
5397
+ const sourceDetailCache = new Map();
5398
+ /**
5399
+ *
5400
+ * @param thoughtSpotHost
5401
+ * @param sourceId
5402
+ */
5403
+ async function getSourceDetail(thoughtSpotHost, sourceId) {
5404
+ if (sourceDetailCache.get(sourceId)) {
5405
+ return sourceDetailCache.get(sourceId);
5406
+ }
5407
+ const details = await graphqlQuery({
5408
+ query: getSourceDetailQuery,
5409
+ variables: {
5410
+ ids: [sourceId],
5411
+ },
5412
+ thoughtSpotHost,
5413
+ });
5414
+ const souceDetails = details[0];
5415
+ if (souceDetails) {
5416
+ sourceDetailCache.set(sourceId, souceDetails);
5417
+ }
5418
+ return souceDetails;
5364
5419
  }
5365
5420
 
5366
- /**
5367
- * Minimal `EventEmitter` interface that is molded against the Node.js
5368
- * `EventEmitter` interface.
5369
- *
5370
- * @constructor
5371
- * @public
5372
- */
5373
- function EventEmitter() {
5374
- this._events = new Events();
5375
- this._eventsCount = 0;
5421
+ const bachSessionId = `
5422
+ id {
5423
+ sessionId
5424
+ genNo
5425
+ acSession {
5426
+ sessionId
5427
+ genNo
5428
+ }
5376
5429
  }
5377
-
5378
- /**
5379
- * Return an array listing the events for which the emitter has registered
5380
- * listeners.
5381
- *
5382
- * @returns {Array}
5383
- * @public
5384
- */
5385
- EventEmitter.prototype.eventNames = function eventNames() {
5386
- var names = []
5387
- , events
5388
- , name;
5389
-
5390
- if (this._eventsCount === 0) return names;
5391
-
5392
- for (name in (events = this._events)) {
5393
- if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
5394
- }
5395
-
5396
- if (Object.getOwnPropertySymbols) {
5397
- return names.concat(Object.getOwnPropertySymbols(events));
5398
- }
5399
-
5400
- return names;
5401
- };
5402
-
5403
- /**
5404
- * Return the listeners registered for a given event.
5405
- *
5406
- * @param {(String|Symbol)} event The event name.
5407
- * @returns {Array} The registered listeners.
5408
- * @public
5409
- */
5410
- EventEmitter.prototype.listeners = function listeners(event) {
5411
- var evt = prefix ? prefix + event : event
5412
- , handlers = this._events[evt];
5413
-
5414
- if (!handlers) return [];
5415
- if (handlers.fn) return [handlers.fn];
5416
-
5417
- for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
5418
- ee[i] = handlers[i].fn;
5419
- }
5420
-
5421
- return ee;
5422
- };
5423
-
5424
- /**
5425
- * Return the number of listeners listening to a given event.
5426
- *
5427
- * @param {(String|Symbol)} event The event name.
5428
- * @returns {Number} The number of listeners.
5429
- * @public
5430
- */
5431
- EventEmitter.prototype.listenerCount = function listenerCount(event) {
5432
- var evt = prefix ? prefix + event : event
5433
- , listeners = this._events[evt];
5434
-
5435
- if (!listeners) return 0;
5436
- if (listeners.fn) return 1;
5437
- return listeners.length;
5438
- };
5439
-
5440
- /**
5441
- * Calls each of the listeners registered for a given event.
5442
- *
5443
- * @param {(String|Symbol)} event The event name.
5444
- * @returns {Boolean} `true` if the event had listeners, else `false`.
5445
- * @public
5446
- */
5447
- EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
5448
- var evt = prefix ? prefix + event : event;
5449
-
5450
- if (!this._events[evt]) return false;
5451
-
5452
- var listeners = this._events[evt]
5453
- , len = arguments.length
5454
- , args
5455
- , i;
5456
-
5457
- if (listeners.fn) {
5458
- if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
5459
-
5460
- switch (len) {
5461
- case 1: return listeners.fn.call(listeners.context), true;
5462
- case 2: return listeners.fn.call(listeners.context, a1), true;
5463
- case 3: return listeners.fn.call(listeners.context, a1, a2), true;
5464
- case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
5465
- case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
5466
- case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
5467
- }
5468
-
5469
- for (i = 1, args = new Array(len -1); i < len; i++) {
5470
- args[i - 1] = arguments[i];
5430
+ `;
5431
+ const getUnaggregatedAnswerSession = `
5432
+ mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
5433
+ Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
5434
+ ${bachSessionId}
5435
+ answer {
5436
+ visualizations {
5437
+ ... on TableViz {
5438
+ columns {
5439
+ column {
5440
+ id
5441
+ name
5442
+ referencedColumns {
5443
+ guid
5444
+ displayName
5445
+ }
5446
+ }
5447
+ }
5448
+ }
5449
+ }
5450
+ }
5471
5451
  }
5472
-
5473
- listeners.fn.apply(listeners.context, args);
5474
- } else {
5475
- var length = listeners.length
5476
- , j;
5477
-
5478
- for (i = 0; i < length; i++) {
5479
- if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
5480
-
5481
- switch (len) {
5482
- case 1: listeners[i].fn.call(listeners[i].context); break;
5483
- case 2: listeners[i].fn.call(listeners[i].context, a1); break;
5484
- case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
5485
- case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
5486
- default:
5487
- if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
5488
- args[j - 1] = arguments[j];
5489
- }
5490
-
5491
- listeners[i].fn.apply(listeners[i].context, args);
5492
- }
5452
+ }
5453
+ `;
5454
+ const removeColumns = `
5455
+ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
5456
+ Answer__removeColumns(
5457
+ session: $session
5458
+ logicalColumnIds: $logicalColumnIds
5459
+ columnIds: $columnIds
5460
+ ) {
5461
+ ${bachSessionId}
5493
5462
  }
5494
- }
5495
-
5496
- return true;
5497
- };
5498
-
5499
- /**
5500
- * Add a listener for a given event.
5501
- *
5502
- * @param {(String|Symbol)} event The event name.
5503
- * @param {Function} fn The listener function.
5504
- * @param {*} [context=this] The context to invoke the listener with.
5505
- * @returns {EventEmitter} `this`.
5506
- * @public
5507
- */
5508
- EventEmitter.prototype.on = function on(event, fn, context) {
5509
- return addListener(this, event, fn, context, false);
5510
- };
5511
-
5512
- /**
5513
- * Add a one-time listener for a given event.
5514
- *
5515
- * @param {(String|Symbol)} event The event name.
5516
- * @param {Function} fn The listener function.
5517
- * @param {*} [context=this] The context to invoke the listener with.
5518
- * @returns {EventEmitter} `this`.
5519
- * @public
5520
- */
5521
- EventEmitter.prototype.once = function once(event, fn, context) {
5522
- return addListener(this, event, fn, context, true);
5523
- };
5524
-
5525
- /**
5526
- * Remove the listeners of a given event.
5527
- *
5528
- * @param {(String|Symbol)} event The event name.
5529
- * @param {Function} fn Only remove the listeners that match this function.
5530
- * @param {*} context Only remove the listeners that have this context.
5531
- * @param {Boolean} once Only remove one-time listeners.
5532
- * @returns {EventEmitter} `this`.
5533
- * @public
5534
- */
5535
- EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
5536
- var evt = prefix ? prefix + event : event;
5537
-
5538
- if (!this._events[evt]) return this;
5539
- if (!fn) {
5540
- clearEvent(this, evt);
5541
- return this;
5542
- }
5543
-
5544
- var listeners = this._events[evt];
5545
-
5546
- if (listeners.fn) {
5547
- if (
5548
- listeners.fn === fn &&
5549
- (!once || listeners.once) &&
5550
- (!context || listeners.context === context)
5551
- ) {
5552
- clearEvent(this, evt);
5463
+ }
5464
+ `;
5465
+ const addColumns = `
5466
+ mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
5467
+ Answer__addColumn(session: $session, columns: $columns) {
5468
+ ${bachSessionId}
5469
+ }
5553
5470
  }
5554
- } else {
5555
- for (var i = 0, events = [], length = listeners.length; i < length; i++) {
5556
- if (
5557
- listeners[i].fn !== fn ||
5558
- (once && !listeners[i].once) ||
5559
- (context && listeners[i].context !== context)
5560
- ) {
5561
- events.push(listeners[i]);
5562
- }
5471
+ `;
5472
+ const getAnswerData = `
5473
+ query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
5474
+ getAnswer(session: $session) {
5475
+ ${bachSessionId}
5476
+ answer {
5477
+ id
5478
+ visualizations {
5479
+ id
5480
+ ... on TableViz {
5481
+ columns {
5482
+ column {
5483
+ id
5484
+ name
5485
+ type
5486
+ aggregationType
5487
+ dataType
5488
+ }
5489
+ }
5490
+ data(deadline: $deadline, pagination: $dataPaginationParams)
5491
+ }
5492
+ }
5493
+ }
5494
+ }
5563
5495
  }
5496
+ `;
5564
5497
 
5565
- //
5566
- // Reset the array, or remove it completely if we have no more listeners.
5567
- //
5568
- if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
5569
- else clearEvent(this, evt);
5570
- }
5571
-
5572
- return this;
5573
- };
5574
-
5575
- /**
5576
- * Remove all listeners, or those of the specified event.
5577
- *
5578
- * @param {(String|Symbol)} [event] The event name.
5579
- * @returns {EventEmitter} `this`.
5580
- * @public
5581
- */
5582
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
5583
- var evt;
5584
-
5585
- if (event) {
5586
- evt = prefix ? prefix + event : event;
5587
- if (this._events[evt]) clearEvent(this, evt);
5588
- } else {
5589
- this._events = new Events();
5590
- this._eventsCount = 0;
5591
- }
5592
-
5593
- return this;
5594
- };
5595
-
5596
- //
5597
- // Alias methods names because people roll like that.
5598
- //
5599
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
5600
- EventEmitter.prototype.addListener = EventEmitter.prototype.on;
5601
-
5602
- //
5603
- // Expose the prefix.
5604
- //
5605
- EventEmitter.prefixed = prefix;
5606
-
5607
- //
5608
- // Allow `EventEmitter` to be imported as module namespace.
5609
- //
5610
- EventEmitter.EventEmitter = EventEmitter;
5611
-
5612
- //
5613
- // Expose the module.
5614
- //
5615
- {
5616
- module.exports = EventEmitter;
5617
- }
5618
- });
5619
-
5620
- /**
5621
- * This method returns `undefined`.
5622
- *
5623
- * @static
5624
- * @memberOf _
5625
- * @since 2.3.0
5626
- * @category Util
5627
- * @example
5628
- *
5629
- * _.times(2, _.noop);
5630
- * // => [undefined, undefined]
5631
- */
5632
- function noop() {
5633
- // No operation performed.
5634
- }
5635
-
5636
- var noop_1 = noop;
5637
-
5638
- /** Used as references for various `Number` constants. */
5639
- var INFINITY = 1 / 0;
5640
-
5641
- /**
5642
- * Creates a set object of `values`.
5643
- *
5644
- * @private
5645
- * @param {Array} values The values to add to the set.
5646
- * @returns {Object} Returns the new set.
5647
- */
5648
- var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) {
5649
- return new _Set(values);
5650
- };
5651
-
5652
- const ERROR_MESSAGE = {
5653
- INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
5654
- LIVEBOARD_VIZ_ID_VALIDATION: 'Please provide either liveboardId or pinboardId',
5655
- TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
5656
- SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
5657
- SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
5658
- };
5659
-
5660
- /**
5661
- * Copyright (c) 2023
5662
- *
5663
- * Utilities related to reading configuration objects
5664
- *
5665
- * @summary Config-related utils
5666
- * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
5667
- */
5668
- const urlRegex = new RegExp([
5669
- '(^(https?:)//)?',
5670
- '(([^:/?#]*)(?::([0-9]+))?)',
5671
- '(/{0,1}[^?#]*)',
5672
- '(\\?[^#]*|)',
5673
- '(#.*|)$', // hash
5674
- ].join(''));
5498
+ // eslint-disable-next-line no-shadow
5499
+ var OperationType;
5500
+ (function (OperationType) {
5501
+ OperationType["GetChartWithData"] = "GetChartWithData";
5502
+ OperationType["GetTableWithHeadlineData"] = "GetTableWithHeadlineData";
5503
+ })(OperationType || (OperationType = {}));
5675
5504
  /**
5676
- * Parse and construct the ThoughtSpot hostname or IP address
5677
- * from the embed configuration object.
5505
+ * Class representing the answer service provided with the
5506
+ * custom action payload. This service could be used to run
5507
+ * graphql queries in the context of the answer on which the
5508
+ * custom action was triggered.
5678
5509
  *
5679
- * @param config
5510
+ * @example
5511
+ * ```js
5512
+ * embed.on(EmbedEvent.CustomAction, e => {
5513
+ * const underlying = await e.answerService.getUnderlyingDataForPoint([
5514
+ * 'col name 1'
5515
+ * ]);
5516
+ * const data = await underlying.fetchData(0, 100);
5517
+ * })
5518
+ * ```
5519
+ * @version
5520
+ * ThoughtSpot: 9.9.0.cl / SDK: 1.25.0
5521
+ * @group Events
5680
5522
  */
5681
- const getThoughtSpotHost = (config) => {
5682
- if (!config.thoughtSpotHost) {
5683
- throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
5523
+ class AnswerService {
5524
+ constructor(session, answer, thoughtSpotHost, selectedPoints) {
5525
+ this.session = session;
5526
+ this.answer = answer;
5527
+ this.thoughtSpotHost = thoughtSpotHost;
5528
+ this.selectedPoints = selectedPoints;
5529
+ this.session = removeTypename(session);
5684
5530
  }
5685
- const urlParts = config.thoughtSpotHost.match(urlRegex);
5686
- if (!urlParts) {
5687
- throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
5531
+ async getSourceDetail() {
5532
+ const sourceId = this.answer.sources[0].header.guid;
5533
+ return getSourceDetail(this.thoughtSpotHost, sourceId);
5688
5534
  }
5689
- const protocol = urlParts[2] || window.location.protocol;
5690
- const host = urlParts[3];
5691
- let path = urlParts[6];
5692
- // Lose the trailing / if any
5693
- if (path.charAt(path.length - 1) === '/') {
5694
- path = path.substring(0, path.length - 1);
5535
+ async removeColumns(columnIds) {
5536
+ return this.executeQuery(removeColumns, {
5537
+ logicalColumnIds: columnIds,
5538
+ });
5695
5539
  }
5696
- // const urlParams = urlParts[7];
5697
- // const hash = urlParts[8];
5698
- return `${protocol}//${host}${path}`;
5699
- };
5700
- const getV2BasePath = (config) => {
5701
- if (config.basepath) {
5702
- return config.basepath;
5540
+ async addColumns(columnIds) {
5541
+ return this.executeQuery(addColumns, {
5542
+ columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
5543
+ });
5703
5544
  }
5704
- const tsHost = getThoughtSpotHost(config);
5705
- // This is to handle when e2e's. Search is run on pods for
5706
- // comp-blink-test-pipeline with baseUrl=https://localhost:8443.
5707
- // This is to handle when the developer is developing in their local
5708
- // environment.
5709
- if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
5710
- return '';
5545
+ async fetchData(offset = 0, size = 1000) {
5546
+ const { answer } = await this.executeQuery(getAnswerData, {
5547
+ deadline: 0,
5548
+ dataPaginationParams: {
5549
+ isClientPaginated: true,
5550
+ offset,
5551
+ size,
5552
+ },
5553
+ });
5554
+ const { columns, data } = answer.visualizations[0];
5555
+ return {
5556
+ columns,
5557
+ data,
5558
+ };
5711
5559
  }
5712
- return 'v2';
5713
- };
5560
+ /**
5561
+ *
5562
+ * @param userLocale
5563
+ * @param includeInfo Include the CSV header in the output
5564
+ * @returns Response
5565
+ */
5566
+ async fetchCSVBlob(userLocale = 'en-us', includeInfo = false) {
5567
+ const fetchUrl = this.getFetchCSVBlobUrl(userLocale, includeInfo);
5568
+ return tokenizedFetch(fetchUrl, {
5569
+ credentials: 'include',
5570
+ });
5571
+ }
5572
+ getFetchCSVBlobUrl(userLocale = 'en-us', includeInfo = false) {
5573
+ return `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
5574
+ }
5575
+ /**
5576
+ * Get underlying data given a point and the output column names.
5577
+ *
5578
+ * @param outputColumnNames
5579
+ * @param selectedPoints
5580
+ * @example
5581
+ * ```js
5582
+ * embed.on(EmbedEvent.CustomAction, e => {
5583
+ * const underlying = await e.answerService.getUnderlyingDataForPoint([
5584
+ * 'col name 1' // The column should exist in the data source.
5585
+ * ]);
5586
+ * const data = await underlying.fetchData(0, 100);
5587
+ * })
5588
+ * ```
5589
+ * @version
5590
+ * ThoughtSpot: 9.9.0.cl / SDK: 1.25.0
5591
+ */
5592
+ async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
5593
+ if (!selectedPoints && !this.selectedPoints) {
5594
+ throw new Error('Needs to be triggered in context of a point');
5595
+ }
5596
+ if (!selectedPoints) {
5597
+ selectedPoints = getSelectedPointsForUnderlyingDataQuery(this.selectedPoints);
5598
+ }
5599
+ const sourceDetail = await this.getSourceDetail();
5600
+ const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
5601
+ const unAggAnswer = await graphqlQuery({
5602
+ query: getUnaggregatedAnswerSession,
5603
+ variables: {
5604
+ session: this.session,
5605
+ columns: selectedPoints,
5606
+ },
5607
+ thoughtSpotHost: this.thoughtSpotHost,
5608
+ });
5609
+ const unaggAnswerSession = new AnswerService(unAggAnswer.id, unAggAnswer.answer, this.thoughtSpotHost);
5610
+ const currentColumns = new Set(unAggAnswer.answer.visualizations[0].columns
5611
+ .map((c) => c.column.referencedColumns[0].guid));
5612
+ const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
5613
+ if (columnsToAdd.length) {
5614
+ await unaggAnswerSession.addColumns(columnsToAdd);
5615
+ }
5616
+ const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
5617
+ if (columnsToRemove.length) {
5618
+ await unaggAnswerSession.removeColumns(columnsToRemove);
5619
+ }
5620
+ return unaggAnswerSession;
5621
+ }
5622
+ async executeQuery(query, variables) {
5623
+ const data = await graphqlQuery({
5624
+ query,
5625
+ variables: {
5626
+ session: this.session,
5627
+ ...variables,
5628
+ },
5629
+ thoughtSpotHost: this.thoughtSpotHost,
5630
+ isCompositeQuery: false,
5631
+ });
5632
+ this.session = deepMerge(this.session, (data === null || data === void 0 ? void 0 : data.id) || {});
5633
+ return data;
5634
+ }
5635
+ getSession() {
5636
+ return this.session;
5637
+ }
5638
+ }
5714
5639
  /**
5715
- * It is a good idea to keep URLs under 2000 chars.
5716
- * If this is ever breached, since we pass view configuration through
5717
- * URL params, we would like to log a warning.
5640
+ *
5641
+ * @param sourceDetail
5642
+ * @param colNames
5643
+ */
5644
+ function getGuidsFromColumnNames(sourceDetail, colNames) {
5645
+ const cols = sourceDetail.columns.reduce((colSet, col) => {
5646
+ colSet[col.name] = col;
5647
+ return colSet;
5648
+ }, {});
5649
+ return new Set(colNames.map((colName) => {
5650
+ const col = cols[colName];
5651
+ return col.id;
5652
+ }));
5653
+ }
5654
+ /**
5655
+ *
5656
+ * @param selectedPoints
5657
+ */
5658
+ function getSelectedPointsForUnderlyingDataQuery(selectedPoints) {
5659
+ const underlyingDataPoint = [];
5660
+ /**
5661
+ *
5662
+ * @param colVal
5663
+ */
5664
+ function addPointFromColVal(colVal) {
5665
+ var _a;
5666
+ const dataType = colVal.column.dataType;
5667
+ const id = colVal.column.id;
5668
+ let dataValue;
5669
+ if (dataType === 'DATE') {
5670
+ if (Number.isFinite(colVal.value)) {
5671
+ dataValue = [{
5672
+ epochRange: {
5673
+ startEpoch: colVal.value,
5674
+ },
5675
+ }];
5676
+ // Case for custom calendar.
5677
+ }
5678
+ else if ((_a = colVal.value) === null || _a === void 0 ? void 0 : _a.v) {
5679
+ dataValue = [{
5680
+ epochRange: {
5681
+ startEpoch: colVal.value.v.s,
5682
+ endEpoch: colVal.value.v.e,
5683
+ },
5684
+ }];
5685
+ }
5686
+ }
5687
+ else {
5688
+ dataValue = [{ value: colVal.value }];
5689
+ }
5690
+ underlyingDataPoint.push({
5691
+ columnId: colVal.column.id,
5692
+ dataValue,
5693
+ });
5694
+ }
5695
+ selectedPoints.forEach((p) => {
5696
+ p.selectedAttributes.forEach(addPointFromColVal);
5697
+ });
5698
+ return underlyingDataPoint;
5699
+ }
5700
+
5701
+ const ERROR_MESSAGE = {
5702
+ INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
5703
+ LIVEBOARD_VIZ_ID_VALIDATION: 'Please provide either liveboardId or pinboardId',
5704
+ TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
5705
+ SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
5706
+ SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
5707
+ };
5708
+
5709
+ /**
5710
+ * Copyright (c) 2023
5711
+ *
5712
+ * Utilities related to reading configuration objects
5713
+ *
5714
+ * @summary Config-related utils
5715
+ * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
5716
+ */
5717
+ const urlRegex = new RegExp([
5718
+ '(^(https?:)//)?',
5719
+ '(([^:/?#]*)(?::([0-9]+))?)',
5720
+ '(/{0,1}[^?#]*)',
5721
+ '(\\?[^#]*|)',
5722
+ '(#.*|)$', // hash
5723
+ ].join(''));
5724
+ /**
5725
+ * Parse and construct the ThoughtSpot hostname or IP address
5726
+ * from the embed configuration object.
5727
+ *
5728
+ * @param config
5729
+ */
5730
+ const getThoughtSpotHost = (config) => {
5731
+ if (!config.thoughtSpotHost) {
5732
+ throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
5733
+ }
5734
+ const urlParts = config.thoughtSpotHost.match(urlRegex);
5735
+ if (!urlParts) {
5736
+ throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
5737
+ }
5738
+ const protocol = urlParts[2] || window.location.protocol;
5739
+ const host = urlParts[3];
5740
+ let path = urlParts[6];
5741
+ // Lose the trailing / if any
5742
+ if (path.charAt(path.length - 1) === '/') {
5743
+ path = path.substring(0, path.length - 1);
5744
+ }
5745
+ // const urlParams = urlParts[7];
5746
+ // const hash = urlParts[8];
5747
+ return `${protocol}//${host}${path}`;
5748
+ };
5749
+ const getV2BasePath = (config) => {
5750
+ if (config.basepath) {
5751
+ return config.basepath;
5752
+ }
5753
+ const tsHost = getThoughtSpotHost(config);
5754
+ // This is to handle when e2e's. Search is run on pods for
5755
+ // comp-blink-test-pipeline with baseUrl=https://localhost:8443.
5756
+ // This is to handle when the developer is developing in their local
5757
+ // environment.
5758
+ if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
5759
+ return '';
5760
+ }
5761
+ return 'v2';
5762
+ };
5763
+ /**
5764
+ * It is a good idea to keep URLs under 2000 chars.
5765
+ * If this is ever breached, since we pass view configuration through
5766
+ * URL params, we would like to log a warning.
5718
5767
  * Reference: https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
5719
5768
  */
5720
5769
  const URL_MAX_LENGTH = 2000;
@@ -11780,827 +11829,794 @@ function initMixpanel(sessionInfo) {
11780
11829
  }
11781
11830
  }
11782
11831
 
11783
- // eslint-disable-next-line import/no-mutable-exports
11784
- let loggedInStatus = false;
11785
- // eslint-disable-next-line import/no-mutable-exports
11786
- let samlAuthWindow = null;
11787
- // eslint-disable-next-line import/no-mutable-exports
11788
- let samlCompletionPromise = null;
11789
- let sessionInfo = null;
11790
- let sessionInfoResolver = null;
11791
- const sessionInfoPromise = new Promise((resolve) => {
11792
- sessionInfoResolver = resolve;
11793
- });
11794
- let releaseVersion = '';
11795
- const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
11796
- /**
11797
- * Enum for auth failure types. This is the parameter passed to the listner
11798
- * of {@link AuthStatus.FAILURE}.
11799
- *
11800
- * @group Authentication / Init
11801
- */
11802
- var AuthFailureType;
11803
- (function (AuthFailureType) {
11804
- AuthFailureType["SDK"] = "SDK";
11805
- AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
11806
- AuthFailureType["EXPIRY"] = "EXPIRY";
11807
- AuthFailureType["OTHER"] = "OTHER";
11808
- })(AuthFailureType || (AuthFailureType = {}));
11809
- /**
11810
- * Enum for auth status emitted by the emitter returned from {@link init}.
11811
- *
11812
- * @group Authentication / Init
11813
- */
11814
- var AuthStatus;
11815
- (function (AuthStatus) {
11816
- /**
11817
- * Emits when the SDK fails to authenticate
11818
- */
11819
- AuthStatus["FAILURE"] = "FAILURE";
11820
- /**
11821
- * Emits when the SDK authenticates successfully
11822
- */
11823
- AuthStatus["SDK_SUCCESS"] = "SDK_SUCCESS";
11824
- /**
11825
- * Emits when the app sends an authentication success message
11826
- */
11827
- AuthStatus["SUCCESS"] = "SUCCESS";
11828
- /**
11829
- * Emits when a user logs out
11830
- */
11831
- AuthStatus["LOGOUT"] = "LOGOUT";
11832
- /**
11833
- * Emitted when inPopup: true in the SAMLRedirect flow.
11834
- * And, we are waiting for popup to be triggered either programatically
11835
- * or by the trigger button.
11836
- *
11837
- * @version SDK: 1.19.0
11838
- */
11839
- AuthStatus["WAITING_FOR_POPUP"] = "WAITING_FOR_POPUP";
11840
- })(AuthStatus || (AuthStatus = {}));
11841
- /**
11842
- * Events which can be triggered on the emitter returned from {@link init}.
11843
- *
11844
- * @group Authentication / Init
11845
- */
11846
- var AuthEvent;
11847
- (function (AuthEvent) {
11848
- /**
11849
- * Manually trigger the SSO popup. This is useful with
11850
- * authStatus: SAMLRedirect/OIDCRedicre and inPopup: true
11851
- */
11852
- AuthEvent["TRIGGER_SSO_POPUP"] = "TRIGGER_SSO_POPUP";
11853
- })(AuthEvent || (AuthEvent = {}));
11854
- /**
11855
- *
11856
- */
11857
- function notifyAuthSDKSuccess() {
11858
- {
11859
- console.error('SDK not initialized');
11860
- return;
11861
- }
11862
- }
11863
- /**
11864
- *
11865
- */
11866
- function notifyAuthSuccess() {
11867
- {
11868
- console.error('SDK not initialized');
11869
- return;
11870
- }
11871
- }
11872
- /**
11873
- *
11874
- * @param failureType
11875
- */
11876
- function notifyAuthFailure(failureType) {
11877
- {
11878
- console.error('SDK not initialized');
11879
- return;
11880
- }
11881
- }
11882
- /**
11883
- *
11884
- */
11885
- function notifyLogout() {
11886
- {
11887
- console.error('SDK not initialized');
11888
- return;
11889
- }
11890
- }
11891
- const initSession = (sessionDetails) => {
11892
- if (sessionInfo == null) {
11893
- sessionInfo = sessionDetails;
11894
- initMixpanel(sessionInfo);
11895
- sessionInfoResolver(sessionInfo);
11896
- }
11897
- };
11898
- const getSessionDetails = (sessionInfoResp) => {
11899
- console.log('helloooo');
11900
- const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
11901
- const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
11902
- const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
11903
- ? prodMixpanelToken
11904
- : devMixpanelToken;
11905
- return {
11906
- userGUID: sessionInfoResp.userGUID,
11907
- mixpanelToken,
11908
- isPublicUser: sessionInfoResp.configInfo.isPublicUser,
11909
- releaseVersion: sessionInfoResp.releaseVersion,
11910
- clusterId: sessionInfoResp.configInfo.selfClusterId,
11911
- clusterName: sessionInfoResp.configInfo.selfClusterName,
11912
- ...sessionInfoResp,
11913
- };
11914
- };
11915
- /**
11916
- * Check if we are logged into the ThoughtSpot cluster
11917
- *
11918
- * @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
11919
- */
11920
- async function isLoggedIn(thoughtSpotHost) {
11921
- const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
11922
- let response = null;
11923
- try {
11924
- response = await fetchSessionInfoService(authVerificationUrl);
11925
- const sessionInfoResp = await response.json();
11926
- const sessionDetails = getSessionDetails(sessionInfoResp);
11927
- // Store user session details from session info
11928
- initSession(sessionDetails);
11929
- releaseVersion = sessionInfoResp.releaseVersion;
11930
- }
11931
- catch (e) {
11932
- return false;
11933
- }
11934
- return response.status === 200;
11935
- }
11936
- /**
11937
- * Return releaseVersion if available
11938
- */
11939
- function getReleaseVersion() {
11940
- return releaseVersion;
11941
- }
11942
- /**
11943
- * Check if we are stuck at the SSO redirect URL
11944
- */
11945
- function isAtSSORedirectUrl() {
11946
- return window.location.href.indexOf(SSO_REDIRECTION_MARKER_GUID) >= 0;
11947
- }
11948
- /**
11949
- * Remove the SSO redirect URL marker
11950
- */
11951
- function removeSSORedirectUrlMarker() {
11952
- // Note (sunny): This will leave a # around even if it was not in the URL
11953
- // to begin with. Trying to remove the hash by changing window.location will
11954
- // reload the page which we don't want. We'll live with adding an
11955
- // unnecessary hash to the parent page URL until we find any use case where
11956
- // that creates an issue.
11957
- window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
11958
- }
11959
- /**
11960
- * Perform token based authentication
11961
- *
11962
- * @param embedConfig The embed configuration
11963
- */
11964
- const doTokenAuth = async (embedConfig) => {
11965
- const { thoughtSpotHost, username, authEndpoint, getAuthToken, } = embedConfig;
11966
- if (!authEndpoint && !getAuthToken) {
11967
- throw new Error('Either auth endpoint or getAuthToken function must be provided');
11968
- }
11969
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
11970
- if (!loggedInStatus) {
11971
- const authToken = await getAuthenticationToken(embedConfig);
11972
- let resp;
11973
- try {
11974
- resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
11975
- }
11976
- catch (e) {
11977
- resp = await fetchAuthService(thoughtSpotHost, username, authToken);
11978
- }
11979
- // token login issues a 302 when successful
11980
- loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
11981
- if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
11982
- // When 3rd party cookie access is blocked, this will fail because
11983
- // cookies will not be sent with the call.
11984
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
11985
- }
11986
- }
11987
- return loggedInStatus;
11988
- };
11989
- /**
11990
- * Validate embedConfig parameters required for cookielessTokenAuth
11991
- *
11992
- * @param embedConfig The embed configuration
11993
- */
11994
- const doCookielessTokenAuth = async (embedConfig) => {
11995
- const { authEndpoint, getAuthToken } = embedConfig;
11996
- if (!authEndpoint && !getAuthToken) {
11997
- throw new Error('Either auth endpoint or getAuthToken function must be provided');
11998
- }
11999
- try {
12000
- const authToken = await getAuthenticationToken(embedConfig);
12001
- if (authToken)
12002
- return true;
12003
- }
12004
- catch {
12005
- // return false if getAuthenticationToken fails
12006
- }
12007
- return false;
12008
- };
12009
- /**
12010
- * Perform basic authentication to the ThoughtSpot cluster using the cluster
12011
- * credentials.
12012
- *
12013
- * Warning: This feature is primarily intended for developer testing. It is
12014
- * strongly advised not to use this authentication method in production.
12015
- *
12016
- * @param embedConfig The embed configuration
12017
- */
12018
- const doBasicAuth = async (embedConfig) => {
12019
- const { thoughtSpotHost, username, password } = embedConfig;
12020
- const loggedIn = await isLoggedIn(thoughtSpotHost);
12021
- if (!loggedIn) {
12022
- const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
12023
- loggedInStatus = response.ok;
12024
- if (embedConfig.detectCookieAccessSlow) {
12025
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
12026
- }
12027
- }
12028
- else {
12029
- loggedInStatus = true;
12030
- }
12031
- return loggedInStatus;
12032
- };
12033
- /**
12034
- *
12035
- * @param ssoURL
12036
- * @param triggerContainer
12037
- * @param triggerText
12038
- */
12039
- async function samlPopupFlow(ssoURL, triggerContainer, triggerText) {
12040
- const openPopup = () => {
12041
- if (samlAuthWindow === null || samlAuthWindow.closed) {
12042
- samlAuthWindow = window.open(ssoURL, '_blank', 'location=no,height=570,width=520,scrollbars=yes,status=yes');
12043
- }
12044
- else {
12045
- samlAuthWindow.focus();
12046
- }
12047
- };
12048
- const containerEl = getDOMNode(triggerContainer);
12049
- if (containerEl) {
12050
- containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
12051
- const authElem = document.getElementById('ts-auth-btn');
12052
- authElem.textContent = triggerText;
12053
- authElem.addEventListener('click', openPopup, { once: true });
12054
- }
12055
- samlCompletionPromise = samlCompletionPromise
12056
- || new Promise((resolve, reject) => {
12057
- window.addEventListener('message', (e) => {
12058
- if (e.data.type === EmbedEvent.SAMLComplete) {
12059
- e.source.close();
12060
- resolve();
12061
- }
12062
- });
12063
- });
12064
- return samlCompletionPromise;
12065
- }
12066
- /**
12067
- * Perform SAML authentication
12068
- *
12069
- * @param embedConfig The embed configuration
12070
- * @param ssoEndPoint
12071
- */
12072
- const doSSOAuth = async (embedConfig, ssoEndPoint) => {
12073
- const { thoughtSpotHost } = embedConfig;
12074
- const loggedIn = await isLoggedIn(thoughtSpotHost);
12075
- if (loggedIn) {
12076
- if (isAtSSORedirectUrl()) {
12077
- removeSSORedirectUrlMarker();
12078
- }
12079
- loggedInStatus = true;
12080
- return;
12081
- }
12082
- // we have already tried authentication and it did not succeed, restore
12083
- // the current URL to the original one and invoke the callback.
12084
- if (isAtSSORedirectUrl()) {
12085
- removeSSORedirectUrlMarker();
12086
- loggedInStatus = false;
12087
- return;
12088
- }
12089
- const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
12090
- if (embedConfig.inPopup) {
12091
- await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
12092
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
12093
- return;
12094
- }
12095
- window.location.href = ssoURL;
12096
- };
12097
- const doSamlAuth = async (embedConfig) => {
12098
- const { thoughtSpotHost } = embedConfig;
12099
- // redirect for SSO, when the SSO authentication is done, this page will be
12100
- // loaded again and the same JS will execute again.
12101
- const ssoRedirectUrl = embedConfig.inPopup
12102
- ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
12103
- : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
12104
- // bring back the page to the same URL
12105
- const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
12106
- await doSSOAuth(embedConfig, ssoEndPoint);
12107
- return loggedInStatus;
12108
- };
12109
- const doOIDCAuth = async (embedConfig) => {
12110
- const { thoughtSpotHost } = embedConfig;
12111
- // redirect for SSO, when the SSO authentication is done, this page will be
12112
- // loaded again and the same JS will execute again.
12113
- const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
12114
- ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
12115
- : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
12116
- // bring back the page to the same URL
12117
- const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
12118
- await doSSOAuth(embedConfig, ssoEndPoint);
12119
- return loggedInStatus;
12120
- };
12121
- /**
12122
- * Perform authentication on the ThoughtSpot cluster
12123
- *
12124
- * @param embedConfig The embed configuration
12125
- */
12126
- const authenticate = async (embedConfig) => {
12127
- const { authType } = embedConfig;
12128
- switch (authType) {
12129
- case AuthType.SSO:
12130
- case AuthType.SAMLRedirect:
12131
- case AuthType.SAML:
12132
- return doSamlAuth(embedConfig);
12133
- case AuthType.OIDC:
12134
- case AuthType.OIDCRedirect:
12135
- return doOIDCAuth(embedConfig);
12136
- case AuthType.AuthServer:
12137
- case AuthType.TrustedAuthToken:
12138
- return doTokenAuth(embedConfig);
12139
- case AuthType.TrustedAuthTokenCookieless:
12140
- return doCookielessTokenAuth(embedConfig);
12141
- case AuthType.Basic:
12142
- return doBasicAuth(embedConfig);
12143
- default:
12144
- return Promise.resolve(true);
12145
- }
11832
+ var eventemitter3 = createCommonjsModule(function (module) {
11833
+
11834
+ var has = Object.prototype.hasOwnProperty
11835
+ , prefix = '~';
11836
+
11837
+ /**
11838
+ * Constructor to create a storage for our `EE` objects.
11839
+ * An `Events` instance is a plain object whose properties are event names.
11840
+ *
11841
+ * @constructor
11842
+ * @private
11843
+ */
11844
+ function Events() {}
11845
+
11846
+ //
11847
+ // We try to not inherit from `Object.prototype`. In some engines creating an
11848
+ // instance in this way is faster than calling `Object.create(null)` directly.
11849
+ // If `Object.create(null)` is not supported we prefix the event names with a
11850
+ // character to make sure that the built-in object properties are not
11851
+ // overridden or used as an attack vector.
11852
+ //
11853
+ if (Object.create) {
11854
+ Events.prototype = Object.create(null);
11855
+
11856
+ //
11857
+ // This hack is needed because the `__proto__` property is still inherited in
11858
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
11859
+ //
11860
+ if (!new Events().__proto__) prefix = false;
11861
+ }
11862
+
11863
+ /**
11864
+ * Representation of a single event listener.
11865
+ *
11866
+ * @param {Function} fn The listener function.
11867
+ * @param {*} context The context to invoke the listener with.
11868
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
11869
+ * @constructor
11870
+ * @private
11871
+ */
11872
+ function EE(fn, context, once) {
11873
+ this.fn = fn;
11874
+ this.context = context;
11875
+ this.once = once || false;
11876
+ }
11877
+
11878
+ /**
11879
+ * Add a listener for a given event.
11880
+ *
11881
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
11882
+ * @param {(String|Symbol)} event The event name.
11883
+ * @param {Function} fn The listener function.
11884
+ * @param {*} context The context to invoke the listener with.
11885
+ * @param {Boolean} once Specify if the listener is a one-time listener.
11886
+ * @returns {EventEmitter}
11887
+ * @private
11888
+ */
11889
+ function addListener(emitter, event, fn, context, once) {
11890
+ if (typeof fn !== 'function') {
11891
+ throw new TypeError('The listener must be a function');
11892
+ }
11893
+
11894
+ var listener = new EE(fn, context || emitter, once)
11895
+ , evt = prefix ? prefix + event : event;
11896
+
11897
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
11898
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
11899
+ else emitter._events[evt] = [emitter._events[evt], listener];
11900
+
11901
+ return emitter;
11902
+ }
11903
+
11904
+ /**
11905
+ * Clear event by name.
11906
+ *
11907
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
11908
+ * @param {(String|Symbol)} evt The Event name.
11909
+ * @private
11910
+ */
11911
+ function clearEvent(emitter, evt) {
11912
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
11913
+ else delete emitter._events[evt];
11914
+ }
11915
+
11916
+ /**
11917
+ * Minimal `EventEmitter` interface that is molded against the Node.js
11918
+ * `EventEmitter` interface.
11919
+ *
11920
+ * @constructor
11921
+ * @public
11922
+ */
11923
+ function EventEmitter() {
11924
+ this._events = new Events();
11925
+ this._eventsCount = 0;
11926
+ }
11927
+
11928
+ /**
11929
+ * Return an array listing the events for which the emitter has registered
11930
+ * listeners.
11931
+ *
11932
+ * @returns {Array}
11933
+ * @public
11934
+ */
11935
+ EventEmitter.prototype.eventNames = function eventNames() {
11936
+ var names = []
11937
+ , events
11938
+ , name;
11939
+
11940
+ if (this._eventsCount === 0) return names;
11941
+
11942
+ for (name in (events = this._events)) {
11943
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
11944
+ }
11945
+
11946
+ if (Object.getOwnPropertySymbols) {
11947
+ return names.concat(Object.getOwnPropertySymbols(events));
11948
+ }
11949
+
11950
+ return names;
11951
+ };
11952
+
11953
+ /**
11954
+ * Return the listeners registered for a given event.
11955
+ *
11956
+ * @param {(String|Symbol)} event The event name.
11957
+ * @returns {Array} The registered listeners.
11958
+ * @public
11959
+ */
11960
+ EventEmitter.prototype.listeners = function listeners(event) {
11961
+ var evt = prefix ? prefix + event : event
11962
+ , handlers = this._events[evt];
11963
+
11964
+ if (!handlers) return [];
11965
+ if (handlers.fn) return [handlers.fn];
11966
+
11967
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
11968
+ ee[i] = handlers[i].fn;
11969
+ }
11970
+
11971
+ return ee;
12146
11972
  };
12147
11973
 
12148
- /* eslint-disable camelcase */
12149
- let config = {};
12150
- const CONFIG_DEFAULTS = {
12151
- loginFailedMessage: 'Not logged in',
12152
- authTriggerText: 'Authorize',
12153
- authType: AuthType.None,
12154
- };
12155
- let authPromise;
12156
- /**
12157
- * Gets the configuration embed was initialized with.
12158
- *
12159
- * @returns {@link EmbedConfig} The configuration embed was initialized with.
12160
- * @version SDK: 1.19.0 | ThoughtSpot: *
12161
- * @group Global methods
12162
- */
12163
- const getEmbedConfig = () => config;
12164
- const getAuthPromise = () => authPromise;
12165
- /**
12166
- * Perform authentication on the ThoughtSpot app as applicable.
12167
- */
12168
- const handleAuth = () => {
12169
- authPromise = authenticate(config);
12170
- authPromise.then((isLoggedIn) => {
12171
- if (!isLoggedIn) {
12172
- notifyAuthFailure(AuthFailureType.SDK);
12173
- }
12174
- else {
12175
- notifyAuthSDKSuccess();
12176
- }
12177
- }, () => {
12178
- notifyAuthFailure(AuthFailureType.SDK);
12179
- });
12180
- return authPromise;
12181
- };
12182
- const hostUrlToFeatureUrl = {
12183
- [PrefetchFeatures.SearchEmbed]: (url) => `${url}v2/#/embed/answer`,
12184
- [PrefetchFeatures.LiveboardEmbed]: (url) => url,
12185
- [PrefetchFeatures.FullApp]: (url) => url,
12186
- [PrefetchFeatures.VizEmbed]: (url) => url,
12187
- };
12188
- /**
12189
- *
12190
- */
12191
- function disableAutoLogin() {
12192
- config.autoLogin = false;
12193
- }
12194
- let renderQueue = Promise.resolve();
12195
- /**
12196
- * Renders functions in a queue, resolves to next function only after the callback next
12197
- * is called
12198
- *
12199
- * @param fn The function being registered
12200
- */
12201
- const renderInQueue = (fn) => {
12202
- const { queueMultiRenders = false } = config;
12203
- if (queueMultiRenders) {
12204
- renderQueue = renderQueue.then(() => new Promise((res) => fn(res)));
12205
- return renderQueue;
12206
- }
12207
- // Sending an empty function to keep it consistent with the above usage.
12208
- return fn(() => { }); // eslint-disable-line @typescript-eslint/no-empty-function
11974
+ /**
11975
+ * Return the number of listeners listening to a given event.
11976
+ *
11977
+ * @param {(String|Symbol)} event The event name.
11978
+ * @returns {Number} The number of listeners.
11979
+ * @public
11980
+ */
11981
+ EventEmitter.prototype.listenerCount = function listenerCount(event) {
11982
+ var evt = prefix ? prefix + event : event
11983
+ , listeners = this._events[evt];
11984
+
11985
+ if (!listeners) return 0;
11986
+ if (listeners.fn) return 1;
11987
+ return listeners.length;
11988
+ };
11989
+
11990
+ /**
11991
+ * Calls each of the listeners registered for a given event.
11992
+ *
11993
+ * @param {(String|Symbol)} event The event name.
11994
+ * @returns {Boolean} `true` if the event had listeners, else `false`.
11995
+ * @public
11996
+ */
11997
+ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
11998
+ var evt = prefix ? prefix + event : event;
11999
+
12000
+ if (!this._events[evt]) return false;
12001
+
12002
+ var listeners = this._events[evt]
12003
+ , len = arguments.length
12004
+ , args
12005
+ , i;
12006
+
12007
+ if (listeners.fn) {
12008
+ if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
12009
+
12010
+ switch (len) {
12011
+ case 1: return listeners.fn.call(listeners.context), true;
12012
+ case 2: return listeners.fn.call(listeners.context, a1), true;
12013
+ case 3: return listeners.fn.call(listeners.context, a1, a2), true;
12014
+ case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
12015
+ case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
12016
+ case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
12017
+ }
12018
+
12019
+ for (i = 1, args = new Array(len -1); i < len; i++) {
12020
+ args[i - 1] = arguments[i];
12021
+ }
12022
+
12023
+ listeners.fn.apply(listeners.context, args);
12024
+ } else {
12025
+ var length = listeners.length
12026
+ , j;
12027
+
12028
+ for (i = 0; i < length; i++) {
12029
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
12030
+
12031
+ switch (len) {
12032
+ case 1: listeners[i].fn.call(listeners[i].context); break;
12033
+ case 2: listeners[i].fn.call(listeners[i].context, a1); break;
12034
+ case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
12035
+ case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
12036
+ default:
12037
+ if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
12038
+ args[j - 1] = arguments[j];
12039
+ }
12040
+
12041
+ listeners[i].fn.apply(listeners[i].context, args);
12042
+ }
12043
+ }
12044
+ }
12045
+
12046
+ return true;
12047
+ };
12048
+
12049
+ /**
12050
+ * Add a listener for a given event.
12051
+ *
12052
+ * @param {(String|Symbol)} event The event name.
12053
+ * @param {Function} fn The listener function.
12054
+ * @param {*} [context=this] The context to invoke the listener with.
12055
+ * @returns {EventEmitter} `this`.
12056
+ * @public
12057
+ */
12058
+ EventEmitter.prototype.on = function on(event, fn, context) {
12059
+ return addListener(this, event, fn, context, false);
12060
+ };
12061
+
12062
+ /**
12063
+ * Add a one-time listener for a given event.
12064
+ *
12065
+ * @param {(String|Symbol)} event The event name.
12066
+ * @param {Function} fn The listener function.
12067
+ * @param {*} [context=this] The context to invoke the listener with.
12068
+ * @returns {EventEmitter} `this`.
12069
+ * @public
12070
+ */
12071
+ EventEmitter.prototype.once = function once(event, fn, context) {
12072
+ return addListener(this, event, fn, context, true);
12073
+ };
12074
+
12075
+ /**
12076
+ * Remove the listeners of a given event.
12077
+ *
12078
+ * @param {(String|Symbol)} event The event name.
12079
+ * @param {Function} fn Only remove the listeners that match this function.
12080
+ * @param {*} context Only remove the listeners that have this context.
12081
+ * @param {Boolean} once Only remove one-time listeners.
12082
+ * @returns {EventEmitter} `this`.
12083
+ * @public
12084
+ */
12085
+ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
12086
+ var evt = prefix ? prefix + event : event;
12087
+
12088
+ if (!this._events[evt]) return this;
12089
+ if (!fn) {
12090
+ clearEvent(this, evt);
12091
+ return this;
12092
+ }
12093
+
12094
+ var listeners = this._events[evt];
12095
+
12096
+ if (listeners.fn) {
12097
+ if (
12098
+ listeners.fn === fn &&
12099
+ (!once || listeners.once) &&
12100
+ (!context || listeners.context === context)
12101
+ ) {
12102
+ clearEvent(this, evt);
12103
+ }
12104
+ } else {
12105
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
12106
+ if (
12107
+ listeners[i].fn !== fn ||
12108
+ (once && !listeners[i].once) ||
12109
+ (context && listeners[i].context !== context)
12110
+ ) {
12111
+ events.push(listeners[i]);
12112
+ }
12113
+ }
12114
+
12115
+ //
12116
+ // Reset the array, or remove it completely if we have no more listeners.
12117
+ //
12118
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
12119
+ else clearEvent(this, evt);
12120
+ }
12121
+
12122
+ return this;
12123
+ };
12124
+
12125
+ /**
12126
+ * Remove all listeners, or those of the specified event.
12127
+ *
12128
+ * @param {(String|Symbol)} [event] The event name.
12129
+ * @returns {EventEmitter} `this`.
12130
+ * @public
12131
+ */
12132
+ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
12133
+ var evt;
12134
+
12135
+ if (event) {
12136
+ evt = prefix ? prefix + event : event;
12137
+ if (this._events[evt]) clearEvent(this, evt);
12138
+ } else {
12139
+ this._events = new Events();
12140
+ this._eventsCount = 0;
12141
+ }
12142
+
12143
+ return this;
12209
12144
  };
12210
12145
 
12211
- const tokenizedFetch = async (input, init) => {
12212
- const req = new Request(input, init);
12213
- const embedConfig = getEmbedConfig();
12214
- if (embedConfig.authType !== AuthType.TrustedAuthTokenCookieless) {
12215
- return fetch(req);
12216
- }
12217
- const authToken = await getAuthenticationToken(embedConfig);
12218
- if (authToken) {
12219
- req.headers.append('Authorization', `Bearer ${authToken}`);
12220
- }
12221
- return fetch(req);
12146
+ //
12147
+ // Alias methods names because people roll like that.
12148
+ //
12149
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
12150
+ EventEmitter.prototype.addListener = EventEmitter.prototype.on;
12151
+
12152
+ //
12153
+ // Expose the prefix.
12154
+ //
12155
+ EventEmitter.prefixed = prefix;
12156
+
12157
+ //
12158
+ // Allow `EventEmitter` to be imported as module namespace.
12159
+ //
12160
+ EventEmitter.EventEmitter = EventEmitter;
12161
+
12162
+ //
12163
+ // Expose the module.
12164
+ //
12165
+ {
12166
+ module.exports = EventEmitter;
12167
+ }
12168
+ });
12169
+
12170
+ /**
12171
+ * This method returns `undefined`.
12172
+ *
12173
+ * @static
12174
+ * @memberOf _
12175
+ * @since 2.3.0
12176
+ * @category Util
12177
+ * @example
12178
+ *
12179
+ * _.times(2, _.noop);
12180
+ * // => [undefined, undefined]
12181
+ */
12182
+ function noop() {
12183
+ // No operation performed.
12184
+ }
12185
+
12186
+ var noop_1 = noop;
12187
+
12188
+ /** Used as references for various `Number` constants. */
12189
+ var INFINITY = 1 / 0;
12190
+
12191
+ /**
12192
+ * Creates a set object of `values`.
12193
+ *
12194
+ * @private
12195
+ * @param {Array} values The values to add to the set.
12196
+ * @returns {Object} Returns the new set.
12197
+ */
12198
+ var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) {
12199
+ return new _Set(values);
12222
12200
  };
12223
12201
 
12202
+ // eslint-disable-next-line import/no-mutable-exports
12203
+ let loggedInStatus = false;
12204
+ // eslint-disable-next-line import/no-mutable-exports
12205
+ let samlAuthWindow = null;
12206
+ // eslint-disable-next-line import/no-mutable-exports
12207
+ let samlCompletionPromise = null;
12208
+ let sessionInfo = null;
12209
+ let sessionInfoResolver = null;
12210
+ const sessionInfoPromise = new Promise((resolve) => {
12211
+ sessionInfoResolver = resolve;
12212
+ });
12213
+ let releaseVersion = '';
12214
+ const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
12224
12215
  /**
12216
+ * Enum for auth failure types. This is the parameter passed to the listner
12217
+ * of {@link AuthStatus.FAILURE}.
12225
12218
  *
12226
- * @param root0
12227
- * @param root0.query
12228
- * @param root0.variables
12229
- * @param root0.thoughtSpotHost
12230
- * @param root0.isCompositeQuery
12219
+ * @group Authentication / Init
12231
12220
  */
12232
- async function graphqlQuery({ query, variables, thoughtSpotHost, isCompositeQuery = false, }) {
12233
- const operationName = getOperationNameFromQuery(query);
12234
- try {
12235
- const response = await fetch(`${thoughtSpotHost}/prism/?op=${operationName}`, {
12236
- method: 'POST',
12237
- headers: {
12238
- 'content-type': 'application/json;charset=UTF-8',
12239
- 'x-requested-by': 'ThoughtSpot',
12240
- accept: '*/*',
12241
- 'accept-language': 'en-us',
12242
- },
12243
- body: JSON.stringify({
12244
- operationName,
12245
- query,
12246
- variables,
12247
- }),
12248
- credentials: 'include',
12249
- });
12250
- const result = await response.json();
12251
- const dataValues = Object.values(result.data);
12252
- return (isCompositeQuery) ? result.data : dataValues[0];
12253
- }
12254
- catch (error) {
12255
- return error;
12256
- }
12257
- }
12258
-
12259
- const getSourceDetailQuery = `
12260
- query GetSourceDetail($ids: [GUID!]!) {
12261
- getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {
12262
- id
12263
- name
12264
- description
12265
- authorName
12266
- authorDisplayName
12267
- isExternal
12268
- type
12269
- created
12270
- modified
12271
- columns {
12272
- id
12273
- name
12274
- author
12275
- authorDisplayName
12276
- description
12277
- dataType
12278
- type
12279
- modified
12280
- ownerName
12281
- owner
12282
- dataRecency
12283
- sources {
12284
- tableId
12285
- tableName
12286
- columnId
12287
- columnName
12288
- __typename
12289
- }
12290
- synonyms
12291
- cohortAnswerId
12292
- __typename
12293
- }
12294
- relationships
12295
- destinationRelationships
12296
- dataSourceId
12297
- __typename
12298
- }
12299
- }
12300
- `;
12301
- const sourceDetailCache = new Map();
12221
+ var AuthFailureType;
12222
+ (function (AuthFailureType) {
12223
+ AuthFailureType["SDK"] = "SDK";
12224
+ AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
12225
+ AuthFailureType["EXPIRY"] = "EXPIRY";
12226
+ AuthFailureType["OTHER"] = "OTHER";
12227
+ })(AuthFailureType || (AuthFailureType = {}));
12302
12228
  /**
12229
+ * Enum for auth status emitted by the emitter returned from {@link init}.
12303
12230
  *
12304
- * @param thoughtSpotHost
12305
- * @param sourceId
12231
+ * @group Authentication / Init
12306
12232
  */
12307
- async function getSourceDetail(thoughtSpotHost, sourceId) {
12308
- if (sourceDetailCache.get(sourceId)) {
12309
- return sourceDetailCache.get(sourceId);
12310
- }
12311
- const details = await graphqlQuery({
12312
- query: getSourceDetailQuery,
12313
- variables: {
12314
- ids: [sourceId],
12315
- },
12316
- thoughtSpotHost,
12317
- });
12318
- const souceDetails = details[0];
12319
- if (souceDetails) {
12320
- sourceDetailCache.set(sourceId, souceDetails);
12321
- }
12322
- return souceDetails;
12323
- }
12324
-
12325
- const bachSessionId = `
12326
- id {
12327
- sessionId
12328
- genNo
12329
- acSession {
12330
- sessionId
12331
- genNo
12332
- }
12333
- }
12334
- `;
12335
- const getUnaggregatedAnswerSession = `
12336
- mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
12337
- Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
12338
- ${bachSessionId}
12339
- answer {
12340
- visualizations {
12341
- ... on TableViz {
12342
- columns {
12343
- column {
12344
- id
12345
- name
12346
- referencedColumns {
12347
- guid
12348
- displayName
12349
- }
12350
- }
12351
- }
12352
- }
12353
- }
12354
- }
12355
- }
12356
- }
12357
- `;
12358
- const removeColumns = `
12359
- mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
12360
- Answer__removeColumns(
12361
- session: $session
12362
- logicalColumnIds: $logicalColumnIds
12363
- columnIds: $columnIds
12364
- ) {
12365
- ${bachSessionId}
12366
- }
12367
- }
12368
- `;
12369
- const addColumns = `
12370
- mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
12371
- Answer__addColumn(session: $session, columns: $columns) {
12372
- ${bachSessionId}
12373
- }
12374
- }
12375
- `;
12376
- const getAnswerData = `
12377
- query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
12378
- getAnswer(session: $session) {
12379
- ${bachSessionId}
12380
- answer {
12381
- id
12382
- visualizations {
12383
- id
12384
- ... on TableViz {
12385
- columns {
12386
- column {
12387
- id
12388
- name
12389
- type
12390
- aggregationType
12391
- dataType
12392
- }
12393
- }
12394
- data(deadline: $deadline, pagination: $dataPaginationParams)
12395
- }
12396
- }
12397
- }
12398
- }
12399
- }
12400
- `;
12401
-
12402
- // eslint-disable-next-line no-shadow
12403
- var OperationType;
12404
- (function (OperationType) {
12405
- OperationType["GetChartWithData"] = "GetChartWithData";
12406
- OperationType["GetTableWithHeadlineData"] = "GetTableWithHeadlineData";
12407
- })(OperationType || (OperationType = {}));
12233
+ var AuthStatus;
12234
+ (function (AuthStatus) {
12235
+ /**
12236
+ * Emits when the SDK fails to authenticate
12237
+ */
12238
+ AuthStatus["FAILURE"] = "FAILURE";
12239
+ /**
12240
+ * Emits when the SDK authenticates successfully
12241
+ */
12242
+ AuthStatus["SDK_SUCCESS"] = "SDK_SUCCESS";
12243
+ /**
12244
+ * Emits when the app sends an authentication success message
12245
+ */
12246
+ AuthStatus["SUCCESS"] = "SUCCESS";
12247
+ /**
12248
+ * Emits when a user logs out
12249
+ */
12250
+ AuthStatus["LOGOUT"] = "LOGOUT";
12251
+ /**
12252
+ * Emitted when inPopup: true in the SAMLRedirect flow.
12253
+ * And, we are waiting for popup to be triggered either programatically
12254
+ * or by the trigger button.
12255
+ *
12256
+ * @version SDK: 1.19.0
12257
+ */
12258
+ AuthStatus["WAITING_FOR_POPUP"] = "WAITING_FOR_POPUP";
12259
+ })(AuthStatus || (AuthStatus = {}));
12408
12260
  /**
12409
- * Class representing the answer service provided with the
12410
- * custom action payload. This service could be used to run
12411
- * graphql queries in the context of the answer on which the
12412
- * custom action was triggered.
12261
+ * Events which can be triggered on the emitter returned from {@link init}.
12413
12262
  *
12414
- * @example
12415
- * ```js
12416
- * embed.on(EmbedEvent.CustomAction, e => {
12417
- * const underlying = await e.answerService.getUnderlyingDataForPoint([
12418
- * 'col name 1'
12419
- * ]);
12420
- * const data = await underlying.fetchData(0, 100);
12421
- * })
12422
- * ```
12423
- * @version
12424
- * ThoughtSpot: 9.9.0.cl / SDK: 1.25.0
12425
- * @group Events
12263
+ * @group Authentication / Init
12426
12264
  */
12427
- class AnswerService {
12428
- constructor(session, answer, thoughtSpotHost, selectedPoints) {
12429
- this.session = session;
12430
- this.answer = answer;
12431
- this.thoughtSpotHost = thoughtSpotHost;
12432
- this.selectedPoints = selectedPoints;
12433
- this.session = removeTypename(session);
12265
+ var AuthEvent;
12266
+ (function (AuthEvent) {
12267
+ /**
12268
+ * Manually trigger the SSO popup. This is useful with
12269
+ * authStatus: SAMLRedirect/OIDCRedicre and inPopup: true
12270
+ */
12271
+ AuthEvent["TRIGGER_SSO_POPUP"] = "TRIGGER_SSO_POPUP";
12272
+ })(AuthEvent || (AuthEvent = {}));
12273
+ /**
12274
+ *
12275
+ */
12276
+ function notifyAuthSDKSuccess() {
12277
+ {
12278
+ console.error('SDK not initialized');
12279
+ return;
12434
12280
  }
12435
- async getSourceDetail() {
12436
- const sourceId = this.answer.sources[0].header.guid;
12437
- return getSourceDetail(this.thoughtSpotHost, sourceId);
12281
+ }
12282
+ /**
12283
+ *
12284
+ */
12285
+ function notifyAuthSuccess() {
12286
+ {
12287
+ console.error('SDK not initialized');
12288
+ return;
12438
12289
  }
12439
- async removeColumns(columnIds) {
12440
- return this.executeQuery(removeColumns, {
12441
- logicalColumnIds: columnIds,
12442
- });
12290
+ }
12291
+ /**
12292
+ *
12293
+ * @param failureType
12294
+ */
12295
+ function notifyAuthFailure(failureType) {
12296
+ {
12297
+ console.error('SDK not initialized');
12298
+ return;
12443
12299
  }
12444
- async addColumns(columnIds) {
12445
- return this.executeQuery(addColumns, {
12446
- columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
12447
- });
12300
+ }
12301
+ /**
12302
+ *
12303
+ */
12304
+ function notifyLogout() {
12305
+ {
12306
+ console.error('SDK not initialized');
12307
+ return;
12448
12308
  }
12449
- async fetchData(offset = 0, size = 1000) {
12450
- const { answer } = await this.executeQuery(getAnswerData, {
12451
- deadline: 0,
12452
- dataPaginationParams: {
12453
- isClientPaginated: true,
12454
- offset,
12455
- size,
12456
- },
12457
- });
12458
- const { columns, data } = answer.visualizations[0];
12459
- return {
12460
- columns,
12461
- data,
12462
- };
12309
+ }
12310
+ const initSession = (sessionDetails) => {
12311
+ if (sessionInfo == null) {
12312
+ sessionInfo = sessionDetails;
12313
+ initMixpanel(sessionInfo);
12314
+ sessionInfoResolver(sessionInfo);
12463
12315
  }
12464
- /**
12465
- *
12466
- * @param userLocale
12467
- * @param includeInfo Include the CSV header in the output
12468
- * @returns Response
12469
- */
12470
- async fetchCSVBlob(userLocale = 'en-us', includeInfo = false) {
12471
- const fetchUrl = this.getFetchCSVBlobUrl(userLocale, includeInfo);
12472
- return tokenizedFetch(fetchUrl, {
12473
- credentials: 'include',
12474
- });
12316
+ };
12317
+ const getSessionDetails = (sessionInfoResp) => {
12318
+ console.log('helloooo');
12319
+ const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
12320
+ const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
12321
+ const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
12322
+ ? prodMixpanelToken
12323
+ : devMixpanelToken;
12324
+ return {
12325
+ userGUID: sessionInfoResp.userGUID,
12326
+ mixpanelToken,
12327
+ isPublicUser: sessionInfoResp.configInfo.isPublicUser,
12328
+ releaseVersion: sessionInfoResp.releaseVersion,
12329
+ clusterId: sessionInfoResp.configInfo.selfClusterId,
12330
+ clusterName: sessionInfoResp.configInfo.selfClusterName,
12331
+ ...sessionInfoResp,
12332
+ };
12333
+ };
12334
+ /**
12335
+ * Check if we are logged into the ThoughtSpot cluster
12336
+ *
12337
+ * @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
12338
+ */
12339
+ async function isLoggedIn(thoughtSpotHost) {
12340
+ const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
12341
+ let response = null;
12342
+ try {
12343
+ response = await fetchSessionInfoService(authVerificationUrl);
12344
+ const sessionInfoResp = await response.json();
12345
+ const sessionDetails = getSessionDetails(sessionInfoResp);
12346
+ // Store user session details from session info
12347
+ initSession(sessionDetails);
12348
+ releaseVersion = sessionInfoResp.releaseVersion;
12475
12349
  }
12476
- getFetchCSVBlobUrl(userLocale = 'en-us', includeInfo = false) {
12477
- return `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
12350
+ catch (e) {
12351
+ return false;
12478
12352
  }
12479
- /**
12480
- * Get underlying data given a point and the output column names.
12481
- *
12482
- * @param outputColumnNames
12483
- * @param selectedPoints
12484
- * @example
12485
- * ```js
12486
- * embed.on(EmbedEvent.CustomAction, e => {
12487
- * const underlying = await e.answerService.getUnderlyingDataForPoint([
12488
- * 'col name 1' // The column should exist in the data source.
12489
- * ]);
12490
- * const data = await underlying.fetchData(0, 100);
12491
- * })
12492
- * ```
12493
- * @version
12494
- * ThoughtSpot: 9.9.0.cl / SDK: 1.25.0
12495
- */
12496
- async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
12497
- if (!selectedPoints && !this.selectedPoints) {
12498
- throw new Error('Needs to be triggered in context of a point');
12353
+ return response.status === 200;
12354
+ }
12355
+ /**
12356
+ * Return releaseVersion if available
12357
+ */
12358
+ function getReleaseVersion() {
12359
+ return releaseVersion;
12360
+ }
12361
+ /**
12362
+ * Check if we are stuck at the SSO redirect URL
12363
+ */
12364
+ function isAtSSORedirectUrl() {
12365
+ return window.location.href.indexOf(SSO_REDIRECTION_MARKER_GUID) >= 0;
12366
+ }
12367
+ /**
12368
+ * Remove the SSO redirect URL marker
12369
+ */
12370
+ function removeSSORedirectUrlMarker() {
12371
+ // Note (sunny): This will leave a # around even if it was not in the URL
12372
+ // to begin with. Trying to remove the hash by changing window.location will
12373
+ // reload the page which we don't want. We'll live with adding an
12374
+ // unnecessary hash to the parent page URL until we find any use case where
12375
+ // that creates an issue.
12376
+ window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
12377
+ }
12378
+ /**
12379
+ * Perform token based authentication
12380
+ *
12381
+ * @param embedConfig The embed configuration
12382
+ */
12383
+ const doTokenAuth = async (embedConfig) => {
12384
+ const { thoughtSpotHost, username, authEndpoint, getAuthToken, } = embedConfig;
12385
+ if (!authEndpoint && !getAuthToken) {
12386
+ throw new Error('Either auth endpoint or getAuthToken function must be provided');
12387
+ }
12388
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
12389
+ if (!loggedInStatus) {
12390
+ const authToken = await getAuthenticationToken(embedConfig);
12391
+ let resp;
12392
+ try {
12393
+ resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
12499
12394
  }
12500
- if (!selectedPoints) {
12501
- selectedPoints = getSelectedPointsForUnderlyingDataQuery(this.selectedPoints);
12395
+ catch (e) {
12396
+ resp = await fetchAuthService(thoughtSpotHost, username, authToken);
12397
+ }
12398
+ // token login issues a 302 when successful
12399
+ loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
12400
+ if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
12401
+ // When 3rd party cookie access is blocked, this will fail because
12402
+ // cookies will not be sent with the call.
12403
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
12404
+ }
12405
+ }
12406
+ return loggedInStatus;
12407
+ };
12408
+ /**
12409
+ * Validate embedConfig parameters required for cookielessTokenAuth
12410
+ *
12411
+ * @param embedConfig The embed configuration
12412
+ */
12413
+ const doCookielessTokenAuth = async (embedConfig) => {
12414
+ const { authEndpoint, getAuthToken } = embedConfig;
12415
+ if (!authEndpoint && !getAuthToken) {
12416
+ throw new Error('Either auth endpoint or getAuthToken function must be provided');
12417
+ }
12418
+ try {
12419
+ const authToken = await getAuthenticationToken(embedConfig);
12420
+ if (authToken)
12421
+ return true;
12422
+ }
12423
+ catch {
12424
+ // return false if getAuthenticationToken fails
12425
+ }
12426
+ return false;
12427
+ };
12428
+ /**
12429
+ * Perform basic authentication to the ThoughtSpot cluster using the cluster
12430
+ * credentials.
12431
+ *
12432
+ * Warning: This feature is primarily intended for developer testing. It is
12433
+ * strongly advised not to use this authentication method in production.
12434
+ *
12435
+ * @param embedConfig The embed configuration
12436
+ */
12437
+ const doBasicAuth = async (embedConfig) => {
12438
+ const { thoughtSpotHost, username, password } = embedConfig;
12439
+ const loggedIn = await isLoggedIn(thoughtSpotHost);
12440
+ if (!loggedIn) {
12441
+ const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
12442
+ loggedInStatus = response.ok;
12443
+ if (embedConfig.detectCookieAccessSlow) {
12444
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
12502
12445
  }
12503
- const sourceDetail = await this.getSourceDetail();
12504
- const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
12505
- const unAggAnswer = await graphqlQuery({
12506
- query: getUnaggregatedAnswerSession,
12507
- variables: {
12508
- session: this.session,
12509
- columns: selectedPoints,
12510
- },
12511
- thoughtSpotHost: this.thoughtSpotHost,
12512
- });
12513
- const unaggAnswerSession = new AnswerService(unAggAnswer.id, unAggAnswer.answer, this.thoughtSpotHost);
12514
- const currentColumns = new Set(unAggAnswer.answer.visualizations[0].columns
12515
- .map((c) => c.column.referencedColumns[0].guid));
12516
- const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
12517
- if (columnsToAdd.length) {
12518
- await unaggAnswerSession.addColumns(columnsToAdd);
12446
+ }
12447
+ else {
12448
+ loggedInStatus = true;
12449
+ }
12450
+ return loggedInStatus;
12451
+ };
12452
+ /**
12453
+ *
12454
+ * @param ssoURL
12455
+ * @param triggerContainer
12456
+ * @param triggerText
12457
+ */
12458
+ async function samlPopupFlow(ssoURL, triggerContainer, triggerText) {
12459
+ const openPopup = () => {
12460
+ if (samlAuthWindow === null || samlAuthWindow.closed) {
12461
+ samlAuthWindow = window.open(ssoURL, '_blank', 'location=no,height=570,width=520,scrollbars=yes,status=yes');
12519
12462
  }
12520
- const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
12521
- if (columnsToRemove.length) {
12522
- await unaggAnswerSession.removeColumns(columnsToRemove);
12463
+ else {
12464
+ samlAuthWindow.focus();
12523
12465
  }
12524
- return unaggAnswerSession;
12466
+ };
12467
+ const containerEl = getDOMNode(triggerContainer);
12468
+ if (containerEl) {
12469
+ containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
12470
+ const authElem = document.getElementById('ts-auth-btn');
12471
+ authElem.textContent = triggerText;
12472
+ authElem.addEventListener('click', openPopup, { once: true });
12525
12473
  }
12526
- async executeQuery(query, variables) {
12527
- const data = await graphqlQuery({
12528
- query,
12529
- variables: {
12530
- session: this.session,
12531
- ...variables,
12532
- },
12533
- thoughtSpotHost: this.thoughtSpotHost,
12534
- isCompositeQuery: false,
12474
+ samlCompletionPromise = samlCompletionPromise
12475
+ || new Promise((resolve, reject) => {
12476
+ window.addEventListener('message', (e) => {
12477
+ if (e.data.type === EmbedEvent.SAMLComplete) {
12478
+ e.source.close();
12479
+ resolve();
12480
+ }
12481
+ });
12535
12482
  });
12536
- this.session = deepMerge(this.session, (data === null || data === void 0 ? void 0 : data.id) || {});
12537
- return data;
12538
- }
12539
- getSession() {
12540
- return this.session;
12541
- }
12483
+ return samlCompletionPromise;
12542
12484
  }
12543
12485
  /**
12486
+ * Perform SAML authentication
12544
12487
  *
12545
- * @param sourceDetail
12546
- * @param colNames
12488
+ * @param embedConfig The embed configuration
12489
+ * @param ssoEndPoint
12547
12490
  */
12548
- function getGuidsFromColumnNames(sourceDetail, colNames) {
12549
- const cols = sourceDetail.columns.reduce((colSet, col) => {
12550
- colSet[col.name] = col;
12551
- return colSet;
12552
- }, {});
12553
- return new Set(colNames.map((colName) => {
12554
- const col = cols[colName];
12555
- return col.id;
12556
- }));
12557
- }
12491
+ const doSSOAuth = async (embedConfig, ssoEndPoint) => {
12492
+ const { thoughtSpotHost } = embedConfig;
12493
+ const loggedIn = await isLoggedIn(thoughtSpotHost);
12494
+ if (loggedIn) {
12495
+ if (isAtSSORedirectUrl()) {
12496
+ removeSSORedirectUrlMarker();
12497
+ }
12498
+ loggedInStatus = true;
12499
+ return;
12500
+ }
12501
+ // we have already tried authentication and it did not succeed, restore
12502
+ // the current URL to the original one and invoke the callback.
12503
+ if (isAtSSORedirectUrl()) {
12504
+ removeSSORedirectUrlMarker();
12505
+ loggedInStatus = false;
12506
+ return;
12507
+ }
12508
+ const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
12509
+ if (embedConfig.inPopup) {
12510
+ await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
12511
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
12512
+ return;
12513
+ }
12514
+ window.location.href = ssoURL;
12515
+ };
12516
+ const doSamlAuth = async (embedConfig) => {
12517
+ const { thoughtSpotHost } = embedConfig;
12518
+ // redirect for SSO, when the SSO authentication is done, this page will be
12519
+ // loaded again and the same JS will execute again.
12520
+ const ssoRedirectUrl = embedConfig.inPopup
12521
+ ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
12522
+ : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
12523
+ // bring back the page to the same URL
12524
+ const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
12525
+ await doSSOAuth(embedConfig, ssoEndPoint);
12526
+ return loggedInStatus;
12527
+ };
12528
+ const doOIDCAuth = async (embedConfig) => {
12529
+ const { thoughtSpotHost } = embedConfig;
12530
+ // redirect for SSO, when the SSO authentication is done, this page will be
12531
+ // loaded again and the same JS will execute again.
12532
+ const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
12533
+ ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
12534
+ : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
12535
+ // bring back the page to the same URL
12536
+ const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
12537
+ await doSSOAuth(embedConfig, ssoEndPoint);
12538
+ return loggedInStatus;
12539
+ };
12558
12540
  /**
12541
+ * Perform authentication on the ThoughtSpot cluster
12559
12542
  *
12560
- * @param selectedPoints
12543
+ * @param embedConfig The embed configuration
12561
12544
  */
12562
- function getSelectedPointsForUnderlyingDataQuery(selectedPoints) {
12563
- const underlyingDataPoint = [];
12564
- /**
12565
- *
12566
- * @param colVal
12567
- */
12568
- function addPointFromColVal(colVal) {
12569
- var _a;
12570
- const dataType = colVal.column.dataType;
12571
- const id = colVal.column.id;
12572
- let dataValue;
12573
- if (dataType === 'DATE') {
12574
- if (Number.isFinite(colVal.value)) {
12575
- dataValue = [{
12576
- epochRange: {
12577
- startEpoch: colVal.value,
12578
- },
12579
- }];
12580
- // Case for custom calendar.
12581
- }
12582
- else if ((_a = colVal.value) === null || _a === void 0 ? void 0 : _a.v) {
12583
- dataValue = [{
12584
- epochRange: {
12585
- startEpoch: colVal.value.v.s,
12586
- endEpoch: colVal.value.v.e,
12587
- },
12588
- }];
12589
- }
12545
+ const authenticate = async (embedConfig) => {
12546
+ const { authType } = embedConfig;
12547
+ switch (authType) {
12548
+ case AuthType.SSO:
12549
+ case AuthType.SAMLRedirect:
12550
+ case AuthType.SAML:
12551
+ return doSamlAuth(embedConfig);
12552
+ case AuthType.OIDC:
12553
+ case AuthType.OIDCRedirect:
12554
+ return doOIDCAuth(embedConfig);
12555
+ case AuthType.AuthServer:
12556
+ case AuthType.TrustedAuthToken:
12557
+ return doTokenAuth(embedConfig);
12558
+ case AuthType.TrustedAuthTokenCookieless:
12559
+ return doCookielessTokenAuth(embedConfig);
12560
+ case AuthType.Basic:
12561
+ return doBasicAuth(embedConfig);
12562
+ default:
12563
+ return Promise.resolve(true);
12564
+ }
12565
+ };
12566
+
12567
+ /* eslint-disable camelcase */
12568
+ const CONFIG_DEFAULTS = {
12569
+ loginFailedMessage: 'Not logged in',
12570
+ authTriggerText: 'Authorize',
12571
+ authType: AuthType.None,
12572
+ };
12573
+ let authPromise;
12574
+ const getAuthPromise = () => authPromise;
12575
+ /**
12576
+ * Perform authentication on the ThoughtSpot app as applicable.
12577
+ */
12578
+ const handleAuth = () => {
12579
+ authPromise = authenticate(getEmbedConfig());
12580
+ authPromise.then((isLoggedIn) => {
12581
+ if (!isLoggedIn) {
12582
+ notifyAuthFailure(AuthFailureType.SDK);
12590
12583
  }
12591
12584
  else {
12592
- dataValue = [{ value: colVal.value }];
12585
+ notifyAuthSDKSuccess();
12593
12586
  }
12594
- underlyingDataPoint.push({
12595
- columnId: colVal.column.id,
12596
- dataValue,
12597
- });
12598
- }
12599
- selectedPoints.forEach((p) => {
12600
- p.selectedAttributes.forEach(addPointFromColVal);
12587
+ }, () => {
12588
+ notifyAuthFailure(AuthFailureType.SDK);
12601
12589
  });
12602
- return underlyingDataPoint;
12603
- }
12590
+ return authPromise;
12591
+ };
12592
+ const hostUrlToFeatureUrl = {
12593
+ [PrefetchFeatures.SearchEmbed]: (url) => `${url}v2/#/embed/answer`,
12594
+ [PrefetchFeatures.LiveboardEmbed]: (url) => url,
12595
+ [PrefetchFeatures.FullApp]: (url) => url,
12596
+ [PrefetchFeatures.VizEmbed]: (url) => url,
12597
+ };
12598
+ /**
12599
+ *
12600
+ */
12601
+ function disableAutoLogin() {
12602
+ getEmbedConfig().autoLogin = false;
12603
+ }
12604
+ let renderQueue = Promise.resolve();
12605
+ /**
12606
+ * Renders functions in a queue, resolves to next function only after the callback next
12607
+ * is called
12608
+ *
12609
+ * @param fn The function being registered
12610
+ */
12611
+ const renderInQueue = (fn) => {
12612
+ const { queueMultiRenders = false } = getEmbedConfig();
12613
+ if (queueMultiRenders) {
12614
+ renderQueue = renderQueue.then(() => new Promise((res) => fn(res)));
12615
+ return renderQueue;
12616
+ }
12617
+ // Sending an empty function to keep it consistent with the above usage.
12618
+ return fn(() => { }); // eslint-disable-line @typescript-eslint/no-empty-function
12619
+ };
12604
12620
 
12605
12621
  /**
12606
12622
  *
@@ -12758,7 +12774,7 @@ function processTrigger(iFrame, messageType, thoughtSpotHost, data) {
12758
12774
  });
12759
12775
  }
12760
12776
 
12761
- var name="@thoughtspot/visual-embed-sdk";var version="1.26.0-token-cache.0";var description="ThoughtSpot Embed SDK";var module="lib/src/index.js";var main="dist/tsembed.js";var types="lib/src/index.d.ts";var files=["dist/**","lib/**","src/**","cjs/**"];var exports={".":{"import":"./lib/src/index.js",require:"./cjs/src/index.js",types:"./lib/src/index.d.ts"},"./react":{"import":"./lib/src/react/all-types-export.js",require:"./cjs/src/react/all-types-export.js",types:"./lib/src/react/all-types-export.d.ts"},"./lib/src/react":{"import":"./lib/src/react/all-types-export.js",require:"./cjs/src/react/all-types-export.js",types:"./lib/src/react/all-types-export.d.ts"}};var typesVersions={"*":{react:["./lib/src/react/all-types-export.d.ts"]}};var scripts={lint:"eslint 'src/**'","lint:fix":"eslint 'src/**/*.*' --fix",tsc:"tsc -p . --incremental false; tsc -p . --incremental false --module commonjs --outDir cjs",start:"gatsby develop","build:gatsby":"npm run clean:gatsby && gatsby build --prefix-paths","build:gatsby:noprefix":"npm run clean:gatsby && gatsby build","serve:gatsby":"gatsby serve","clean:gatsby":"gatsby clean","build-and-publish":"npm run build:gatsby && npm run publish","bundle-dts-file":"dts-bundle --name @thoughtspot/visual-embed-sdk --out visual-embed-sdk.d.ts --main lib/src/index.d.ts","bundle-dts":"dts-bundle --name ../../dist/visual-embed-sdk --main lib/src/index.d.ts --outputAsModuleFolder=true","bundle-dts-react":"dts-bundle --name ../../../dist/visual-embed-sdk-react --main lib/src/react/index.d.ts --outputAsModuleFolder=true","bundle-dts-react-full":"dts-bundle --name ../../../dist/visual-embed-sdk-react-full --main lib/src/react/all-types-export.d.ts --outputAsModuleFolder=true",build:"rollup -c",watch:"rollup -cw","docs-cmd":"node scripts/gatsby-commands.js",docgen:"typedoc --tsconfig tsconfig.json --theme typedoc-theme","test-sdk":"jest -c jest.config.sdk.js --runInBand","test-docs":"jest -c jest.config.docs.js",test:"npm run test-sdk && npm run test-docs",posttest:"cat ./coverage/sdk/lcov.info | coveralls","is-publish-allowed":"node scripts/is-publish-allowed.js",prepublishOnly:"npm run is-publish-allowed && npm run test && npm run tsc && npm run bundle-dts-file && npm run bundle-dts && npm run bundle-dts-react && npm run bundle-dts-react-full && npm run build","check-size":"npm run build && size-limit","publish-dev":"npm publish --tag dev","publish-prod":"npm publish --tag latest"};var peerDependencies={react:"> 16.8.0","react-dom":"> 16.8.0"};var dependencies={algoliasearch:"^4.10.5",classnames:"^2.3.1",dompurify:"^2.3.4","eslint-plugin-comment-length":"^0.9.2","eslint-plugin-jsdoc":"^40.1.0",eventemitter3:"^4.0.7","gatsby-plugin-vercel":"^1.0.3","html-react-parser":"^1.4.12",lodash:"^4.17.21","mixpanel-browser":"^2.45.0","ts-deepmerge":"^6.0.2",tslib:"^2.5.3","use-deep-compare-effect":"^1.8.1"};var devDependencies={"@mdx-js/mdx":"^1.6.22","@mdx-js/react":"^1.6.22","@react-icons/all-files":"^4.1.0","@rollup/plugin-commonjs":"^18.0.0","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^11.2.1","@rollup/plugin-replace":"^5.0.2","@size-limit/preset-big-lib":"^8.2.6","@testing-library/dom":"^7.31.0","@testing-library/jest-dom":"^5.14.1","@testing-library/react":"^11.2.7","@testing-library/user-event":"^13.1.8","@types/jest":"^22.2.3","@types/mixpanel-browser":"^2.35.6","@types/react-test-renderer":"^17.0.1","@typescript-eslint/eslint-plugin":"^4.6.0","@typescript-eslint/parser":"^4.6.0",asciidoctor:"^2.2.1","babel-jest":"^26.6.3","babel-preset-gatsby":"^1.10.0","command-line-args":"^5.1.1",coveralls:"^3.1.0","current-git-branch":"^1.1.0","dts-bundle":"^0.7.3",eslint:"^7.12.1","eslint-config-airbnb-base":"^14.2.0","eslint-config-prettier":"^6.15.0","eslint-import-resolver-typescript":"^2.3.0","eslint-plugin-import":"^2.22.1","eslint-plugin-prettier":"^3.1.4","eslint-plugin-react-hooks":"^4.2.0","fs-extra":"^10.0.0",gatsby:"3.13.1","gatsby-plugin-algolia":"^0.22.2","gatsby-plugin-catch-links":"^3.1.0","gatsby-plugin-env-variables":"^2.1.0","gatsby-plugin-intl":"^0.3.3","gatsby-plugin-manifest":"^3.2.0","gatsby-plugin-output":"^0.1.3","gatsby-plugin-sass":"6.7.0","gatsby-plugin-sitemap":"^4.10.0","gatsby-source-filesystem":"3.1.0","gatsby-transformer-asciidoc":"2.1.0","gatsby-transformer-rehype":"2.0.0","gh-pages":"^3.1.0","highlight.js":"^10.6.0","html-to-text":"^8.0.0","identity-obj-proxy":"^3.0.0","istanbul-merge":"^1.1.1",jest:"^26.6.3","jest-fetch-mock":"^3.0.3",jsdom:"^17.0.0","node-sass":"^8.0.0",prettier:"2.1.2",react:"^16.14.0","react-dom":"^16.14.0","react-resizable":"^1.11.0","react-resize-detector":"^6.6.0","react-test-renderer":"^17.0.2","react-use-flexsearch":"^0.1.1",rollup:"2.30.0","rollup-plugin-typescript2":"0.27.3","ts-jest":"^26.5.5","ts-loader":"8.0.4",typedoc:"0.21.6","typedoc-plugin-toc-group":"thoughtspot/typedoc-plugin-toc-group",typescript:"^4.9.4","url-search-params-polyfill":"^8.1.0",util:"^0.12.4"};var author="ThoughtSpot";var email="support@thoughtspot.com";var license="ThoughtSpot Development Tools End User License Agreement";var directories={lib:"lib"};var repository={type:"git",url:"git+https://github.com/thoughtspot/visual-embed-sdk.git"};var publishConfig={registry:"https://registry.npmjs.org"};var keywords=["thoughtspot","everywhere","embed","sdk","analytics"];var bugs={url:"https://github.com/thoughtspot/visual-embed-sdk/issues"};var homepage="https://github.com/thoughtspot/visual-embed-sdk#readme";var globals={window:{}};var pkgInfo = {name:name,version:version,description:description,module:module,main:main,types:types,files:files,exports:exports,typesVersions:typesVersions,"size-limit":[{path:"dist/tsembed.js",limit:"43 kB"}],scripts:scripts,peerDependencies:peerDependencies,dependencies:dependencies,devDependencies:devDependencies,author:author,email:email,license:license,directories:directories,repository:repository,publishConfig:publishConfig,keywords:keywords,bugs:bugs,homepage:homepage,globals:globals};
12777
+ var name="@thoughtspot/visual-embed-sdk";var version="1.26.0-token-cache.2";var description="ThoughtSpot Embed SDK";var module="lib/src/index.js";var main="dist/tsembed.js";var types="lib/src/index.d.ts";var files=["dist/**","lib/**","src/**","cjs/**"];var exports={".":{"import":"./lib/src/index.js",require:"./cjs/src/index.js",types:"./lib/src/index.d.ts"},"./react":{"import":"./lib/src/react/all-types-export.js",require:"./cjs/src/react/all-types-export.js",types:"./lib/src/react/all-types-export.d.ts"},"./lib/src/react":{"import":"./lib/src/react/all-types-export.js",require:"./cjs/src/react/all-types-export.js",types:"./lib/src/react/all-types-export.d.ts"}};var typesVersions={"*":{react:["./lib/src/react/all-types-export.d.ts"]}};var scripts={lint:"eslint 'src/**'","lint:fix":"eslint 'src/**/*.*' --fix",tsc:"tsc -p . --incremental false; tsc -p . --incremental false --module commonjs --outDir cjs",start:"gatsby develop","build:gatsby":"npm run clean:gatsby && gatsby build --prefix-paths","build:gatsby:noprefix":"npm run clean:gatsby && gatsby build","serve:gatsby":"gatsby serve","clean:gatsby":"gatsby clean","build-and-publish":"npm run build:gatsby && npm run publish","bundle-dts-file":"dts-bundle --name @thoughtspot/visual-embed-sdk --out visual-embed-sdk.d.ts --main lib/src/index.d.ts","bundle-dts":"dts-bundle --name ../../dist/visual-embed-sdk --main lib/src/index.d.ts --outputAsModuleFolder=true","bundle-dts-react":"dts-bundle --name ../../../dist/visual-embed-sdk-react --main lib/src/react/index.d.ts --outputAsModuleFolder=true","bundle-dts-react-full":"dts-bundle --name ../../../dist/visual-embed-sdk-react-full --main lib/src/react/all-types-export.d.ts --outputAsModuleFolder=true",build:"rollup -c",watch:"rollup -cw","docs-cmd":"node scripts/gatsby-commands.js",docgen:"typedoc --tsconfig tsconfig.json --theme typedoc-theme","test-sdk":"jest -c jest.config.sdk.js --runInBand","test-docs":"jest -c jest.config.docs.js",test:"npm run test-sdk && npm run test-docs",posttest:"cat ./coverage/sdk/lcov.info | coveralls","is-publish-allowed":"node scripts/is-publish-allowed.js",prepublishOnly:"npm run is-publish-allowed && npm run test && npm run tsc && npm run bundle-dts-file && npm run bundle-dts && npm run bundle-dts-react && npm run bundle-dts-react-full && npm run build","check-size":"npm run build && size-limit","publish-dev":"npm publish --tag dev","publish-prod":"npm publish --tag latest"};var peerDependencies={react:"> 16.8.0","react-dom":"> 16.8.0"};var dependencies={algoliasearch:"^4.10.5",classnames:"^2.3.1",dompurify:"^2.3.4","eslint-plugin-comment-length":"^0.9.2","eslint-plugin-jsdoc":"^40.1.0",eventemitter3:"^4.0.7","gatsby-plugin-vercel":"^1.0.3","html-react-parser":"^1.4.12",lodash:"^4.17.21","mixpanel-browser":"^2.45.0","ts-deepmerge":"^6.0.2",tslib:"^2.5.3","use-deep-compare-effect":"^1.8.1"};var devDependencies={"@mdx-js/mdx":"^1.6.22","@mdx-js/react":"^1.6.22","@react-icons/all-files":"^4.1.0","@rollup/plugin-commonjs":"^18.0.0","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^11.2.1","@rollup/plugin-replace":"^5.0.2","@size-limit/preset-big-lib":"^8.2.6","@testing-library/dom":"^7.31.0","@testing-library/jest-dom":"^5.14.1","@testing-library/react":"^11.2.7","@testing-library/user-event":"^13.1.8","@types/jest":"^22.2.3","@types/mixpanel-browser":"^2.35.6","@types/react-test-renderer":"^17.0.1","@typescript-eslint/eslint-plugin":"^4.6.0","@typescript-eslint/parser":"^4.6.0",asciidoctor:"^2.2.1","babel-jest":"^26.6.3","babel-preset-gatsby":"^1.10.0","command-line-args":"^5.1.1",coveralls:"^3.1.0","current-git-branch":"^1.1.0","dts-bundle":"^0.7.3",eslint:"^7.12.1","eslint-config-airbnb-base":"^14.2.0","eslint-config-prettier":"^6.15.0","eslint-import-resolver-typescript":"^2.3.0","eslint-plugin-import":"^2.22.1","eslint-plugin-prettier":"^3.1.4","eslint-plugin-react-hooks":"^4.2.0","fs-extra":"^10.0.0",gatsby:"3.13.1","gatsby-plugin-algolia":"^0.22.2","gatsby-plugin-catch-links":"^3.1.0","gatsby-plugin-env-variables":"^2.1.0","gatsby-plugin-intl":"^0.3.3","gatsby-plugin-manifest":"^3.2.0","gatsby-plugin-output":"^0.1.3","gatsby-plugin-sass":"6.7.0","gatsby-plugin-sitemap":"^4.10.0","gatsby-source-filesystem":"3.1.0","gatsby-transformer-asciidoc":"2.1.0","gatsby-transformer-rehype":"2.0.0","gh-pages":"^3.1.0","highlight.js":"^10.6.0","html-to-text":"^8.0.0","identity-obj-proxy":"^3.0.0","istanbul-merge":"^1.1.1",jest:"^26.6.3","jest-fetch-mock":"^3.0.3",jsdom:"^17.0.0","node-sass":"^8.0.0",prettier:"2.1.2",react:"^16.14.0","react-dom":"^16.14.0","react-resizable":"^1.11.0","react-resize-detector":"^6.6.0","react-test-renderer":"^17.0.2","react-use-flexsearch":"^0.1.1",rollup:"2.30.0","rollup-plugin-typescript2":"0.27.3","ts-jest":"^26.5.5","ts-loader":"8.0.4",typedoc:"0.21.6","typedoc-plugin-toc-group":"thoughtspot/typedoc-plugin-toc-group",typescript:"^4.9.4","url-search-params-polyfill":"^8.1.0",util:"^0.12.4"};var author="ThoughtSpot";var email="support@thoughtspot.com";var license="ThoughtSpot Development Tools End User License Agreement";var directories={lib:"lib"};var repository={type:"git",url:"git+https://github.com/thoughtspot/visual-embed-sdk.git"};var publishConfig={registry:"https://registry.npmjs.org"};var keywords=["thoughtspot","everywhere","embed","sdk","analytics"];var bugs={url:"https://github.com/thoughtspot/visual-embed-sdk/issues"};var homepage="https://github.com/thoughtspot/visual-embed-sdk#readme";var globals={window:{}};var pkgInfo = {name:name,version:version,description:description,module:module,main:main,types:types,files:files,exports:exports,typesVersions:typesVersions,"size-limit":[{path:"dist/tsembed.js",limit:"44 kB"}],scripts:scripts,peerDependencies:peerDependencies,dependencies:dependencies,devDependencies:devDependencies,author:author,email:email,license:license,directories:directories,repository:repository,publishConfig:publishConfig,keywords:keywords,bugs:bugs,homepage:homepage,globals:globals};
12762
12778
 
12763
12779
  /**
12764
12780
  * Copyright (c) 2022