@thoughtspot/visual-embed-sdk 1.27.8 → 1.28.0-alpha.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 (142) hide show
  1. package/README.md +1 -1
  2. package/cjs/package.json +1 -1
  3. package/cjs/src/auth.d.ts.map +1 -1
  4. package/cjs/src/auth.js +2 -2
  5. package/cjs/src/auth.js.map +1 -1
  6. package/cjs/src/embed/base.d.ts +1 -1
  7. package/cjs/src/embed/base.d.ts.map +1 -1
  8. package/cjs/src/embed/base.js +5 -5
  9. package/cjs/src/embed/base.js.map +1 -1
  10. package/cjs/src/embed/base.spec.js +1 -1
  11. package/cjs/src/embed/base.spec.js.map +1 -1
  12. package/cjs/src/embed/sage.d.ts +5 -5
  13. package/cjs/src/embed/sage.d.ts.map +1 -1
  14. package/cjs/src/embed/sage.js +1 -16
  15. package/cjs/src/embed/sage.js.map +1 -1
  16. package/cjs/src/embed/sage.spec.js +11 -11
  17. package/cjs/src/embed/sage.spec.js.map +1 -1
  18. package/cjs/src/embed/search.d.ts +1 -5
  19. package/cjs/src/embed/search.d.ts.map +1 -1
  20. package/cjs/src/embed/search.js +4 -4
  21. package/cjs/src/embed/search.js.map +1 -1
  22. package/cjs/src/embed/ts-embed.d.ts +1 -1
  23. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  24. package/cjs/src/embed/ts-embed.js +6 -6
  25. package/cjs/src/embed/ts-embed.js.map +1 -1
  26. package/cjs/src/embed/ts-embed.spec.js +8 -14
  27. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  28. package/cjs/src/index.d.ts +4 -3
  29. package/cjs/src/index.d.ts.map +1 -1
  30. package/cjs/src/index.js +4 -1
  31. package/cjs/src/index.js.map +1 -1
  32. package/cjs/src/mixpanel-service.d.ts +1 -0
  33. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  34. package/cjs/src/mixpanel-service.js +1 -0
  35. package/cjs/src/mixpanel-service.js.map +1 -1
  36. package/cjs/src/react/all-types-export.d.ts +1 -1
  37. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  38. package/cjs/src/react/all-types-export.js +2 -1
  39. package/cjs/src/react/all-types-export.js.map +1 -1
  40. package/cjs/src/react/index.spec.js +0 -12
  41. package/cjs/src/react/index.spec.js.map +1 -1
  42. package/cjs/src/types.d.ts +43 -13
  43. package/cjs/src/types.d.ts.map +1 -1
  44. package/cjs/src/types.js +37 -10
  45. package/cjs/src/types.js.map +1 -1
  46. package/cjs/src/utils/graphql/answerService/answerService.d.ts +56 -2
  47. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  48. package/cjs/src/utils/graphql/answerService/answerService.js +55 -0
  49. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  50. package/dist/src/auth.d.ts.map +1 -1
  51. package/dist/src/embed/base.d.ts +1 -1
  52. package/dist/src/embed/base.d.ts.map +1 -1
  53. package/dist/src/embed/sage.d.ts +5 -5
  54. package/dist/src/embed/sage.d.ts.map +1 -1
  55. package/dist/src/embed/search.d.ts +1 -5
  56. package/dist/src/embed/search.d.ts.map +1 -1
  57. package/dist/src/embed/ts-embed.d.ts +1 -1
  58. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  59. package/dist/src/index.d.ts +4 -3
  60. package/dist/src/index.d.ts.map +1 -1
  61. package/dist/src/mixpanel-service.d.ts +1 -0
  62. package/dist/src/mixpanel-service.d.ts.map +1 -1
  63. package/dist/src/react/all-types-export.d.ts +1 -1
  64. package/dist/src/react/all-types-export.d.ts.map +1 -1
  65. package/dist/src/types.d.ts +43 -13
  66. package/dist/src/types.d.ts.map +1 -1
  67. package/dist/src/utils/graphql/answerService/answerService.d.ts +56 -2
  68. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  69. package/dist/tsembed-react.es.js +2800 -2732
  70. package/dist/tsembed-react.js +1525 -1457
  71. package/dist/tsembed.es.js +1768 -1700
  72. package/dist/tsembed.js +1674 -1604
  73. package/dist/visual-embed-sdk-react-full.d.ts +135 -24
  74. package/dist/visual-embed-sdk-react.d.ts +135 -24
  75. package/dist/visual-embed-sdk.d.ts +135 -24
  76. package/lib/package.json +1 -1
  77. package/lib/src/auth.d.ts.map +1 -1
  78. package/lib/src/auth.js +3 -3
  79. package/lib/src/auth.js.map +1 -1
  80. package/lib/src/embed/base.d.ts +1 -1
  81. package/lib/src/embed/base.d.ts.map +1 -1
  82. package/lib/src/embed/base.js +5 -5
  83. package/lib/src/embed/base.js.map +1 -1
  84. package/lib/src/embed/base.spec.js +2 -2
  85. package/lib/src/embed/base.spec.js.map +1 -1
  86. package/lib/src/embed/sage.d.ts +5 -5
  87. package/lib/src/embed/sage.d.ts.map +1 -1
  88. package/lib/src/embed/sage.js +1 -16
  89. package/lib/src/embed/sage.js.map +1 -1
  90. package/lib/src/embed/sage.spec.js +11 -11
  91. package/lib/src/embed/sage.spec.js.map +1 -1
  92. package/lib/src/embed/search.d.ts +1 -5
  93. package/lib/src/embed/search.d.ts.map +1 -1
  94. package/lib/src/embed/search.js +5 -5
  95. package/lib/src/embed/search.js.map +1 -1
  96. package/lib/src/embed/ts-embed.d.ts +1 -1
  97. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  98. package/lib/src/embed/ts-embed.js +9 -9
  99. package/lib/src/embed/ts-embed.js.map +1 -1
  100. package/lib/src/embed/ts-embed.spec.js +8 -14
  101. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  102. package/lib/src/index.d.ts +4 -3
  103. package/lib/src/index.d.ts.map +1 -1
  104. package/lib/src/index.js +2 -3
  105. package/lib/src/index.js.map +1 -1
  106. package/lib/src/mixpanel-service.d.ts +1 -0
  107. package/lib/src/mixpanel-service.d.ts.map +1 -1
  108. package/lib/src/mixpanel-service.js +1 -0
  109. package/lib/src/mixpanel-service.js.map +1 -1
  110. package/lib/src/react/all-types-export.d.ts +1 -1
  111. package/lib/src/react/all-types-export.d.ts.map +1 -1
  112. package/lib/src/react/all-types-export.js +1 -1
  113. package/lib/src/react/all-types-export.js.map +1 -1
  114. package/lib/src/react/index.spec.js +0 -12
  115. package/lib/src/react/index.spec.js.map +1 -1
  116. package/lib/src/types.d.ts +43 -13
  117. package/lib/src/types.d.ts.map +1 -1
  118. package/lib/src/types.js +37 -10
  119. package/lib/src/types.js.map +1 -1
  120. package/lib/src/utils/authService/authService.spec.js +1 -1
  121. package/lib/src/utils/authService/authService.spec.js.map +1 -1
  122. package/lib/src/utils/graphql/answerService/answerService.d.ts +56 -2
  123. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  124. package/lib/src/utils/graphql/answerService/answerService.js +55 -0
  125. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  126. package/lib/src/visual-embed-sdk.d.ts +144 -30
  127. package/package.json +1 -1
  128. package/src/auth.ts +6 -6
  129. package/src/embed/base.spec.ts +3 -3
  130. package/src/embed/base.ts +12 -12
  131. package/src/embed/sage.spec.ts +11 -11
  132. package/src/embed/sage.ts +4 -17
  133. package/src/embed/search.ts +6 -11
  134. package/src/embed/ts-embed.spec.ts +19 -25
  135. package/src/embed/ts-embed.ts +37 -34
  136. package/src/index.ts +10 -1
  137. package/src/mixpanel-service.ts +1 -0
  138. package/src/react/all-types-export.ts +1 -0
  139. package/src/react/index.spec.tsx +0 -29
  140. package/src/types.ts +53 -24
  141. package/src/utils/authService/authService.spec.ts +4 -4
  142. package/src/utils/graphql/answerService/answerService.ts +56 -1
@@ -183,6 +183,7 @@ var AuthType;
183
183
  * .then((response) => response.json())
184
184
  * .then((data) => data.token);
185
185
  * }
186
+ * });
186
187
  * ```
187
188
  */
188
189
  AuthType["TrustedAuthToken"] = "AuthServer";
@@ -478,7 +479,8 @@ var EmbedEvent;
478
479
  * A custom action has been triggered.
479
480
  *
480
481
  * @returns actionId - ID of the custom action
481
- * @returns data - Response payload with the Answer or Liveboard data
482
+ * @returns payload {@link CustomActionPayload} - Response payload with the
483
+ * Answer or Liveboard data
482
484
  * @example
483
485
  * ```js
484
486
  * appEmbed.on(EmbedEvent.customAction, payload => {
@@ -498,7 +500,7 @@ var EmbedEvent;
498
500
  * @example
499
501
  * ```js
500
502
  * livebaordEmbed.on(EmbedEvent.VizPointDoubleClick, payload => {
501
- * console.log('VizPointDoubleClick', payload)
503
+ * console.log('VizPointDoubleClick', payload);
502
504
  * })
503
505
  * ```
504
506
  */
@@ -524,15 +526,40 @@ var EmbedEvent;
524
526
  */
525
527
  EmbedEvent["VizPointClick"] = "vizPointClick";
526
528
  /**
527
- * An error has occurred.
529
+ * An error has occurred. This event is fired for the following error types:
530
+ *
531
+ * `API` - API call failure error.
532
+ *
533
+ * `FULLSCREEN` - Error when presenting a Liveboard or visualization in full screen mode.
534
+ *
535
+ * `SINGLE_VALUE_FILTER` - Error due to multiple values in the single value filter.
528
536
  *
537
+ * `NON_EXIST_FILTER` - Error due to a non-existent filter.
538
+ *
539
+ * `INVALID_DATE_VALUE` - Invalid date value error.
540
+ *
541
+ * `INVALID_OPERATOR` - Use of invalid operator during filter application.
542
+ *
543
+ * For more information, see [Developer Documentation](https://developers.thoughtspot.com/docs/events-app-integration#errorType)
529
544
  * @returns error - An error object or message
530
545
  * @example
531
546
  * ```js
532
- * SearchEmbed.on(EmbedEvent.Error, showErrorMsg)
533
- * //show error messaage
534
- * function showErrorMsg() {
535
- * document.getElementById("error");
547
+ * // API error
548
+ * SearchEmbed.on(EmbedEvent.Error, (error) => {
549
+ * console.log(error);
550
+ * // { type: "Error", data: { errorType: "API", error: { message: '...', error: '...' } } }
551
+ * });
552
+ * ```
553
+ * @example
554
+ * ```js
555
+ * // Fullscreen error (Errors during presenting of a liveboard)
556
+ * LiveboardEmbed.on(EmbedEvent.Error, (error) => {
557
+ * console.log(error);
558
+ * // { type: "Error", data: { errorType: "FULLSCREEN", error: {
559
+ * // message: "Fullscreen API is not enabled",
560
+ * // stack: "..."
561
+ * // } }}
562
+ * })
536
563
  * ```
537
564
  */
538
565
  EmbedEvent["Error"] = "Error";
@@ -1242,7 +1269,7 @@ var EmbedEvent;
1242
1269
  /**
1243
1270
  * Emitted when a LB/viz is renamed
1244
1271
  *
1245
- * @version SDK : 1.28.0 | ThoughtSpot: 9.11.0.cl
1272
+ * @version SDK : 1.28.0 | ThoughtSpot: 9.10.5.cl
1246
1273
  */
1247
1274
  EmbedEvent["Rename"] = "rename";
1248
1275
  })(EmbedEvent || (EmbedEvent = {}));
@@ -1917,7 +1944,7 @@ var HostEvent;
1917
1944
  */
1918
1945
  HostEvent["ResetSearch"] = "resetSearch";
1919
1946
  /**
1920
- * @hidden
1947
+ *
1921
1948
  * Get the currents visible and runtime filters applied on a Liveboard
1922
1949
  * @example
1923
1950
  * liveboardEmbed.trigger(HostEvent.GetFilters)
@@ -1925,7 +1952,7 @@ var HostEvent;
1925
1952
  */
1926
1953
  HostEvent["GetFilters"] = "getFilters";
1927
1954
  /**
1928
- * @hidden
1955
+ *
1929
1956
  * Update the visible filters on the Liveboard.
1930
1957
  * @param - filter: filter object containing column name and filter operation and values
1931
1958
  * @example
@@ -5671,8 +5698,6 @@ function isEqual(value, other) {
5671
5698
 
5672
5699
  var isEqual_1 = isEqual;
5673
5700
 
5674
- var name="@thoughtspot/visual-embed-sdk";var version="1.27.8";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":"^46.9.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};
5675
-
5676
5701
  const EndPoints = {
5677
5702
  AUTH_VERIFICATION: '/callosum/v1/session/info',
5678
5703
  SAML_LOGIN_TEMPLATE: (targetUrl) => `/callosum/v1/saml/login?targetURLPath=${targetUrl}`,
@@ -5835,549 +5860,1093 @@ const resetCachedAuthToken = () => {
5835
5860
  cachedAuthToken = null;
5836
5861
  };
5837
5862
 
5838
- var Config = {
5839
- DEBUG: false,
5840
- LIB_VERSION: '2.45.0'
5863
+ let config = {};
5864
+ /**
5865
+ * Gets the configuration embed was initialized with.
5866
+ *
5867
+ * @returns {@link EmbedConfig} The configuration embed was initialized with.
5868
+ * @version SDK: 1.19.0 | ThoughtSpot: *
5869
+ * @group Global methods
5870
+ */
5871
+ const getEmbedConfig = () => config;
5872
+ /**
5873
+ * Sets the configuration embed was initialized with.
5874
+ * And returns the new configuration.
5875
+ *
5876
+ * @param newConfig The configuration to set.
5877
+ * @version SDK: 1.27.0 | ThoughtSpot: *
5878
+ * @group Global methods
5879
+ */
5880
+ const setEmbedConfig = (newConfig) => {
5881
+ config = newConfig;
5882
+ return newConfig;
5841
5883
  };
5842
5884
 
5843
- // since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
5844
- var window$1;
5845
- if (typeof(window) === 'undefined') {
5846
- var loc = {
5847
- hostname: ''
5848
- };
5849
- window$1 = {
5850
- navigator: { userAgent: '' },
5851
- document: {
5852
- location: loc,
5853
- referrer: ''
5854
- },
5855
- screen: { width: 0, height: 0 },
5856
- location: loc
5857
- };
5858
- } else {
5859
- window$1 = window;
5860
- }
5861
-
5862
- /*
5863
- * Saved references to long variable names, so that closure compiler can
5864
- * minimize file size.
5865
- */
5866
-
5867
- var ArrayProto = Array.prototype;
5868
- var FuncProto = Function.prototype;
5869
- var ObjProto = Object.prototype;
5870
- var slice = ArrayProto.slice;
5871
- var toString = ObjProto.toString;
5872
- var hasOwnProperty$9 = ObjProto.hasOwnProperty;
5873
- var windowConsole = window$1.console;
5874
- var navigator = window$1.navigator;
5875
- var document$1 = window$1.document;
5876
- var windowOpera = window$1.opera;
5877
- var screen = window$1.screen;
5878
- var userAgent = navigator.userAgent;
5879
- var nativeBind = FuncProto.bind;
5880
- var nativeForEach = ArrayProto.forEach;
5881
- var nativeIndexOf = ArrayProto.indexOf;
5882
- var nativeMap = ArrayProto.map;
5883
- var nativeIsArray = Array.isArray;
5884
- var breaker = {};
5885
- var _ = {
5886
- trim: function(str) {
5887
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
5888
- return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
5889
- }
5885
+ const tokenizedFetch = async (input, init) => {
5886
+ const embedConfig = getEmbedConfig();
5887
+ if (embedConfig.authType !== AuthType.TrustedAuthTokenCookieless) {
5888
+ return fetch(input, init);
5889
+ }
5890
+ const req = new Request(input, init);
5891
+ const authToken = await getAuthenticationToken(embedConfig);
5892
+ if (authToken) {
5893
+ req.headers.append('Authorization', `Bearer ${authToken}`);
5894
+ }
5895
+ return fetch(req);
5890
5896
  };
5891
5897
 
5892
- // Console override
5893
- var console$1 = {
5894
- /** @type {function(...*)} */
5895
- log: function() {
5896
- if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
5897
- try {
5898
- windowConsole.log.apply(windowConsole, arguments);
5899
- } catch (err) {
5900
- _.each(arguments, function(arg) {
5901
- windowConsole.log(arg);
5902
- });
5903
- }
5904
- }
5905
- },
5906
- /** @type {function(...*)} */
5907
- warn: function() {
5908
- if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
5909
- var args = ['Mixpanel warning:'].concat(_.toArray(arguments));
5910
- try {
5911
- windowConsole.warn.apply(windowConsole, args);
5912
- } catch (err) {
5913
- _.each(args, function(arg) {
5914
- windowConsole.warn(arg);
5915
- });
5916
- }
5917
- }
5918
- },
5919
- /** @type {function(...*)} */
5920
- error: function() {
5921
- if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
5922
- var args = ['Mixpanel error:'].concat(_.toArray(arguments));
5923
- try {
5924
- windowConsole.error.apply(windowConsole, args);
5925
- } catch (err) {
5926
- _.each(args, function(arg) {
5927
- windowConsole.error(arg);
5928
- });
5898
+ /**
5899
+ *
5900
+ * @param root0
5901
+ * @param root0.query
5902
+ * @param root0.variables
5903
+ * @param root0.thoughtSpotHost
5904
+ * @param root0.isCompositeQuery
5905
+ */
5906
+ async function graphqlQuery({ query, variables, thoughtSpotHost, isCompositeQuery = false, }) {
5907
+ const operationName = getOperationNameFromQuery(query);
5908
+ try {
5909
+ const response = await fetch(`${thoughtSpotHost}/prism/?op=${operationName}`, {
5910
+ method: 'POST',
5911
+ headers: {
5912
+ 'content-type': 'application/json;charset=UTF-8',
5913
+ 'x-requested-by': 'ThoughtSpot',
5914
+ accept: '*/*',
5915
+ 'accept-language': 'en-us',
5916
+ },
5917
+ body: JSON.stringify({
5918
+ operationName,
5919
+ query,
5920
+ variables,
5921
+ }),
5922
+ credentials: 'include',
5923
+ });
5924
+ const result = await response.json();
5925
+ const dataValues = Object.values(result.data);
5926
+ return (isCompositeQuery) ? result.data : dataValues[0];
5927
+ }
5928
+ catch (error) {
5929
+ return error;
5930
+ }
5931
+ }
5932
+
5933
+ const getSourceDetailQuery = `
5934
+ query GetSourceDetail($ids: [GUID!]!) {
5935
+ getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {
5936
+ id
5937
+ name
5938
+ description
5939
+ authorName
5940
+ authorDisplayName
5941
+ isExternal
5942
+ type
5943
+ created
5944
+ modified
5945
+ columns {
5946
+ id
5947
+ name
5948
+ author
5949
+ authorDisplayName
5950
+ description
5951
+ dataType
5952
+ type
5953
+ modified
5954
+ ownerName
5955
+ owner
5956
+ dataRecency
5957
+ sources {
5958
+ tableId
5959
+ tableName
5960
+ columnId
5961
+ columnName
5962
+ __typename
5929
5963
  }
5964
+ synonyms
5965
+ cohortAnswerId
5966
+ __typename
5930
5967
  }
5931
- },
5932
- /** @type {function(...*)} */
5933
- critical: function() {
5934
- if (!_.isUndefined(windowConsole) && windowConsole) {
5935
- var args = ['Mixpanel error:'].concat(_.toArray(arguments));
5936
- try {
5937
- windowConsole.error.apply(windowConsole, args);
5938
- } catch (err) {
5939
- _.each(args, function(arg) {
5940
- windowConsole.error(arg);
5941
- });
5942
- }
5968
+ relationships
5969
+ destinationRelationships
5970
+ dataSourceId
5971
+ __typename
5943
5972
  }
5944
- }
5945
- };
5973
+ }
5974
+ `;
5975
+ const sourceDetailCache = new Map();
5976
+ /**
5977
+ *
5978
+ * @param thoughtSpotHost
5979
+ * @param sourceId
5980
+ */
5981
+ async function getSourceDetail(thoughtSpotHost, sourceId) {
5982
+ if (sourceDetailCache.get(sourceId)) {
5983
+ return sourceDetailCache.get(sourceId);
5984
+ }
5985
+ const details = await graphqlQuery({
5986
+ query: getSourceDetailQuery,
5987
+ variables: {
5988
+ ids: [sourceId],
5989
+ },
5990
+ thoughtSpotHost,
5991
+ });
5992
+ const souceDetails = details[0];
5993
+ if (souceDetails) {
5994
+ sourceDetailCache.set(sourceId, souceDetails);
5995
+ }
5996
+ return souceDetails;
5997
+ }
5946
5998
 
5947
- var log_func_with_prefix = function(func, prefix) {
5948
- return function() {
5949
- arguments[0] = '[' + prefix + '] ' + arguments[0];
5950
- return func.apply(console$1, arguments);
5951
- };
5952
- };
5953
- var console_with_prefix = function(prefix) {
5954
- return {
5955
- log: log_func_with_prefix(console$1.log, prefix),
5956
- error: log_func_with_prefix(console$1.error, prefix),
5957
- critical: log_func_with_prefix(console$1.critical, prefix)
5958
- };
5959
- };
5960
-
5961
-
5962
- // UNDERSCORE
5963
- // Embed part of the Underscore Library
5964
- _.bind = function(func, context) {
5965
- var args, bound;
5966
- if (nativeBind && func.bind === nativeBind) {
5967
- return nativeBind.apply(func, slice.call(arguments, 1));
5968
- }
5969
- if (!_.isFunction(func)) {
5970
- throw new TypeError();
5971
- }
5972
- args = slice.call(arguments, 2);
5973
- bound = function() {
5974
- if (!(this instanceof bound)) {
5975
- return func.apply(context, args.concat(slice.call(arguments)));
5976
- }
5977
- var ctor = {};
5978
- ctor.prototype = func.prototype;
5979
- var self = new ctor();
5980
- ctor.prototype = null;
5981
- var result = func.apply(self, args.concat(slice.call(arguments)));
5982
- if (Object(result) === result) {
5983
- return result;
5984
- }
5985
- return self;
5986
- };
5987
- return bound;
5988
- };
5989
-
5990
- /**
5991
- * @param {*=} obj
5992
- * @param {function(...*)=} iterator
5993
- * @param {Object=} context
5994
- */
5995
- _.each = function(obj, iterator, context) {
5996
- if (obj === null || obj === undefined) {
5997
- return;
5999
+ const bachSessionId = `
6000
+ id {
6001
+ sessionId
6002
+ genNo
6003
+ acSession {
6004
+ sessionId
6005
+ genNo
5998
6006
  }
5999
- if (nativeForEach && obj.forEach === nativeForEach) {
6000
- obj.forEach(iterator, context);
6001
- } else if (obj.length === +obj.length) {
6002
- for (var i = 0, l = obj.length; i < l; i++) {
6003
- if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) {
6004
- return;
6005
- }
6006
- }
6007
- } else {
6008
- for (var key in obj) {
6009
- if (hasOwnProperty$9.call(obj, key)) {
6010
- if (iterator.call(context, obj[key], key, obj) === breaker) {
6011
- return;
6007
+ }
6008
+ `;
6009
+ const getUnaggregatedAnswerSession = `
6010
+ mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
6011
+ Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
6012
+ ${bachSessionId}
6013
+ answer {
6014
+ visualizations {
6015
+ ... on TableViz {
6016
+ columns {
6017
+ column {
6018
+ id
6019
+ name
6020
+ referencedColumns {
6021
+ guid
6022
+ displayName
6023
+ }
6024
+ }
6025
+ }
6012
6026
  }
6013
6027
  }
6014
6028
  }
6015
6029
  }
6016
- };
6017
-
6018
- _.extend = function(obj) {
6019
- _.each(slice.call(arguments, 1), function(source) {
6020
- for (var prop in source) {
6021
- if (source[prop] !== void 0) {
6022
- obj[prop] = source[prop];
6023
- }
6024
- }
6025
- });
6026
- return obj;
6027
- };
6028
-
6029
- _.isArray = nativeIsArray || function(obj) {
6030
- return toString.call(obj) === '[object Array]';
6031
- };
6032
-
6033
- // from a comment on http://dbj.org/dbj/?p=286
6034
- // fails on only one very rare and deliberate custom object:
6035
- // var bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
6036
- _.isFunction = function(f) {
6037
- try {
6038
- return /^\s*\bfunction\b/.test(f);
6039
- } catch (x) {
6040
- return false;
6041
- }
6042
- };
6043
-
6044
- _.isArguments = function(obj) {
6045
- return !!(obj && hasOwnProperty$9.call(obj, 'callee'));
6046
- };
6047
-
6048
- _.toArray = function(iterable) {
6049
- if (!iterable) {
6050
- return [];
6051
- }
6052
- if (iterable.toArray) {
6053
- return iterable.toArray();
6054
- }
6055
- if (_.isArray(iterable)) {
6056
- return slice.call(iterable);
6057
- }
6058
- if (_.isArguments(iterable)) {
6059
- return slice.call(iterable);
6060
- }
6061
- return _.values(iterable);
6062
- };
6063
-
6064
- _.map = function(arr, callback, context) {
6065
- if (nativeMap && arr.map === nativeMap) {
6066
- return arr.map(callback, context);
6067
- } else {
6068
- var results = [];
6069
- _.each(arr, function(item) {
6070
- results.push(callback.call(context, item));
6071
- });
6072
- return results;
6073
- }
6074
- };
6075
-
6076
- _.keys = function(obj) {
6077
- var results = [];
6078
- if (obj === null) {
6079
- return results;
6080
- }
6081
- _.each(obj, function(value, key) {
6082
- results[results.length] = key;
6083
- });
6084
- return results;
6085
- };
6086
-
6087
- _.values = function(obj) {
6088
- var results = [];
6089
- if (obj === null) {
6090
- return results;
6091
- }
6092
- _.each(obj, function(value) {
6093
- results[results.length] = value;
6094
- });
6095
- return results;
6096
- };
6097
-
6098
- _.include = function(obj, target) {
6099
- var found = false;
6100
- if (obj === null) {
6101
- return found;
6102
- }
6103
- if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
6104
- return obj.indexOf(target) != -1;
6030
+ }
6031
+ `;
6032
+ const removeColumns = `
6033
+ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
6034
+ Answer__removeColumns(
6035
+ session: $session
6036
+ logicalColumnIds: $logicalColumnIds
6037
+ columnIds: $columnIds
6038
+ ) {
6039
+ ${bachSessionId}
6105
6040
  }
6106
- _.each(obj, function(value) {
6107
- if (found || (found = (value === target))) {
6108
- return breaker;
6041
+ }
6042
+ `;
6043
+ const addColumns = `
6044
+ mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
6045
+ Answer__addColumn(session: $session, columns: $columns) {
6046
+ ${bachSessionId}
6109
6047
  }
6110
- });
6111
- return found;
6112
- };
6113
-
6114
- _.includes = function(str, needle) {
6115
- return str.indexOf(needle) !== -1;
6116
- };
6117
-
6118
- // Underscore Addons
6119
- _.inherit = function(subclass, superclass) {
6120
- subclass.prototype = new superclass();
6121
- subclass.prototype.constructor = subclass;
6122
- subclass.superclass = superclass.prototype;
6123
- return subclass;
6124
- };
6125
-
6126
- _.isObject = function(obj) {
6127
- return (obj === Object(obj) && !_.isArray(obj));
6128
- };
6129
-
6130
- _.isEmptyObject = function(obj) {
6131
- if (_.isObject(obj)) {
6132
- for (var key in obj) {
6133
- if (hasOwnProperty$9.call(obj, key)) {
6134
- return false;
6048
+ }
6049
+ `;
6050
+ const getAnswerData = `
6051
+ query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
6052
+ getAnswer(session: $session) {
6053
+ ${bachSessionId}
6054
+ answer {
6055
+ id
6056
+ visualizations {
6057
+ id
6058
+ ... on TableViz {
6059
+ columns {
6060
+ column {
6061
+ id
6062
+ name
6063
+ type
6064
+ aggregationType
6065
+ dataType
6066
+ }
6067
+ }
6068
+ data(deadline: $deadline, pagination: $dataPaginationParams)
6069
+ }
6070
+ }
6135
6071
  }
6136
6072
  }
6137
- return true;
6138
6073
  }
6139
- return false;
6140
- };
6141
-
6142
- _.isUndefined = function(obj) {
6143
- return obj === void 0;
6144
- };
6145
-
6146
- _.isString = function(obj) {
6147
- return toString.call(obj) == '[object String]';
6148
- };
6149
-
6150
- _.isDate = function(obj) {
6151
- return toString.call(obj) == '[object Date]';
6152
- };
6153
-
6154
- _.isNumber = function(obj) {
6155
- return toString.call(obj) == '[object Number]';
6156
- };
6074
+ `;
6157
6075
 
6158
- _.isElement = function(obj) {
6159
- return !!(obj && obj.nodeType === 1);
6160
- };
6161
-
6162
- _.encodeDates = function(obj) {
6163
- _.each(obj, function(v, k) {
6164
- if (_.isDate(v)) {
6165
- obj[k] = _.formatDate(v);
6166
- } else if (_.isObject(v)) {
6167
- obj[k] = _.encodeDates(v); // recurse
6168
- }
6169
- });
6170
- return obj;
6171
- };
6076
+ // eslint-disable-next-line no-shadow
6077
+ var OperationType;
6078
+ (function (OperationType) {
6079
+ OperationType["GetChartWithData"] = "GetChartWithData";
6080
+ OperationType["GetTableWithHeadlineData"] = "GetTableWithHeadlineData";
6081
+ })(OperationType || (OperationType = {}));
6082
+ /**
6083
+ * Class representing the answer service provided with the
6084
+ * custom action payload. This service could be used to run
6085
+ * graphql queries in the context of the answer on which the
6086
+ * custom action was triggered.
6087
+ *
6088
+ * @example
6089
+ * ```js
6090
+ * embed.on(EmbedEvent.CustomAction, e => {
6091
+ * const underlying = await e.answerService.getUnderlyingDataForPoint([
6092
+ * 'col name 1'
6093
+ * ]);
6094
+ * const data = await underlying.fetchData(0, 100);
6095
+ * })
6096
+ * ```
6097
+ * @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
6098
+ * @group Events
6099
+ */
6100
+ class AnswerService {
6101
+ /**
6102
+ * Should not need to be called directly.
6103
+ *
6104
+ * @param session
6105
+ * @param answer
6106
+ * @param thoughtSpotHost
6107
+ * @param selectedPoints
6108
+ */
6109
+ constructor(session, answer, thoughtSpotHost, selectedPoints) {
6110
+ this.session = session;
6111
+ this.answer = answer;
6112
+ this.thoughtSpotHost = thoughtSpotHost;
6113
+ this.selectedPoints = selectedPoints;
6114
+ this.session = removeTypename(session);
6115
+ }
6116
+ /**
6117
+ * Get the details about the source used in the answer.
6118
+ * This can be used to get the list of all columns in the data source for example.
6119
+ */
6120
+ async getSourceDetail() {
6121
+ const sourceId = this.answer.sources[0].header.guid;
6122
+ return getSourceDetail(this.thoughtSpotHost, sourceId);
6123
+ }
6124
+ /**
6125
+ * Remove columnIds and return updated answer session.
6126
+ *
6127
+ * @param columnIds
6128
+ * @returns
6129
+ */
6130
+ async removeColumns(columnIds) {
6131
+ return this.executeQuery(removeColumns, {
6132
+ logicalColumnIds: columnIds,
6133
+ });
6134
+ }
6135
+ /**
6136
+ * Add columnIds and return updated answer session.
6137
+ *
6138
+ * @param columnIds
6139
+ * @returns
6140
+ */
6141
+ async addColumns(columnIds) {
6142
+ return this.executeQuery(addColumns, {
6143
+ columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
6144
+ });
6145
+ }
6146
+ /**
6147
+ * Fetch data from the answer.
6148
+ *
6149
+ * @param offset
6150
+ * @param size
6151
+ * @returns
6152
+ */
6153
+ async fetchData(offset = 0, size = 1000) {
6154
+ const { answer } = await this.executeQuery(getAnswerData, {
6155
+ deadline: 0,
6156
+ dataPaginationParams: {
6157
+ isClientPaginated: true,
6158
+ offset,
6159
+ size,
6160
+ },
6161
+ });
6162
+ const { columns, data } = answer.visualizations.find((viz) => !!viz.data) || {};
6163
+ return {
6164
+ columns,
6165
+ data,
6166
+ };
6167
+ }
6168
+ /**
6169
+ * Fetch the data for the answer as a CSV blob. This might be
6170
+ * quicker for larger data.
6171
+ *
6172
+ * @param userLocale
6173
+ * @param includeInfo Include the CSV header in the output
6174
+ * @returns Response
6175
+ */
6176
+ async fetchCSVBlob(userLocale = 'en-us', includeInfo = false) {
6177
+ const fetchUrl = this.getFetchCSVBlobUrl(userLocale, includeInfo);
6178
+ return tokenizedFetch(fetchUrl, {
6179
+ credentials: 'include',
6180
+ });
6181
+ }
6182
+ /**
6183
+ * Just get the internal URL for this answer's data
6184
+ * as a CSV blob.
6185
+ *
6186
+ * @param userLocale
6187
+ * @param includeInfo
6188
+ * @returns
6189
+ */
6190
+ getFetchCSVBlobUrl(userLocale = 'en-us', includeInfo = false) {
6191
+ return `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
6192
+ }
6193
+ /**
6194
+ * Get underlying data given a point and the output column names.
6195
+ * In case of a context menu action, the selectedPoints are
6196
+ * automatically passed.
6197
+ *
6198
+ * @param outputColumnNames
6199
+ * @param selectedPoints
6200
+ * @example
6201
+ * ```js
6202
+ * embed.on(EmbedEvent.CustomAction, e => {
6203
+ * const underlying = await e.answerService.getUnderlyingDataForPoint([
6204
+ * 'col name 1' // The column should exist in the data source.
6205
+ * ]);
6206
+ * const data = await underlying.fetchData(0, 100);
6207
+ * })
6208
+ * ```
6209
+ * @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
6210
+ */
6211
+ async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
6212
+ if (!selectedPoints && !this.selectedPoints) {
6213
+ throw new Error('Needs to be triggered in context of a point');
6214
+ }
6215
+ if (!selectedPoints) {
6216
+ selectedPoints = getSelectedPointsForUnderlyingDataQuery(this.selectedPoints);
6217
+ }
6218
+ const sourceDetail = await this.getSourceDetail();
6219
+ const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
6220
+ const unAggAnswer = await graphqlQuery({
6221
+ query: getUnaggregatedAnswerSession,
6222
+ variables: {
6223
+ session: this.session,
6224
+ columns: selectedPoints,
6225
+ },
6226
+ thoughtSpotHost: this.thoughtSpotHost,
6227
+ });
6228
+ const unaggAnswerSession = new AnswerService(unAggAnswer.id, unAggAnswer.answer, this.thoughtSpotHost);
6229
+ const currentColumns = new Set(unAggAnswer.answer.visualizations[0].columns
6230
+ .map((c) => c.column.referencedColumns[0].guid));
6231
+ const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
6232
+ if (columnsToAdd.length) {
6233
+ await unaggAnswerSession.addColumns(columnsToAdd);
6234
+ }
6235
+ const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
6236
+ if (columnsToRemove.length) {
6237
+ await unaggAnswerSession.removeColumns(columnsToRemove);
6238
+ }
6239
+ return unaggAnswerSession;
6240
+ }
6241
+ /**
6242
+ * Execute a custom graphql query in the context of the answer.
6243
+ *
6244
+ * @param query graphql query
6245
+ * @param variables graphql variables
6246
+ * @returns
6247
+ */
6248
+ async executeQuery(query, variables) {
6249
+ const data = await graphqlQuery({
6250
+ query,
6251
+ variables: {
6252
+ session: this.session,
6253
+ ...variables,
6254
+ },
6255
+ thoughtSpotHost: this.thoughtSpotHost,
6256
+ isCompositeQuery: false,
6257
+ });
6258
+ this.session = deepMerge(this.session, (data === null || data === void 0 ? void 0 : data.id) || {});
6259
+ return data;
6260
+ }
6261
+ /**
6262
+ * Get the internal session details for the answer.
6263
+ *
6264
+ * @returns
6265
+ */
6266
+ getSession() {
6267
+ return this.session;
6268
+ }
6269
+ }
6270
+ /**
6271
+ *
6272
+ * @param sourceDetail
6273
+ * @param colNames
6274
+ */
6275
+ function getGuidsFromColumnNames(sourceDetail, colNames) {
6276
+ const cols = sourceDetail.columns.reduce((colSet, col) => {
6277
+ colSet[col.name] = col;
6278
+ return colSet;
6279
+ }, {});
6280
+ return new Set(colNames.map((colName) => {
6281
+ const col = cols[colName];
6282
+ return col.id;
6283
+ }));
6284
+ }
6285
+ /**
6286
+ *
6287
+ * @param selectedPoints
6288
+ */
6289
+ function getSelectedPointsForUnderlyingDataQuery(selectedPoints) {
6290
+ const underlyingDataPoint = [];
6291
+ /**
6292
+ *
6293
+ * @param colVal
6294
+ */
6295
+ function addPointFromColVal(colVal) {
6296
+ var _a;
6297
+ const dataType = colVal.column.dataType;
6298
+ const id = colVal.column.id;
6299
+ let dataValue;
6300
+ if (dataType === 'DATE') {
6301
+ if (Number.isFinite(colVal.value)) {
6302
+ dataValue = [{
6303
+ epochRange: {
6304
+ startEpoch: colVal.value,
6305
+ },
6306
+ }];
6307
+ // Case for custom calendar.
6308
+ }
6309
+ else if ((_a = colVal.value) === null || _a === void 0 ? void 0 : _a.v) {
6310
+ dataValue = [{
6311
+ epochRange: {
6312
+ startEpoch: colVal.value.v.s,
6313
+ endEpoch: colVal.value.v.e,
6314
+ },
6315
+ }];
6316
+ }
6317
+ }
6318
+ else {
6319
+ dataValue = [{ value: colVal.value }];
6320
+ }
6321
+ underlyingDataPoint.push({
6322
+ columnId: colVal.column.id,
6323
+ dataValue,
6324
+ });
6325
+ }
6326
+ selectedPoints.forEach((p) => {
6327
+ p.selectedAttributes.forEach(addPointFromColVal);
6328
+ });
6329
+ return underlyingDataPoint;
6330
+ }
6172
6331
 
6173
- _.timestamp = function() {
6174
- Date.now = Date.now || function() {
6175
- return +new Date;
6176
- };
6177
- return Date.now();
6332
+ const ERROR_MESSAGE = {
6333
+ INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
6334
+ LIVEBOARD_VIZ_ID_VALIDATION: 'Please provide either liveboardId or pinboardId',
6335
+ TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
6336
+ SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
6337
+ SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
6178
6338
  };
6179
6339
 
6180
- _.formatDate = function(d) {
6181
- // YYYY-MM-DDTHH:MM:SS in UTC
6182
- function pad(n) {
6183
- return n < 10 ? '0' + n : n;
6184
- }
6185
- return d.getUTCFullYear() + '-' +
6186
- pad(d.getUTCMonth() + 1) + '-' +
6187
- pad(d.getUTCDate()) + 'T' +
6188
- pad(d.getUTCHours()) + ':' +
6189
- pad(d.getUTCMinutes()) + ':' +
6190
- pad(d.getUTCSeconds());
6191
- };
6340
+ /**
6341
+ * Copyright (c) 2023
6342
+ *
6343
+ * Utilities related to reading configuration objects
6344
+ *
6345
+ * @summary Config-related utils
6346
+ * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
6347
+ */
6348
+ const urlRegex = new RegExp([
6349
+ '(^(https?:)//)?',
6350
+ '(([^:/?#]*)(?::([0-9]+))?)',
6351
+ '(/{0,1}[^?#]*)',
6352
+ '(\\?[^#]*|)',
6353
+ '(#.*|)$', // hash
6354
+ ].join(''));
6355
+ /**
6356
+ * Parse and construct the ThoughtSpot hostname or IP address
6357
+ * from the embed configuration object.
6358
+ *
6359
+ * @param config
6360
+ */
6361
+ const getThoughtSpotHost = (config) => {
6362
+ if (!config.thoughtSpotHost) {
6363
+ throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
6364
+ }
6365
+ const urlParts = config.thoughtSpotHost.match(urlRegex);
6366
+ if (!urlParts) {
6367
+ throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
6368
+ }
6369
+ const protocol = urlParts[2] || window.location.protocol;
6370
+ const host = urlParts[3];
6371
+ let path = urlParts[6];
6372
+ // Lose the trailing / if any
6373
+ if (path.charAt(path.length - 1) === '/') {
6374
+ path = path.substring(0, path.length - 1);
6375
+ }
6376
+ // const urlParams = urlParts[7];
6377
+ // const hash = urlParts[8];
6378
+ return `${protocol}//${host}${path}`;
6379
+ };
6380
+ const getV2BasePath = (config) => {
6381
+ if (config.basepath) {
6382
+ return config.basepath;
6383
+ }
6384
+ const tsHost = getThoughtSpotHost(config);
6385
+ // This is to handle when e2e's. Search is run on pods for
6386
+ // comp-blink-test-pipeline with baseUrl=https://localhost:8443.
6387
+ // This is to handle when the developer is developing in their local
6388
+ // environment.
6389
+ if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
6390
+ return '';
6391
+ }
6392
+ return 'v2';
6393
+ };
6394
+ /**
6395
+ * It is a good idea to keep URLs under 2000 chars.
6396
+ * If this is ever breached, since we pass view configuration through
6397
+ * URL params, we would like to log a warning.
6398
+ * Reference: https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
6399
+ */
6400
+ const URL_MAX_LENGTH = 2000;
6401
+ /**
6402
+ * The default CSS dimensions of the embedded app
6403
+ */
6404
+ const DEFAULT_EMBED_WIDTH = '100%';
6405
+ const DEFAULT_EMBED_HEIGHT = '100%';
6192
6406
 
6193
- _.strip_empty_properties = function(p) {
6194
- var ret = {};
6195
- _.each(p, function(v, k) {
6196
- if (_.isString(v) && v.length > 0) {
6197
- ret[k] = v;
6198
- }
6199
- });
6200
- return ret;
6407
+ var Config = {
6408
+ DEBUG: false,
6409
+ LIB_VERSION: '2.45.0'
6201
6410
  };
6202
6411
 
6412
+ // since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
6413
+ var window$1;
6414
+ if (typeof(window) === 'undefined') {
6415
+ var loc = {
6416
+ hostname: ''
6417
+ };
6418
+ window$1 = {
6419
+ navigator: { userAgent: '' },
6420
+ document: {
6421
+ location: loc,
6422
+ referrer: ''
6423
+ },
6424
+ screen: { width: 0, height: 0 },
6425
+ location: loc
6426
+ };
6427
+ } else {
6428
+ window$1 = window;
6429
+ }
6430
+
6203
6431
  /*
6204
- * this function returns a copy of object after truncating it. If
6205
- * passed an Array or Object it will iterate through obj and
6206
- * truncate all the values recursively.
6432
+ * Saved references to long variable names, so that closure compiler can
6433
+ * minimize file size.
6207
6434
  */
6208
- _.truncate = function(obj, length) {
6209
- var ret;
6210
6435
 
6211
- if (typeof(obj) === 'string') {
6212
- ret = obj.slice(0, length);
6213
- } else if (_.isArray(obj)) {
6214
- ret = [];
6215
- _.each(obj, function(val) {
6216
- ret.push(_.truncate(val, length));
6217
- });
6218
- } else if (_.isObject(obj)) {
6219
- ret = {};
6220
- _.each(obj, function(val, key) {
6221
- ret[key] = _.truncate(val, length);
6222
- });
6223
- } else {
6224
- ret = obj;
6436
+ var ArrayProto = Array.prototype;
6437
+ var FuncProto = Function.prototype;
6438
+ var ObjProto = Object.prototype;
6439
+ var slice = ArrayProto.slice;
6440
+ var toString = ObjProto.toString;
6441
+ var hasOwnProperty$9 = ObjProto.hasOwnProperty;
6442
+ var windowConsole = window$1.console;
6443
+ var navigator = window$1.navigator;
6444
+ var document$1 = window$1.document;
6445
+ var windowOpera = window$1.opera;
6446
+ var screen = window$1.screen;
6447
+ var userAgent = navigator.userAgent;
6448
+ var nativeBind = FuncProto.bind;
6449
+ var nativeForEach = ArrayProto.forEach;
6450
+ var nativeIndexOf = ArrayProto.indexOf;
6451
+ var nativeMap = ArrayProto.map;
6452
+ var nativeIsArray = Array.isArray;
6453
+ var breaker = {};
6454
+ var _ = {
6455
+ trim: function(str) {
6456
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
6457
+ return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
6225
6458
  }
6226
-
6227
- return ret;
6228
6459
  };
6229
6460
 
6230
- _.JSONEncode = (function() {
6231
- return function(mixed_val) {
6232
- var value = mixed_val;
6233
- var quote = function(string) {
6234
- var escapable = /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; // eslint-disable-line no-control-regex
6235
- var meta = { // table of character substitutions
6236
- '\b': '\\b',
6237
- '\t': '\\t',
6238
- '\n': '\\n',
6239
- '\f': '\\f',
6240
- '\r': '\\r',
6241
- '"': '\\"',
6242
- '\\': '\\\\'
6243
- };
6461
+ // Console override
6462
+ var console$1 = {
6463
+ /** @type {function(...*)} */
6464
+ log: function() {
6465
+ if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
6466
+ try {
6467
+ windowConsole.log.apply(windowConsole, arguments);
6468
+ } catch (err) {
6469
+ _.each(arguments, function(arg) {
6470
+ windowConsole.log(arg);
6471
+ });
6472
+ }
6473
+ }
6474
+ },
6475
+ /** @type {function(...*)} */
6476
+ warn: function() {
6477
+ if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
6478
+ var args = ['Mixpanel warning:'].concat(_.toArray(arguments));
6479
+ try {
6480
+ windowConsole.warn.apply(windowConsole, args);
6481
+ } catch (err) {
6482
+ _.each(args, function(arg) {
6483
+ windowConsole.warn(arg);
6484
+ });
6485
+ }
6486
+ }
6487
+ },
6488
+ /** @type {function(...*)} */
6489
+ error: function() {
6490
+ if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
6491
+ var args = ['Mixpanel error:'].concat(_.toArray(arguments));
6492
+ try {
6493
+ windowConsole.error.apply(windowConsole, args);
6494
+ } catch (err) {
6495
+ _.each(args, function(arg) {
6496
+ windowConsole.error(arg);
6497
+ });
6498
+ }
6499
+ }
6500
+ },
6501
+ /** @type {function(...*)} */
6502
+ critical: function() {
6503
+ if (!_.isUndefined(windowConsole) && windowConsole) {
6504
+ var args = ['Mixpanel error:'].concat(_.toArray(arguments));
6505
+ try {
6506
+ windowConsole.error.apply(windowConsole, args);
6507
+ } catch (err) {
6508
+ _.each(args, function(arg) {
6509
+ windowConsole.error(arg);
6510
+ });
6511
+ }
6512
+ }
6513
+ }
6514
+ };
6244
6515
 
6245
- escapable.lastIndex = 0;
6246
- return escapable.test(string) ?
6247
- '"' + string.replace(escapable, function(a) {
6248
- var c = meta[a];
6249
- return typeof c === 'string' ? c :
6250
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
6251
- }) + '"' :
6252
- '"' + string + '"';
6253
- };
6516
+ var log_func_with_prefix = function(func, prefix) {
6517
+ return function() {
6518
+ arguments[0] = '[' + prefix + '] ' + arguments[0];
6519
+ return func.apply(console$1, arguments);
6520
+ };
6521
+ };
6522
+ var console_with_prefix = function(prefix) {
6523
+ return {
6524
+ log: log_func_with_prefix(console$1.log, prefix),
6525
+ error: log_func_with_prefix(console$1.error, prefix),
6526
+ critical: log_func_with_prefix(console$1.critical, prefix)
6527
+ };
6528
+ };
6254
6529
 
6255
- var str = function(key, holder) {
6256
- var gap = '';
6257
- var indent = ' ';
6258
- var i = 0; // The loop counter.
6259
- var k = ''; // The member key.
6260
- var v = ''; // The member value.
6261
- var length = 0;
6262
- var mind = gap;
6263
- var partial = [];
6264
- var value = holder[key];
6265
6530
 
6266
- // If the value has a toJSON method, call it to obtain a replacement value.
6267
- if (value && typeof value === 'object' &&
6268
- typeof value.toJSON === 'function') {
6269
- value = value.toJSON(key);
6531
+ // UNDERSCORE
6532
+ // Embed part of the Underscore Library
6533
+ _.bind = function(func, context) {
6534
+ var args, bound;
6535
+ if (nativeBind && func.bind === nativeBind) {
6536
+ return nativeBind.apply(func, slice.call(arguments, 1));
6537
+ }
6538
+ if (!_.isFunction(func)) {
6539
+ throw new TypeError();
6540
+ }
6541
+ args = slice.call(arguments, 2);
6542
+ bound = function() {
6543
+ if (!(this instanceof bound)) {
6544
+ return func.apply(context, args.concat(slice.call(arguments)));
6545
+ }
6546
+ var ctor = {};
6547
+ ctor.prototype = func.prototype;
6548
+ var self = new ctor();
6549
+ ctor.prototype = null;
6550
+ var result = func.apply(self, args.concat(slice.call(arguments)));
6551
+ if (Object(result) === result) {
6552
+ return result;
6553
+ }
6554
+ return self;
6555
+ };
6556
+ return bound;
6557
+ };
6558
+
6559
+ /**
6560
+ * @param {*=} obj
6561
+ * @param {function(...*)=} iterator
6562
+ * @param {Object=} context
6563
+ */
6564
+ _.each = function(obj, iterator, context) {
6565
+ if (obj === null || obj === undefined) {
6566
+ return;
6567
+ }
6568
+ if (nativeForEach && obj.forEach === nativeForEach) {
6569
+ obj.forEach(iterator, context);
6570
+ } else if (obj.length === +obj.length) {
6571
+ for (var i = 0, l = obj.length; i < l; i++) {
6572
+ if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) {
6573
+ return;
6574
+ }
6575
+ }
6576
+ } else {
6577
+ for (var key in obj) {
6578
+ if (hasOwnProperty$9.call(obj, key)) {
6579
+ if (iterator.call(context, obj[key], key, obj) === breaker) {
6580
+ return;
6581
+ }
6270
6582
  }
6583
+ }
6584
+ }
6585
+ };
6271
6586
 
6272
- // What happens next depends on the value's type.
6273
- switch (typeof value) {
6274
- case 'string':
6275
- return quote(value);
6587
+ _.extend = function(obj) {
6588
+ _.each(slice.call(arguments, 1), function(source) {
6589
+ for (var prop in source) {
6590
+ if (source[prop] !== void 0) {
6591
+ obj[prop] = source[prop];
6592
+ }
6593
+ }
6594
+ });
6595
+ return obj;
6596
+ };
6276
6597
 
6277
- case 'number':
6278
- // JSON numbers must be finite. Encode non-finite numbers as null.
6279
- return isFinite(value) ? String(value) : 'null';
6598
+ _.isArray = nativeIsArray || function(obj) {
6599
+ return toString.call(obj) === '[object Array]';
6600
+ };
6280
6601
 
6281
- case 'boolean':
6282
- case 'null':
6283
- // If the value is a boolean or null, convert it to a string. Note:
6284
- // typeof null does not produce 'null'. The case is included here in
6285
- // the remote chance that this gets fixed someday.
6602
+ // from a comment on http://dbj.org/dbj/?p=286
6603
+ // fails on only one very rare and deliberate custom object:
6604
+ // var bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
6605
+ _.isFunction = function(f) {
6606
+ try {
6607
+ return /^\s*\bfunction\b/.test(f);
6608
+ } catch (x) {
6609
+ return false;
6610
+ }
6611
+ };
6286
6612
 
6287
- return String(value);
6613
+ _.isArguments = function(obj) {
6614
+ return !!(obj && hasOwnProperty$9.call(obj, 'callee'));
6615
+ };
6288
6616
 
6289
- case 'object':
6290
- // If the type is 'object', we might be dealing with an object or an array or
6291
- // null.
6292
- // Due to a specification blunder in ECMAScript, typeof null is 'object',
6293
- // so watch out for that case.
6294
- if (!value) {
6295
- return 'null';
6296
- }
6617
+ _.toArray = function(iterable) {
6618
+ if (!iterable) {
6619
+ return [];
6620
+ }
6621
+ if (iterable.toArray) {
6622
+ return iterable.toArray();
6623
+ }
6624
+ if (_.isArray(iterable)) {
6625
+ return slice.call(iterable);
6626
+ }
6627
+ if (_.isArguments(iterable)) {
6628
+ return slice.call(iterable);
6629
+ }
6630
+ return _.values(iterable);
6631
+ };
6297
6632
 
6298
- // Make an array to hold the partial results of stringifying this object value.
6299
- gap += indent;
6300
- partial = [];
6633
+ _.map = function(arr, callback, context) {
6634
+ if (nativeMap && arr.map === nativeMap) {
6635
+ return arr.map(callback, context);
6636
+ } else {
6637
+ var results = [];
6638
+ _.each(arr, function(item) {
6639
+ results.push(callback.call(context, item));
6640
+ });
6641
+ return results;
6642
+ }
6643
+ };
6301
6644
 
6302
- // Is the value an array?
6303
- if (toString.apply(value) === '[object Array]') {
6304
- // The value is an array. Stringify every element. Use null as a placeholder
6305
- // for non-JSON values.
6645
+ _.keys = function(obj) {
6646
+ var results = [];
6647
+ if (obj === null) {
6648
+ return results;
6649
+ }
6650
+ _.each(obj, function(value, key) {
6651
+ results[results.length] = key;
6652
+ });
6653
+ return results;
6654
+ };
6306
6655
 
6307
- length = value.length;
6308
- for (i = 0; i < length; i += 1) {
6309
- partial[i] = str(i, value) || 'null';
6310
- }
6656
+ _.values = function(obj) {
6657
+ var results = [];
6658
+ if (obj === null) {
6659
+ return results;
6660
+ }
6661
+ _.each(obj, function(value) {
6662
+ results[results.length] = value;
6663
+ });
6664
+ return results;
6665
+ };
6311
6666
 
6312
- // Join all of the elements together, separated with commas, and wrap them in
6313
- // brackets.
6314
- v = partial.length === 0 ? '[]' :
6315
- gap ? '[\n' + gap +
6316
- partial.join(',\n' + gap) + '\n' +
6317
- mind + ']' :
6318
- '[' + partial.join(',') + ']';
6319
- gap = mind;
6320
- return v;
6321
- }
6667
+ _.include = function(obj, target) {
6668
+ var found = false;
6669
+ if (obj === null) {
6670
+ return found;
6671
+ }
6672
+ if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
6673
+ return obj.indexOf(target) != -1;
6674
+ }
6675
+ _.each(obj, function(value) {
6676
+ if (found || (found = (value === target))) {
6677
+ return breaker;
6678
+ }
6679
+ });
6680
+ return found;
6681
+ };
6322
6682
 
6323
- // Iterate through all of the keys in the object.
6324
- for (k in value) {
6325
- if (hasOwnProperty$9.call(value, k)) {
6326
- v = str(k, value);
6327
- if (v) {
6328
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
6329
- }
6330
- }
6331
- }
6683
+ _.includes = function(str, needle) {
6684
+ return str.indexOf(needle) !== -1;
6685
+ };
6332
6686
 
6333
- // Join all of the member texts together, separated with commas,
6334
- // and wrap them in braces.
6335
- v = partial.length === 0 ? '{}' :
6336
- gap ? '{' + partial.join(',') + '' +
6337
- mind + '}' : '{' + partial.join(',') + '}';
6338
- gap = mind;
6339
- return v;
6340
- }
6341
- };
6687
+ // Underscore Addons
6688
+ _.inherit = function(subclass, superclass) {
6689
+ subclass.prototype = new superclass();
6690
+ subclass.prototype.constructor = subclass;
6691
+ subclass.superclass = superclass.prototype;
6692
+ return subclass;
6693
+ };
6342
6694
 
6343
- // Make a fake root object containing our value under the key of ''.
6344
- // Return the result of stringifying the value.
6345
- return str('', {
6346
- '': value
6347
- });
6348
- };
6349
- })();
6695
+ _.isObject = function(obj) {
6696
+ return (obj === Object(obj) && !_.isArray(obj));
6697
+ };
6350
6698
 
6351
- /**
6352
- * From https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js
6353
- * Slightly modified to throw a real Error rather than a POJO
6354
- */
6355
- _.JSONDecode = (function() {
6356
- var at, // The index of the current character
6357
- ch, // The current character
6358
- escapee = {
6359
- '"': '"',
6360
- '\\': '\\',
6361
- '/': '/',
6362
- 'b': '\b',
6363
- 'f': '\f',
6364
- 'n': '\n',
6365
- 'r': '\r',
6366
- 't': '\t'
6367
- },
6368
- text,
6369
- error = function(m) {
6370
- var e = new SyntaxError(m);
6371
- e.at = at;
6372
- e.text = text;
6373
- throw e;
6374
- },
6375
- next = function(c) {
6376
- // If a c parameter is provided, verify that it matches the current character.
6377
- if (c && c !== ch) {
6378
- error('Expected \'' + c + '\' instead of \'' + ch + '\'');
6699
+ _.isEmptyObject = function(obj) {
6700
+ if (_.isObject(obj)) {
6701
+ for (var key in obj) {
6702
+ if (hasOwnProperty$9.call(obj, key)) {
6703
+ return false;
6379
6704
  }
6380
- // Get the next character. When there are no more characters,
6705
+ }
6706
+ return true;
6707
+ }
6708
+ return false;
6709
+ };
6710
+
6711
+ _.isUndefined = function(obj) {
6712
+ return obj === void 0;
6713
+ };
6714
+
6715
+ _.isString = function(obj) {
6716
+ return toString.call(obj) == '[object String]';
6717
+ };
6718
+
6719
+ _.isDate = function(obj) {
6720
+ return toString.call(obj) == '[object Date]';
6721
+ };
6722
+
6723
+ _.isNumber = function(obj) {
6724
+ return toString.call(obj) == '[object Number]';
6725
+ };
6726
+
6727
+ _.isElement = function(obj) {
6728
+ return !!(obj && obj.nodeType === 1);
6729
+ };
6730
+
6731
+ _.encodeDates = function(obj) {
6732
+ _.each(obj, function(v, k) {
6733
+ if (_.isDate(v)) {
6734
+ obj[k] = _.formatDate(v);
6735
+ } else if (_.isObject(v)) {
6736
+ obj[k] = _.encodeDates(v); // recurse
6737
+ }
6738
+ });
6739
+ return obj;
6740
+ };
6741
+
6742
+ _.timestamp = function() {
6743
+ Date.now = Date.now || function() {
6744
+ return +new Date;
6745
+ };
6746
+ return Date.now();
6747
+ };
6748
+
6749
+ _.formatDate = function(d) {
6750
+ // YYYY-MM-DDTHH:MM:SS in UTC
6751
+ function pad(n) {
6752
+ return n < 10 ? '0' + n : n;
6753
+ }
6754
+ return d.getUTCFullYear() + '-' +
6755
+ pad(d.getUTCMonth() + 1) + '-' +
6756
+ pad(d.getUTCDate()) + 'T' +
6757
+ pad(d.getUTCHours()) + ':' +
6758
+ pad(d.getUTCMinutes()) + ':' +
6759
+ pad(d.getUTCSeconds());
6760
+ };
6761
+
6762
+ _.strip_empty_properties = function(p) {
6763
+ var ret = {};
6764
+ _.each(p, function(v, k) {
6765
+ if (_.isString(v) && v.length > 0) {
6766
+ ret[k] = v;
6767
+ }
6768
+ });
6769
+ return ret;
6770
+ };
6771
+
6772
+ /*
6773
+ * this function returns a copy of object after truncating it. If
6774
+ * passed an Array or Object it will iterate through obj and
6775
+ * truncate all the values recursively.
6776
+ */
6777
+ _.truncate = function(obj, length) {
6778
+ var ret;
6779
+
6780
+ if (typeof(obj) === 'string') {
6781
+ ret = obj.slice(0, length);
6782
+ } else if (_.isArray(obj)) {
6783
+ ret = [];
6784
+ _.each(obj, function(val) {
6785
+ ret.push(_.truncate(val, length));
6786
+ });
6787
+ } else if (_.isObject(obj)) {
6788
+ ret = {};
6789
+ _.each(obj, function(val, key) {
6790
+ ret[key] = _.truncate(val, length);
6791
+ });
6792
+ } else {
6793
+ ret = obj;
6794
+ }
6795
+
6796
+ return ret;
6797
+ };
6798
+
6799
+ _.JSONEncode = (function() {
6800
+ return function(mixed_val) {
6801
+ var value = mixed_val;
6802
+ var quote = function(string) {
6803
+ var escapable = /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; // eslint-disable-line no-control-regex
6804
+ var meta = { // table of character substitutions
6805
+ '\b': '\\b',
6806
+ '\t': '\\t',
6807
+ '\n': '\\n',
6808
+ '\f': '\\f',
6809
+ '\r': '\\r',
6810
+ '"': '\\"',
6811
+ '\\': '\\\\'
6812
+ };
6813
+
6814
+ escapable.lastIndex = 0;
6815
+ return escapable.test(string) ?
6816
+ '"' + string.replace(escapable, function(a) {
6817
+ var c = meta[a];
6818
+ return typeof c === 'string' ? c :
6819
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
6820
+ }) + '"' :
6821
+ '"' + string + '"';
6822
+ };
6823
+
6824
+ var str = function(key, holder) {
6825
+ var gap = '';
6826
+ var indent = ' ';
6827
+ var i = 0; // The loop counter.
6828
+ var k = ''; // The member key.
6829
+ var v = ''; // The member value.
6830
+ var length = 0;
6831
+ var mind = gap;
6832
+ var partial = [];
6833
+ var value = holder[key];
6834
+
6835
+ // If the value has a toJSON method, call it to obtain a replacement value.
6836
+ if (value && typeof value === 'object' &&
6837
+ typeof value.toJSON === 'function') {
6838
+ value = value.toJSON(key);
6839
+ }
6840
+
6841
+ // What happens next depends on the value's type.
6842
+ switch (typeof value) {
6843
+ case 'string':
6844
+ return quote(value);
6845
+
6846
+ case 'number':
6847
+ // JSON numbers must be finite. Encode non-finite numbers as null.
6848
+ return isFinite(value) ? String(value) : 'null';
6849
+
6850
+ case 'boolean':
6851
+ case 'null':
6852
+ // If the value is a boolean or null, convert it to a string. Note:
6853
+ // typeof null does not produce 'null'. The case is included here in
6854
+ // the remote chance that this gets fixed someday.
6855
+
6856
+ return String(value);
6857
+
6858
+ case 'object':
6859
+ // If the type is 'object', we might be dealing with an object or an array or
6860
+ // null.
6861
+ // Due to a specification blunder in ECMAScript, typeof null is 'object',
6862
+ // so watch out for that case.
6863
+ if (!value) {
6864
+ return 'null';
6865
+ }
6866
+
6867
+ // Make an array to hold the partial results of stringifying this object value.
6868
+ gap += indent;
6869
+ partial = [];
6870
+
6871
+ // Is the value an array?
6872
+ if (toString.apply(value) === '[object Array]') {
6873
+ // The value is an array. Stringify every element. Use null as a placeholder
6874
+ // for non-JSON values.
6875
+
6876
+ length = value.length;
6877
+ for (i = 0; i < length; i += 1) {
6878
+ partial[i] = str(i, value) || 'null';
6879
+ }
6880
+
6881
+ // Join all of the elements together, separated with commas, and wrap them in
6882
+ // brackets.
6883
+ v = partial.length === 0 ? '[]' :
6884
+ gap ? '[\n' + gap +
6885
+ partial.join(',\n' + gap) + '\n' +
6886
+ mind + ']' :
6887
+ '[' + partial.join(',') + ']';
6888
+ gap = mind;
6889
+ return v;
6890
+ }
6891
+
6892
+ // Iterate through all of the keys in the object.
6893
+ for (k in value) {
6894
+ if (hasOwnProperty$9.call(value, k)) {
6895
+ v = str(k, value);
6896
+ if (v) {
6897
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
6898
+ }
6899
+ }
6900
+ }
6901
+
6902
+ // Join all of the member texts together, separated with commas,
6903
+ // and wrap them in braces.
6904
+ v = partial.length === 0 ? '{}' :
6905
+ gap ? '{' + partial.join(',') + '' +
6906
+ mind + '}' : '{' + partial.join(',') + '}';
6907
+ gap = mind;
6908
+ return v;
6909
+ }
6910
+ };
6911
+
6912
+ // Make a fake root object containing our value under the key of ''.
6913
+ // Return the result of stringifying the value.
6914
+ return str('', {
6915
+ '': value
6916
+ });
6917
+ };
6918
+ })();
6919
+
6920
+ /**
6921
+ * From https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js
6922
+ * Slightly modified to throw a real Error rather than a POJO
6923
+ */
6924
+ _.JSONDecode = (function() {
6925
+ var at, // The index of the current character
6926
+ ch, // The current character
6927
+ escapee = {
6928
+ '"': '"',
6929
+ '\\': '\\',
6930
+ '/': '/',
6931
+ 'b': '\b',
6932
+ 'f': '\f',
6933
+ 'n': '\n',
6934
+ 'r': '\r',
6935
+ 't': '\t'
6936
+ },
6937
+ text,
6938
+ error = function(m) {
6939
+ var e = new SyntaxError(m);
6940
+ e.at = at;
6941
+ e.text = text;
6942
+ throw e;
6943
+ },
6944
+ next = function(c) {
6945
+ // If a c parameter is provided, verify that it matches the current character.
6946
+ if (c && c !== ch) {
6947
+ error('Expected \'' + c + '\' instead of \'' + ch + '\'');
6948
+ }
6949
+ // Get the next character. When there are no more characters,
6381
6950
  // return the empty string.
6382
6951
  ch = text.charAt(at);
6383
6952
  at += 1;
@@ -11829,6 +12398,7 @@ const MIXPANEL_EVENT = {
11829
12398
  VISUAL_SDK_ON: 'visual-sdk-on',
11830
12399
  VISUAL_SDK_IFRAME_LOAD_PERFORMANCE: 'visual-sdk-iframe-load-performance',
11831
12400
  VISUAL_SDK_EMBED_CREATE: 'visual-sdk-embed-create',
12401
+ VERCEL_INTEGRATION_COMPLETED: 'vercel-integration-completed',
11832
12402
  };
11833
12403
  let isMixpanelInitialized = false;
11834
12404
  let eventQueue = [];
@@ -11891,1086 +12461,158 @@ function initMixpanel(sessionInfo) {
11891
12461
  }
11892
12462
  }
11893
12463
 
11894
- let config = {};
11895
- /**
11896
- * Gets the configuration embed was initialized with.
11897
- *
11898
- * @returns {@link EmbedConfig} The configuration embed was initialized with.
11899
- * @version SDK: 1.19.0 | ThoughtSpot: *
11900
- * @group Global methods
11901
- */
11902
- const getEmbedConfig = () => config;
11903
- /**
11904
- * Sets the configuration embed was initialized with.
11905
- * And returns the new configuration.
11906
- *
11907
- * @param newConfig The configuration to set.
11908
- * @version SDK: 1.27.0 | ThoughtSpot: *
11909
- * @group Global methods
11910
- */
11911
- const setEmbedConfig = (newConfig) => {
11912
- config = newConfig;
11913
- return newConfig;
12464
+ var eventemitter3 = createCommonjsModule(function (module) {
12465
+
12466
+ var has = Object.prototype.hasOwnProperty
12467
+ , prefix = '~';
12468
+
12469
+ /**
12470
+ * Constructor to create a storage for our `EE` objects.
12471
+ * An `Events` instance is a plain object whose properties are event names.
12472
+ *
12473
+ * @constructor
12474
+ * @private
12475
+ */
12476
+ function Events() {}
12477
+
12478
+ //
12479
+ // We try to not inherit from `Object.prototype`. In some engines creating an
12480
+ // instance in this way is faster than calling `Object.create(null)` directly.
12481
+ // If `Object.create(null)` is not supported we prefix the event names with a
12482
+ // character to make sure that the built-in object properties are not
12483
+ // overridden or used as an attack vector.
12484
+ //
12485
+ if (Object.create) {
12486
+ Events.prototype = Object.create(null);
12487
+
12488
+ //
12489
+ // This hack is needed because the `__proto__` property is still inherited in
12490
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
12491
+ //
12492
+ if (!new Events().__proto__) prefix = false;
12493
+ }
12494
+
12495
+ /**
12496
+ * Representation of a single event listener.
12497
+ *
12498
+ * @param {Function} fn The listener function.
12499
+ * @param {*} context The context to invoke the listener with.
12500
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
12501
+ * @constructor
12502
+ * @private
12503
+ */
12504
+ function EE(fn, context, once) {
12505
+ this.fn = fn;
12506
+ this.context = context;
12507
+ this.once = once || false;
12508
+ }
12509
+
12510
+ /**
12511
+ * Add a listener for a given event.
12512
+ *
12513
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
12514
+ * @param {(String|Symbol)} event The event name.
12515
+ * @param {Function} fn The listener function.
12516
+ * @param {*} context The context to invoke the listener with.
12517
+ * @param {Boolean} once Specify if the listener is a one-time listener.
12518
+ * @returns {EventEmitter}
12519
+ * @private
12520
+ */
12521
+ function addListener(emitter, event, fn, context, once) {
12522
+ if (typeof fn !== 'function') {
12523
+ throw new TypeError('The listener must be a function');
12524
+ }
12525
+
12526
+ var listener = new EE(fn, context || emitter, once)
12527
+ , evt = prefix ? prefix + event : event;
12528
+
12529
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
12530
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
12531
+ else emitter._events[evt] = [emitter._events[evt], listener];
12532
+
12533
+ return emitter;
12534
+ }
12535
+
12536
+ /**
12537
+ * Clear event by name.
12538
+ *
12539
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
12540
+ * @param {(String|Symbol)} evt The Event name.
12541
+ * @private
12542
+ */
12543
+ function clearEvent(emitter, evt) {
12544
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
12545
+ else delete emitter._events[evt];
12546
+ }
12547
+
12548
+ /**
12549
+ * Minimal `EventEmitter` interface that is molded against the Node.js
12550
+ * `EventEmitter` interface.
12551
+ *
12552
+ * @constructor
12553
+ * @public
12554
+ */
12555
+ function EventEmitter() {
12556
+ this._events = new Events();
12557
+ this._eventsCount = 0;
12558
+ }
12559
+
12560
+ /**
12561
+ * Return an array listing the events for which the emitter has registered
12562
+ * listeners.
12563
+ *
12564
+ * @returns {Array}
12565
+ * @public
12566
+ */
12567
+ EventEmitter.prototype.eventNames = function eventNames() {
12568
+ var names = []
12569
+ , events
12570
+ , name;
12571
+
12572
+ if (this._eventsCount === 0) return names;
12573
+
12574
+ for (name in (events = this._events)) {
12575
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
12576
+ }
12577
+
12578
+ if (Object.getOwnPropertySymbols) {
12579
+ return names.concat(Object.getOwnPropertySymbols(events));
12580
+ }
12581
+
12582
+ return names;
11914
12583
  };
11915
12584
 
11916
- const tokenizedFetch = async (input, init) => {
11917
- const embedConfig = getEmbedConfig();
11918
- if (embedConfig.authType !== AuthType.TrustedAuthTokenCookieless) {
11919
- return fetch(input, init);
11920
- }
11921
- const req = new Request(input, init);
11922
- const authToken = await getAuthenticationToken(embedConfig);
11923
- if (authToken) {
11924
- req.headers.append('Authorization', `Bearer ${authToken}`);
11925
- }
11926
- return fetch(req);
12585
+ /**
12586
+ * Return the listeners registered for a given event.
12587
+ *
12588
+ * @param {(String|Symbol)} event The event name.
12589
+ * @returns {Array} The registered listeners.
12590
+ * @public
12591
+ */
12592
+ EventEmitter.prototype.listeners = function listeners(event) {
12593
+ var evt = prefix ? prefix + event : event
12594
+ , handlers = this._events[evt];
12595
+
12596
+ if (!handlers) return [];
12597
+ if (handlers.fn) return [handlers.fn];
12598
+
12599
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
12600
+ ee[i] = handlers[i].fn;
12601
+ }
12602
+
12603
+ return ee;
11927
12604
  };
11928
12605
 
11929
- /**
11930
- *
11931
- * @param url
11932
- * @param options
11933
- */
11934
- function tokenisedFailureLoggedFetch(url, options = {}) {
11935
- return tokenizedFetch(url, options).then(async (r) => {
11936
- var _a;
11937
- if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
11938
- logger.error('Failure', await ((_a = r.text) === null || _a === void 0 ? void 0 : _a.call(r)));
11939
- }
11940
- return r;
11941
- });
11942
- }
11943
- /**
11944
- *
11945
- * @param authVerificationUrl
11946
- */
11947
- function fetchSessionInfoService(authVerificationUrl) {
11948
- return tokenisedFailureLoggedFetch(authVerificationUrl, {
11949
- credentials: 'include',
11950
- });
11951
- }
11952
- /**
11953
- *
11954
- * @param thoughtSpotHost
11955
- */
11956
- async function fetchLogoutService(thoughtSpotHost) {
11957
- return tokenisedFailureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
11958
- credentials: 'include',
11959
- method: 'POST',
11960
- headers: {
11961
- 'x-requested-by': 'ThoughtSpot',
11962
- },
11963
- });
11964
- }
11965
-
11966
- // eslint-disable-next-line import/no-mutable-exports
11967
- let loggedInStatus = false;
11968
- // eslint-disable-next-line import/no-mutable-exports
11969
- let samlAuthWindow = null;
11970
- // eslint-disable-next-line import/no-mutable-exports
11971
- let samlCompletionPromise = null;
11972
- let sessionInfo = null;
11973
- let sessionInfoResolver = null;
11974
- const sessionInfoPromise = new Promise((resolve) => {
11975
- sessionInfoResolver = resolve;
11976
- });
11977
- let releaseVersion = '';
11978
- const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
11979
- /**
11980
- * Enum for auth failure types. This is the parameter passed to the listner
11981
- * of {@link AuthStatus.FAILURE}.
11982
- *
11983
- * @group Authentication / Init
11984
- */
11985
- var AuthFailureType;
11986
- (function (AuthFailureType) {
11987
- AuthFailureType["SDK"] = "SDK";
11988
- AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
11989
- AuthFailureType["EXPIRY"] = "EXPIRY";
11990
- AuthFailureType["OTHER"] = "OTHER";
11991
- })(AuthFailureType || (AuthFailureType = {}));
11992
- /**
11993
- * Enum for auth status emitted by the emitter returned from {@link init}.
11994
- *
11995
- * @group Authentication / Init
11996
- */
11997
- var AuthStatus;
11998
- (function (AuthStatus) {
11999
- /**
12000
- * Emits when the SDK fails to authenticate
12001
- */
12002
- AuthStatus["FAILURE"] = "FAILURE";
12003
- /**
12004
- * Emits when the SDK authenticates successfully
12005
- */
12006
- AuthStatus["SDK_SUCCESS"] = "SDK_SUCCESS";
12007
- /**
12008
- * Emits when the app sends an authentication success message
12009
- */
12010
- AuthStatus["SUCCESS"] = "SUCCESS";
12011
- /**
12012
- * Emits when a user logs out
12013
- */
12014
- AuthStatus["LOGOUT"] = "LOGOUT";
12015
- /**
12016
- * Emitted when inPopup is true in the SAMLRedirect flow and the
12017
- * popup is waiting to be triggered either programmatically
12018
- * or by the trigger button.
12019
- *
12020
- * @version SDK: 1.19.0
12021
- */
12022
- AuthStatus["WAITING_FOR_POPUP"] = "WAITING_FOR_POPUP";
12023
- })(AuthStatus || (AuthStatus = {}));
12024
- /**
12025
- * Events which can be triggered on the emitter returned from {@link init}.
12026
- *
12027
- * @group Authentication / Init
12028
- */
12029
- var AuthEvent;
12030
- (function (AuthEvent) {
12031
- /**
12032
- * Manually trigger the SSO popup. This is useful when
12033
- * authStatus is SAMLRedirect/OIDCRedirect and inPopup is set to true
12034
- */
12035
- AuthEvent["TRIGGER_SSO_POPUP"] = "TRIGGER_SSO_POPUP";
12036
- })(AuthEvent || (AuthEvent = {}));
12037
- let authEE;
12038
- /**
12039
- *
12040
- * @param eventEmitter
12041
- */
12042
- function setAuthEE(eventEmitter) {
12043
- authEE = eventEmitter;
12044
- }
12045
- /**
12046
- *
12047
- */
12048
- function notifyAuthSDKSuccess() {
12049
- if (!authEE) {
12050
- logger.error('SDK not initialized');
12051
- return;
12052
- }
12053
- authEE.emit(AuthStatus.SDK_SUCCESS);
12054
- }
12055
- /**
12056
- *
12057
- */
12058
- function notifyAuthSuccess() {
12059
- if (!authEE) {
12060
- logger.error('SDK not initialized');
12061
- return;
12062
- }
12063
- authEE.emit(AuthStatus.SUCCESS, sessionInfo);
12064
- }
12065
- /**
12066
- *
12067
- * @param failureType
12068
- */
12069
- function notifyAuthFailure(failureType) {
12070
- if (!authEE) {
12071
- logger.error('SDK not initialized');
12072
- return;
12073
- }
12074
- authEE.emit(AuthStatus.FAILURE, failureType);
12075
- }
12076
- /**
12077
- *
12078
- */
12079
- function notifyLogout() {
12080
- if (!authEE) {
12081
- logger.error('SDK not initialized');
12082
- return;
12083
- }
12084
- authEE.emit(AuthStatus.LOGOUT);
12085
- }
12086
- const initSession = (sessionDetails) => {
12087
- if (sessionInfo == null) {
12088
- sessionInfo = sessionDetails;
12089
- initMixpanel(sessionInfo);
12090
- sessionInfoResolver(sessionInfo);
12091
- }
12092
- };
12093
- const getSessionDetails = (sessionInfoResp) => {
12094
- const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
12095
- const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
12096
- const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
12097
- ? prodMixpanelToken
12098
- : devMixpanelToken;
12099
- return {
12100
- userGUID: sessionInfoResp.userGUID,
12101
- mixpanelToken,
12102
- isPublicUser: sessionInfoResp.configInfo.isPublicUser,
12103
- releaseVersion: sessionInfoResp.releaseVersion,
12104
- clusterId: sessionInfoResp.configInfo.selfClusterId,
12105
- clusterName: sessionInfoResp.configInfo.selfClusterName,
12106
- ...sessionInfoResp,
12107
- };
12108
- };
12109
- /**
12110
- * Check if we are logged into the ThoughtSpot cluster
12111
- *
12112
- * @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
12113
- */
12114
- async function isLoggedIn(thoughtSpotHost) {
12115
- const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
12116
- let response = null;
12117
- try {
12118
- response = await fetchSessionInfoService(authVerificationUrl);
12119
- const sessionInfoResp = await response.json();
12120
- const sessionDetails = getSessionDetails(sessionInfoResp);
12121
- // Store user session details from session info
12122
- initSession(sessionDetails);
12123
- releaseVersion = sessionInfoResp.releaseVersion;
12124
- }
12125
- catch (e) {
12126
- return false;
12127
- }
12128
- return response.status === 200;
12129
- }
12130
- /**
12131
- * Return releaseVersion if available
12132
- */
12133
- function getReleaseVersion() {
12134
- return releaseVersion;
12135
- }
12136
- /**
12137
- * Return a promise that resolves with the session information when
12138
- * authentication is successful. And info is available.
12139
- *
12140
- * @group Global methods
12141
- */
12142
- function getSessionInfo() {
12143
- return sessionInfoPromise;
12144
- }
12145
- /**
12146
- * Check if we are stuck at the SSO redirect URL
12147
- */
12148
- function isAtSSORedirectUrl() {
12149
- return window.location.href.indexOf(SSO_REDIRECTION_MARKER_GUID) >= 0;
12150
- }
12151
- /**
12152
- * Remove the SSO redirect URL marker
12153
- */
12154
- function removeSSORedirectUrlMarker() {
12155
- // Note (sunny): This will leave a # around even if it was not in the URL
12156
- // to begin with. Trying to remove the hash by changing window.location will
12157
- // reload the page which we don't want. We'll live with adding an
12158
- // unnecessary hash to the parent page URL until we find any use case where
12159
- // that creates an issue.
12160
- window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
12161
- }
12162
- /**
12163
- * Perform token based authentication
12164
- *
12165
- * @param embedConfig The embed configuration
12166
- */
12167
- const doTokenAuth = async (embedConfig) => {
12168
- const { thoughtSpotHost, username, authEndpoint, getAuthToken, } = embedConfig;
12169
- if (!authEndpoint && !getAuthToken) {
12170
- throw new Error('Either auth endpoint or getAuthToken function must be provided');
12171
- }
12172
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
12173
- if (!loggedInStatus) {
12174
- const authToken = await getAuthenticationToken(embedConfig);
12175
- let resp;
12176
- try {
12177
- resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
12178
- }
12179
- catch (e) {
12180
- resp = await fetchAuthService(thoughtSpotHost, username, authToken);
12181
- }
12182
- // token login issues a 302 when successful
12183
- loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
12184
- if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
12185
- // When 3rd party cookie access is blocked, this will fail because
12186
- // cookies will not be sent with the call.
12187
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
12188
- }
12189
- }
12190
- return loggedInStatus;
12191
- };
12192
- /**
12193
- * Validate embedConfig parameters required for cookielessTokenAuth
12194
- *
12195
- * @param embedConfig The embed configuration
12196
- */
12197
- const doCookielessTokenAuth = async (embedConfig) => {
12198
- const { authEndpoint, getAuthToken } = embedConfig;
12199
- if (!authEndpoint && !getAuthToken) {
12200
- throw new Error('Either auth endpoint or getAuthToken function must be provided');
12201
- }
12202
- let authSuccess = false;
12203
- try {
12204
- const authToken = await getAuthenticationToken(embedConfig);
12205
- if (authToken) {
12206
- authSuccess = true;
12207
- }
12208
- }
12209
- catch {
12210
- authSuccess = false;
12211
- }
12212
- return authSuccess;
12213
- };
12214
- /**
12215
- * Perform basic authentication to the ThoughtSpot cluster using the cluster
12216
- * credentials.
12217
- *
12218
- * Warning: This feature is primarily intended for developer testing. It is
12219
- * strongly advised not to use this authentication method in production.
12220
- *
12221
- * @param embedConfig The embed configuration
12222
- */
12223
- const doBasicAuth = async (embedConfig) => {
12224
- const { thoughtSpotHost, username, password } = embedConfig;
12225
- const loggedIn = await isLoggedIn(thoughtSpotHost);
12226
- if (!loggedIn) {
12227
- const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
12228
- loggedInStatus = response.ok;
12229
- if (embedConfig.detectCookieAccessSlow) {
12230
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
12231
- }
12232
- }
12233
- else {
12234
- loggedInStatus = true;
12235
- }
12236
- return loggedInStatus;
12237
- };
12238
- /**
12239
- *
12240
- * @param ssoURL
12241
- * @param triggerContainer
12242
- * @param triggerText
12243
- */
12244
- async function samlPopupFlow(ssoURL, triggerContainer, triggerText) {
12245
- const openPopup = () => {
12246
- if (samlAuthWindow === null || samlAuthWindow.closed) {
12247
- samlAuthWindow = window.open(ssoURL, '_blank', 'location=no,height=570,width=520,scrollbars=yes,status=yes');
12248
- }
12249
- else {
12250
- samlAuthWindow.focus();
12251
- }
12252
- };
12253
- authEE === null || authEE === void 0 ? void 0 : authEE.emit(AuthStatus.WAITING_FOR_POPUP);
12254
- const containerEl = getDOMNode(triggerContainer);
12255
- if (containerEl) {
12256
- containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
12257
- const authElem = document.getElementById('ts-auth-btn');
12258
- authElem.textContent = triggerText;
12259
- authElem.addEventListener('click', openPopup, { once: true });
12260
- }
12261
- samlCompletionPromise = samlCompletionPromise
12262
- || new Promise((resolve, reject) => {
12263
- window.addEventListener('message', (e) => {
12264
- if (e.data.type === EmbedEvent.SAMLComplete) {
12265
- e.source.close();
12266
- resolve();
12267
- }
12268
- });
12269
- });
12270
- authEE === null || authEE === void 0 ? void 0 : authEE.once(AuthEvent.TRIGGER_SSO_POPUP, openPopup);
12271
- return samlCompletionPromise;
12272
- }
12273
- /**
12274
- * Perform SAML authentication
12275
- *
12276
- * @param embedConfig The embed configuration
12277
- * @param ssoEndPoint
12278
- */
12279
- const doSSOAuth = async (embedConfig, ssoEndPoint) => {
12280
- const { thoughtSpotHost } = embedConfig;
12281
- const loggedIn = await isLoggedIn(thoughtSpotHost);
12282
- if (loggedIn) {
12283
- if (isAtSSORedirectUrl()) {
12284
- removeSSORedirectUrlMarker();
12285
- }
12286
- loggedInStatus = true;
12287
- return;
12288
- }
12289
- // we have already tried authentication and it did not succeed, restore
12290
- // the current URL to the original one and invoke the callback.
12291
- if (isAtSSORedirectUrl()) {
12292
- removeSSORedirectUrlMarker();
12293
- loggedInStatus = false;
12294
- return;
12295
- }
12296
- const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
12297
- if (embedConfig.inPopup) {
12298
- await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
12299
- loggedInStatus = await isLoggedIn(thoughtSpotHost);
12300
- return;
12301
- }
12302
- window.location.href = ssoURL;
12303
- };
12304
- const doSamlAuth = async (embedConfig) => {
12305
- const { thoughtSpotHost } = embedConfig;
12306
- // redirect for SSO, when the SSO authentication is done, this page will be
12307
- // loaded again and the same JS will execute again.
12308
- const ssoRedirectUrl = embedConfig.inPopup
12309
- ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
12310
- : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
12311
- // bring back the page to the same URL
12312
- const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
12313
- await doSSOAuth(embedConfig, ssoEndPoint);
12314
- return loggedInStatus;
12315
- };
12316
- const doOIDCAuth = async (embedConfig) => {
12317
- const { thoughtSpotHost } = embedConfig;
12318
- // redirect for SSO, when the SSO authentication is done, this page will be
12319
- // loaded again and the same JS will execute again.
12320
- const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
12321
- ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
12322
- : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
12323
- // bring back the page to the same URL
12324
- const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
12325
- await doSSOAuth(embedConfig, ssoEndPoint);
12326
- return loggedInStatus;
12327
- };
12328
- const logout = async (embedConfig) => {
12329
- const { thoughtSpotHost } = embedConfig;
12330
- await fetchLogoutService(thoughtSpotHost);
12331
- resetCachedAuthToken();
12332
- const thoughtspotIframes = document.querySelectorAll("[data-ts-iframe='true']");
12333
- if (thoughtspotIframes === null || thoughtspotIframes === void 0 ? void 0 : thoughtspotIframes.length) {
12334
- thoughtspotIframes.forEach((el) => {
12335
- el.parentElement.innerHTML = embedConfig.loginFailedMessage;
12336
- });
12337
- }
12338
- loggedInStatus = false;
12339
- return loggedInStatus;
12340
- };
12341
- /**
12342
- * Perform authentication on the ThoughtSpot cluster
12343
- *
12344
- * @param embedConfig The embed configuration
12345
- */
12346
- const authenticate = async (embedConfig) => {
12347
- const { authType } = embedConfig;
12348
- switch (authType) {
12349
- case AuthType.SSO:
12350
- case AuthType.SAMLRedirect:
12351
- case AuthType.SAML:
12352
- return doSamlAuth(embedConfig);
12353
- case AuthType.OIDC:
12354
- case AuthType.OIDCRedirect:
12355
- return doOIDCAuth(embedConfig);
12356
- case AuthType.AuthServer:
12357
- case AuthType.TrustedAuthToken:
12358
- return doTokenAuth(embedConfig);
12359
- case AuthType.TrustedAuthTokenCookieless:
12360
- return doCookielessTokenAuth(embedConfig);
12361
- case AuthType.Basic:
12362
- return doBasicAuth(embedConfig);
12363
- default:
12364
- return Promise.resolve(true);
12365
- }
12366
- };
12367
-
12368
- const ERROR_MESSAGE = {
12369
- INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
12370
- LIVEBOARD_VIZ_ID_VALIDATION: 'Please provide either liveboardId or pinboardId',
12371
- TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
12372
- SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
12373
- SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
12374
- };
12375
-
12376
- /**
12377
- * Copyright (c) 2023
12378
- *
12379
- * Utilities related to reading configuration objects
12380
- *
12381
- * @summary Config-related utils
12382
- * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
12383
- */
12384
- const urlRegex = new RegExp([
12385
- '(^(https?:)//)?',
12386
- '(([^:/?#]*)(?::([0-9]+))?)',
12387
- '(/{0,1}[^?#]*)',
12388
- '(\\?[^#]*|)',
12389
- '(#.*|)$', // hash
12390
- ].join(''));
12391
- /**
12392
- * Parse and construct the ThoughtSpot hostname or IP address
12393
- * from the embed configuration object.
12394
- *
12395
- * @param config
12396
- */
12397
- const getThoughtSpotHost = (config) => {
12398
- if (!config.thoughtSpotHost) {
12399
- throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
12400
- }
12401
- const urlParts = config.thoughtSpotHost.match(urlRegex);
12402
- if (!urlParts) {
12403
- throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
12404
- }
12405
- const protocol = urlParts[2] || window.location.protocol;
12406
- const host = urlParts[3];
12407
- let path = urlParts[6];
12408
- // Lose the trailing / if any
12409
- if (path.charAt(path.length - 1) === '/') {
12410
- path = path.substring(0, path.length - 1);
12411
- }
12412
- // const urlParams = urlParts[7];
12413
- // const hash = urlParts[8];
12414
- return `${protocol}//${host}${path}`;
12415
- };
12416
- const getV2BasePath = (config) => {
12417
- if (config.basepath) {
12418
- return config.basepath;
12419
- }
12420
- const tsHost = getThoughtSpotHost(config);
12421
- // This is to handle when e2e's. Search is run on pods for
12422
- // comp-blink-test-pipeline with baseUrl=https://localhost:8443.
12423
- // This is to handle when the developer is developing in their local
12424
- // environment.
12425
- if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
12426
- return '';
12427
- }
12428
- return 'v2';
12429
- };
12430
- /**
12431
- * It is a good idea to keep URLs under 2000 chars.
12432
- * If this is ever breached, since we pass view configuration through
12433
- * URL params, we would like to log a warning.
12434
- * Reference: https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
12435
- */
12436
- const URL_MAX_LENGTH = 2000;
12437
- /**
12438
- * The default CSS dimensions of the embedded app
12439
- */
12440
- const DEFAULT_EMBED_WIDTH = '100%';
12441
- const DEFAULT_EMBED_HEIGHT = '100%';
12442
-
12443
- /**
12444
- *
12445
- * @param root0
12446
- * @param root0.query
12447
- * @param root0.variables
12448
- * @param root0.thoughtSpotHost
12449
- * @param root0.isCompositeQuery
12450
- */
12451
- async function graphqlQuery({ query, variables, thoughtSpotHost, isCompositeQuery = false, }) {
12452
- const operationName = getOperationNameFromQuery(query);
12453
- try {
12454
- const response = await fetch(`${thoughtSpotHost}/prism/?op=${operationName}`, {
12455
- method: 'POST',
12456
- headers: {
12457
- 'content-type': 'application/json;charset=UTF-8',
12458
- 'x-requested-by': 'ThoughtSpot',
12459
- accept: '*/*',
12460
- 'accept-language': 'en-us',
12461
- },
12462
- body: JSON.stringify({
12463
- operationName,
12464
- query,
12465
- variables,
12466
- }),
12467
- credentials: 'include',
12468
- });
12469
- const result = await response.json();
12470
- const dataValues = Object.values(result.data);
12471
- return (isCompositeQuery) ? result.data : dataValues[0];
12472
- }
12473
- catch (error) {
12474
- return error;
12475
- }
12476
- }
12477
-
12478
- const getSourceDetailQuery = `
12479
- query GetSourceDetail($ids: [GUID!]!) {
12480
- getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {
12481
- id
12482
- name
12483
- description
12484
- authorName
12485
- authorDisplayName
12486
- isExternal
12487
- type
12488
- created
12489
- modified
12490
- columns {
12491
- id
12492
- name
12493
- author
12494
- authorDisplayName
12495
- description
12496
- dataType
12497
- type
12498
- modified
12499
- ownerName
12500
- owner
12501
- dataRecency
12502
- sources {
12503
- tableId
12504
- tableName
12505
- columnId
12506
- columnName
12507
- __typename
12508
- }
12509
- synonyms
12510
- cohortAnswerId
12511
- __typename
12512
- }
12513
- relationships
12514
- destinationRelationships
12515
- dataSourceId
12516
- __typename
12517
- }
12518
- }
12519
- `;
12520
- const sourceDetailCache = new Map();
12521
- /**
12522
- *
12523
- * @param thoughtSpotHost
12524
- * @param sourceId
12525
- */
12526
- async function getSourceDetail(thoughtSpotHost, sourceId) {
12527
- if (sourceDetailCache.get(sourceId)) {
12528
- return sourceDetailCache.get(sourceId);
12529
- }
12530
- const details = await graphqlQuery({
12531
- query: getSourceDetailQuery,
12532
- variables: {
12533
- ids: [sourceId],
12534
- },
12535
- thoughtSpotHost,
12536
- });
12537
- const souceDetails = details[0];
12538
- if (souceDetails) {
12539
- sourceDetailCache.set(sourceId, souceDetails);
12540
- }
12541
- return souceDetails;
12542
- }
12543
-
12544
- const bachSessionId = `
12545
- id {
12546
- sessionId
12547
- genNo
12548
- acSession {
12549
- sessionId
12550
- genNo
12551
- }
12552
- }
12553
- `;
12554
- const getUnaggregatedAnswerSession = `
12555
- mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
12556
- Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
12557
- ${bachSessionId}
12558
- answer {
12559
- visualizations {
12560
- ... on TableViz {
12561
- columns {
12562
- column {
12563
- id
12564
- name
12565
- referencedColumns {
12566
- guid
12567
- displayName
12568
- }
12569
- }
12570
- }
12571
- }
12572
- }
12573
- }
12574
- }
12575
- }
12576
- `;
12577
- const removeColumns = `
12578
- mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
12579
- Answer__removeColumns(
12580
- session: $session
12581
- logicalColumnIds: $logicalColumnIds
12582
- columnIds: $columnIds
12583
- ) {
12584
- ${bachSessionId}
12585
- }
12586
- }
12587
- `;
12588
- const addColumns = `
12589
- mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
12590
- Answer__addColumn(session: $session, columns: $columns) {
12591
- ${bachSessionId}
12592
- }
12593
- }
12594
- `;
12595
- const getAnswerData = `
12596
- query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
12597
- getAnswer(session: $session) {
12598
- ${bachSessionId}
12599
- answer {
12600
- id
12601
- visualizations {
12602
- id
12603
- ... on TableViz {
12604
- columns {
12605
- column {
12606
- id
12607
- name
12608
- type
12609
- aggregationType
12610
- dataType
12611
- }
12612
- }
12613
- data(deadline: $deadline, pagination: $dataPaginationParams)
12614
- }
12615
- }
12616
- }
12617
- }
12618
- }
12619
- `;
12620
-
12621
- // eslint-disable-next-line no-shadow
12622
- var OperationType;
12623
- (function (OperationType) {
12624
- OperationType["GetChartWithData"] = "GetChartWithData";
12625
- OperationType["GetTableWithHeadlineData"] = "GetTableWithHeadlineData";
12626
- })(OperationType || (OperationType = {}));
12627
- /**
12628
- * Class representing the answer service provided with the
12629
- * custom action payload. This service could be used to run
12630
- * graphql queries in the context of the answer on which the
12631
- * custom action was triggered.
12632
- *
12633
- * @example
12634
- * ```js
12635
- * embed.on(EmbedEvent.CustomAction, e => {
12636
- * const underlying = await e.answerService.getUnderlyingDataForPoint([
12637
- * 'col name 1'
12638
- * ]);
12639
- * const data = await underlying.fetchData(0, 100);
12640
- * })
12641
- * ```
12642
- * @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
12643
- * @group Events
12644
- */
12645
- class AnswerService {
12646
- constructor(session, answer, thoughtSpotHost, selectedPoints) {
12647
- this.session = session;
12648
- this.answer = answer;
12649
- this.thoughtSpotHost = thoughtSpotHost;
12650
- this.selectedPoints = selectedPoints;
12651
- this.session = removeTypename(session);
12652
- }
12653
- async getSourceDetail() {
12654
- const sourceId = this.answer.sources[0].header.guid;
12655
- return getSourceDetail(this.thoughtSpotHost, sourceId);
12656
- }
12657
- async removeColumns(columnIds) {
12658
- return this.executeQuery(removeColumns, {
12659
- logicalColumnIds: columnIds,
12660
- });
12661
- }
12662
- async addColumns(columnIds) {
12663
- return this.executeQuery(addColumns, {
12664
- columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
12665
- });
12666
- }
12667
- async fetchData(offset = 0, size = 1000) {
12668
- const { answer } = await this.executeQuery(getAnswerData, {
12669
- deadline: 0,
12670
- dataPaginationParams: {
12671
- isClientPaginated: true,
12672
- offset,
12673
- size,
12674
- },
12675
- });
12676
- const { columns, data } = answer.visualizations.find((viz) => !!viz.data) || {};
12677
- return {
12678
- columns,
12679
- data,
12680
- };
12681
- }
12682
- /**
12683
- *
12684
- * @param userLocale
12685
- * @param includeInfo Include the CSV header in the output
12686
- * @returns Response
12687
- */
12688
- async fetchCSVBlob(userLocale = 'en-us', includeInfo = false) {
12689
- const fetchUrl = this.getFetchCSVBlobUrl(userLocale, includeInfo);
12690
- return tokenizedFetch(fetchUrl, {
12691
- credentials: 'include',
12692
- });
12693
- }
12694
- getFetchCSVBlobUrl(userLocale = 'en-us', includeInfo = false) {
12695
- return `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
12696
- }
12697
- /**
12698
- * Get underlying data given a point and the output column names.
12699
- *
12700
- * @param outputColumnNames
12701
- * @param selectedPoints
12702
- * @example
12703
- * ```js
12704
- * embed.on(EmbedEvent.CustomAction, e => {
12705
- * const underlying = await e.answerService.getUnderlyingDataForPoint([
12706
- * 'col name 1' // The column should exist in the data source.
12707
- * ]);
12708
- * const data = await underlying.fetchData(0, 100);
12709
- * })
12710
- * ```
12711
- * @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
12712
- */
12713
- async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
12714
- if (!selectedPoints && !this.selectedPoints) {
12715
- throw new Error('Needs to be triggered in context of a point');
12716
- }
12717
- if (!selectedPoints) {
12718
- selectedPoints = getSelectedPointsForUnderlyingDataQuery(this.selectedPoints);
12719
- }
12720
- const sourceDetail = await this.getSourceDetail();
12721
- const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
12722
- const unAggAnswer = await graphqlQuery({
12723
- query: getUnaggregatedAnswerSession,
12724
- variables: {
12725
- session: this.session,
12726
- columns: selectedPoints,
12727
- },
12728
- thoughtSpotHost: this.thoughtSpotHost,
12729
- });
12730
- const unaggAnswerSession = new AnswerService(unAggAnswer.id, unAggAnswer.answer, this.thoughtSpotHost);
12731
- const currentColumns = new Set(unAggAnswer.answer.visualizations[0].columns
12732
- .map((c) => c.column.referencedColumns[0].guid));
12733
- const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
12734
- if (columnsToAdd.length) {
12735
- await unaggAnswerSession.addColumns(columnsToAdd);
12736
- }
12737
- const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
12738
- if (columnsToRemove.length) {
12739
- await unaggAnswerSession.removeColumns(columnsToRemove);
12740
- }
12741
- return unaggAnswerSession;
12742
- }
12743
- async executeQuery(query, variables) {
12744
- const data = await graphqlQuery({
12745
- query,
12746
- variables: {
12747
- session: this.session,
12748
- ...variables,
12749
- },
12750
- thoughtSpotHost: this.thoughtSpotHost,
12751
- isCompositeQuery: false,
12752
- });
12753
- this.session = deepMerge(this.session, (data === null || data === void 0 ? void 0 : data.id) || {});
12754
- return data;
12755
- }
12756
- getSession() {
12757
- return this.session;
12758
- }
12759
- }
12760
- /**
12761
- *
12762
- * @param sourceDetail
12763
- * @param colNames
12764
- */
12765
- function getGuidsFromColumnNames(sourceDetail, colNames) {
12766
- const cols = sourceDetail.columns.reduce((colSet, col) => {
12767
- colSet[col.name] = col;
12768
- return colSet;
12769
- }, {});
12770
- return new Set(colNames.map((colName) => {
12771
- const col = cols[colName];
12772
- return col.id;
12773
- }));
12774
- }
12775
- /**
12776
- *
12777
- * @param selectedPoints
12778
- */
12779
- function getSelectedPointsForUnderlyingDataQuery(selectedPoints) {
12780
- const underlyingDataPoint = [];
12781
- /**
12782
- *
12783
- * @param colVal
12784
- */
12785
- function addPointFromColVal(colVal) {
12786
- var _a;
12787
- const dataType = colVal.column.dataType;
12788
- const id = colVal.column.id;
12789
- let dataValue;
12790
- if (dataType === 'DATE') {
12791
- if (Number.isFinite(colVal.value)) {
12792
- dataValue = [{
12793
- epochRange: {
12794
- startEpoch: colVal.value,
12795
- },
12796
- }];
12797
- // Case for custom calendar.
12798
- }
12799
- else if ((_a = colVal.value) === null || _a === void 0 ? void 0 : _a.v) {
12800
- dataValue = [{
12801
- epochRange: {
12802
- startEpoch: colVal.value.v.s,
12803
- endEpoch: colVal.value.v.e,
12804
- },
12805
- }];
12806
- }
12807
- }
12808
- else {
12809
- dataValue = [{ value: colVal.value }];
12810
- }
12811
- underlyingDataPoint.push({
12812
- columnId: colVal.column.id,
12813
- dataValue,
12814
- });
12815
- }
12816
- selectedPoints.forEach((p) => {
12817
- p.selectedAttributes.forEach(addPointFromColVal);
12818
- });
12819
- return underlyingDataPoint;
12820
- }
12821
-
12822
- var eventemitter3 = createCommonjsModule(function (module) {
12823
-
12824
- var has = Object.prototype.hasOwnProperty
12825
- , prefix = '~';
12826
-
12827
- /**
12828
- * Constructor to create a storage for our `EE` objects.
12829
- * An `Events` instance is a plain object whose properties are event names.
12830
- *
12831
- * @constructor
12832
- * @private
12833
- */
12834
- function Events() {}
12835
-
12836
- //
12837
- // We try to not inherit from `Object.prototype`. In some engines creating an
12838
- // instance in this way is faster than calling `Object.create(null)` directly.
12839
- // If `Object.create(null)` is not supported we prefix the event names with a
12840
- // character to make sure that the built-in object properties are not
12841
- // overridden or used as an attack vector.
12842
- //
12843
- if (Object.create) {
12844
- Events.prototype = Object.create(null);
12845
-
12846
- //
12847
- // This hack is needed because the `__proto__` property is still inherited in
12848
- // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
12849
- //
12850
- if (!new Events().__proto__) prefix = false;
12851
- }
12852
-
12853
- /**
12854
- * Representation of a single event listener.
12855
- *
12856
- * @param {Function} fn The listener function.
12857
- * @param {*} context The context to invoke the listener with.
12858
- * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
12859
- * @constructor
12860
- * @private
12861
- */
12862
- function EE(fn, context, once) {
12863
- this.fn = fn;
12864
- this.context = context;
12865
- this.once = once || false;
12866
- }
12867
-
12868
- /**
12869
- * Add a listener for a given event.
12870
- *
12871
- * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
12872
- * @param {(String|Symbol)} event The event name.
12873
- * @param {Function} fn The listener function.
12874
- * @param {*} context The context to invoke the listener with.
12875
- * @param {Boolean} once Specify if the listener is a one-time listener.
12876
- * @returns {EventEmitter}
12877
- * @private
12878
- */
12879
- function addListener(emitter, event, fn, context, once) {
12880
- if (typeof fn !== 'function') {
12881
- throw new TypeError('The listener must be a function');
12882
- }
12883
-
12884
- var listener = new EE(fn, context || emitter, once)
12885
- , evt = prefix ? prefix + event : event;
12886
-
12887
- if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
12888
- else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
12889
- else emitter._events[evt] = [emitter._events[evt], listener];
12890
-
12891
- return emitter;
12892
- }
12893
-
12894
- /**
12895
- * Clear event by name.
12896
- *
12897
- * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
12898
- * @param {(String|Symbol)} evt The Event name.
12899
- * @private
12900
- */
12901
- function clearEvent(emitter, evt) {
12902
- if (--emitter._eventsCount === 0) emitter._events = new Events();
12903
- else delete emitter._events[evt];
12904
- }
12905
-
12906
- /**
12907
- * Minimal `EventEmitter` interface that is molded against the Node.js
12908
- * `EventEmitter` interface.
12909
- *
12910
- * @constructor
12911
- * @public
12912
- */
12913
- function EventEmitter() {
12914
- this._events = new Events();
12915
- this._eventsCount = 0;
12916
- }
12917
-
12918
- /**
12919
- * Return an array listing the events for which the emitter has registered
12920
- * listeners.
12921
- *
12922
- * @returns {Array}
12923
- * @public
12924
- */
12925
- EventEmitter.prototype.eventNames = function eventNames() {
12926
- var names = []
12927
- , events
12928
- , name;
12929
-
12930
- if (this._eventsCount === 0) return names;
12931
-
12932
- for (name in (events = this._events)) {
12933
- if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
12934
- }
12935
-
12936
- if (Object.getOwnPropertySymbols) {
12937
- return names.concat(Object.getOwnPropertySymbols(events));
12938
- }
12939
-
12940
- return names;
12941
- };
12942
-
12943
- /**
12944
- * Return the listeners registered for a given event.
12945
- *
12946
- * @param {(String|Symbol)} event The event name.
12947
- * @returns {Array} The registered listeners.
12948
- * @public
12949
- */
12950
- EventEmitter.prototype.listeners = function listeners(event) {
12951
- var evt = prefix ? prefix + event : event
12952
- , handlers = this._events[evt];
12953
-
12954
- if (!handlers) return [];
12955
- if (handlers.fn) return [handlers.fn];
12956
-
12957
- for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
12958
- ee[i] = handlers[i].fn;
12959
- }
12960
-
12961
- return ee;
12962
- };
12963
-
12964
- /**
12965
- * Return the number of listeners listening to a given event.
12966
- *
12967
- * @param {(String|Symbol)} event The event name.
12968
- * @returns {Number} The number of listeners.
12969
- * @public
12970
- */
12971
- EventEmitter.prototype.listenerCount = function listenerCount(event) {
12972
- var evt = prefix ? prefix + event : event
12973
- , listeners = this._events[evt];
12606
+ /**
12607
+ * Return the number of listeners listening to a given event.
12608
+ *
12609
+ * @param {(String|Symbol)} event The event name.
12610
+ * @returns {Number} The number of listeners.
12611
+ * @public
12612
+ */
12613
+ EventEmitter.prototype.listenerCount = function listenerCount(event) {
12614
+ var evt = prefix ? prefix + event : event
12615
+ , listeners = this._events[evt];
12974
12616
 
12975
12617
  if (!listeners) return 0;
12976
12618
  if (listeners.fn) return 1;
@@ -13278,109 +12920,548 @@ var _arrayIncludesWith = arrayIncludesWith;
13278
12920
  /** Used as references for various `Number` constants. */
13279
12921
  var INFINITY = 1 / 0;
13280
12922
 
13281
- /**
13282
- * Creates a set object of `values`.
13283
- *
13284
- * @private
13285
- * @param {Array} values The values to add to the set.
13286
- * @returns {Object} Returns the new set.
13287
- */
13288
- var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) {
13289
- return new _Set(values);
12923
+ /**
12924
+ * Creates a set object of `values`.
12925
+ *
12926
+ * @private
12927
+ * @param {Array} values The values to add to the set.
12928
+ * @returns {Object} Returns the new set.
12929
+ */
12930
+ var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) {
12931
+ return new _Set(values);
12932
+ };
12933
+
12934
+ var _createSet = createSet;
12935
+
12936
+ /** Used as the size to enable large array optimizations. */
12937
+ var LARGE_ARRAY_SIZE$1 = 200;
12938
+
12939
+ /**
12940
+ * The base implementation of `_.uniqBy` without support for iteratee shorthands.
12941
+ *
12942
+ * @private
12943
+ * @param {Array} array The array to inspect.
12944
+ * @param {Function} [iteratee] The iteratee invoked per element.
12945
+ * @param {Function} [comparator] The comparator invoked per element.
12946
+ * @returns {Array} Returns the new duplicate free array.
12947
+ */
12948
+ function baseUniq(array, iteratee, comparator) {
12949
+ var index = -1,
12950
+ includes = _arrayIncludes,
12951
+ length = array.length,
12952
+ isCommon = true,
12953
+ result = [],
12954
+ seen = result;
12955
+
12956
+ if (comparator) {
12957
+ isCommon = false;
12958
+ includes = _arrayIncludesWith;
12959
+ }
12960
+ else if (length >= LARGE_ARRAY_SIZE$1) {
12961
+ var set = iteratee ? null : _createSet(array);
12962
+ if (set) {
12963
+ return _setToArray(set);
12964
+ }
12965
+ isCommon = false;
12966
+ includes = _cacheHas;
12967
+ seen = new _SetCache;
12968
+ }
12969
+ else {
12970
+ seen = iteratee ? [] : result;
12971
+ }
12972
+ outer:
12973
+ while (++index < length) {
12974
+ var value = array[index],
12975
+ computed = iteratee ? iteratee(value) : value;
12976
+
12977
+ value = (comparator || value !== 0) ? value : 0;
12978
+ if (isCommon && computed === computed) {
12979
+ var seenIndex = seen.length;
12980
+ while (seenIndex--) {
12981
+ if (seen[seenIndex] === computed) {
12982
+ continue outer;
12983
+ }
12984
+ }
12985
+ if (iteratee) {
12986
+ seen.push(computed);
12987
+ }
12988
+ result.push(value);
12989
+ }
12990
+ else if (!includes(seen, computed, comparator)) {
12991
+ if (seen !== result) {
12992
+ seen.push(computed);
12993
+ }
12994
+ result.push(value);
12995
+ }
12996
+ }
12997
+ return result;
12998
+ }
12999
+
13000
+ var _baseUniq = baseUniq;
13001
+
13002
+ /**
13003
+ * Creates a duplicate-free version of an array, using
13004
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
13005
+ * for equality comparisons, in which only the first occurrence of each element
13006
+ * is kept. The order of result values is determined by the order they occur
13007
+ * in the array.
13008
+ *
13009
+ * @static
13010
+ * @memberOf _
13011
+ * @since 0.1.0
13012
+ * @category Array
13013
+ * @param {Array} array The array to inspect.
13014
+ * @returns {Array} Returns the new duplicate free array.
13015
+ * @example
13016
+ *
13017
+ * _.uniq([2, 1, 2]);
13018
+ * // => [2, 1]
13019
+ */
13020
+ function uniq(array) {
13021
+ return (array && array.length) ? _baseUniq(array) : [];
13022
+ }
13023
+
13024
+ var uniq_1 = uniq;
13025
+
13026
+ /**
13027
+ *
13028
+ * @param url
13029
+ * @param options
13030
+ */
13031
+ function tokenisedFailureLoggedFetch(url, options = {}) {
13032
+ return tokenizedFetch(url, options).then(async (r) => {
13033
+ var _a;
13034
+ if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
13035
+ logger.error('Failure', await ((_a = r.text) === null || _a === void 0 ? void 0 : _a.call(r)));
13036
+ }
13037
+ return r;
13038
+ });
13039
+ }
13040
+ /**
13041
+ *
13042
+ * @param authVerificationUrl
13043
+ */
13044
+ function fetchSessionInfoService(authVerificationUrl) {
13045
+ return tokenisedFailureLoggedFetch(authVerificationUrl, {
13046
+ credentials: 'include',
13047
+ });
13048
+ }
13049
+ /**
13050
+ *
13051
+ * @param thoughtSpotHost
13052
+ */
13053
+ async function fetchLogoutService(thoughtSpotHost) {
13054
+ return tokenisedFailureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
13055
+ credentials: 'include',
13056
+ method: 'POST',
13057
+ headers: {
13058
+ 'x-requested-by': 'ThoughtSpot',
13059
+ },
13060
+ });
13061
+ }
13062
+
13063
+ // eslint-disable-next-line import/no-mutable-exports
13064
+ let loggedInStatus = false;
13065
+ // eslint-disable-next-line import/no-mutable-exports
13066
+ let samlAuthWindow = null;
13067
+ // eslint-disable-next-line import/no-mutable-exports
13068
+ let samlCompletionPromise = null;
13069
+ let sessionInfo = null;
13070
+ let sessionInfoResolver = null;
13071
+ const sessionInfoPromise = new Promise((resolve) => {
13072
+ sessionInfoResolver = resolve;
13073
+ });
13074
+ let releaseVersion = '';
13075
+ const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
13076
+ /**
13077
+ * Enum for auth failure types. This is the parameter passed to the listner
13078
+ * of {@link AuthStatus.FAILURE}.
13079
+ *
13080
+ * @group Authentication / Init
13081
+ */
13082
+ var AuthFailureType;
13083
+ (function (AuthFailureType) {
13084
+ AuthFailureType["SDK"] = "SDK";
13085
+ AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
13086
+ AuthFailureType["EXPIRY"] = "EXPIRY";
13087
+ AuthFailureType["OTHER"] = "OTHER";
13088
+ })(AuthFailureType || (AuthFailureType = {}));
13089
+ /**
13090
+ * Enum for auth status emitted by the emitter returned from {@link init}.
13091
+ *
13092
+ * @group Authentication / Init
13093
+ */
13094
+ var AuthStatus;
13095
+ (function (AuthStatus) {
13096
+ /**
13097
+ * Emits when the SDK fails to authenticate
13098
+ */
13099
+ AuthStatus["FAILURE"] = "FAILURE";
13100
+ /**
13101
+ * Emits when the SDK authenticates successfully
13102
+ */
13103
+ AuthStatus["SDK_SUCCESS"] = "SDK_SUCCESS";
13104
+ /**
13105
+ * Emits when the app sends an authentication success message
13106
+ */
13107
+ AuthStatus["SUCCESS"] = "SUCCESS";
13108
+ /**
13109
+ * Emits when a user logs out
13110
+ */
13111
+ AuthStatus["LOGOUT"] = "LOGOUT";
13112
+ /**
13113
+ * Emitted when inPopup is true in the SAMLRedirect flow and the
13114
+ * popup is waiting to be triggered either programmatically
13115
+ * or by the trigger button.
13116
+ *
13117
+ * @version SDK: 1.19.0
13118
+ */
13119
+ AuthStatus["WAITING_FOR_POPUP"] = "WAITING_FOR_POPUP";
13120
+ })(AuthStatus || (AuthStatus = {}));
13121
+ /**
13122
+ * Events which can be triggered on the emitter returned from {@link init}.
13123
+ *
13124
+ * @group Authentication / Init
13125
+ */
13126
+ var AuthEvent;
13127
+ (function (AuthEvent) {
13128
+ /**
13129
+ * Manually trigger the SSO popup. This is useful when
13130
+ * authStatus is SAMLRedirect/OIDCRedirect and inPopup is set to true
13131
+ */
13132
+ AuthEvent["TRIGGER_SSO_POPUP"] = "TRIGGER_SSO_POPUP";
13133
+ })(AuthEvent || (AuthEvent = {}));
13134
+ let authEE;
13135
+ /**
13136
+ *
13137
+ * @param eventEmitter
13138
+ */
13139
+ function setAuthEE(eventEmitter) {
13140
+ authEE = eventEmitter;
13141
+ }
13142
+ /**
13143
+ *
13144
+ */
13145
+ function notifyAuthSDKSuccess() {
13146
+ if (!authEE) {
13147
+ logger.error('SDK not initialized');
13148
+ return;
13149
+ }
13150
+ authEE.emit(AuthStatus.SDK_SUCCESS);
13151
+ }
13152
+ /**
13153
+ *
13154
+ */
13155
+ function notifyAuthSuccess() {
13156
+ if (!authEE) {
13157
+ logger.error('SDK not initialized');
13158
+ return;
13159
+ }
13160
+ authEE.emit(AuthStatus.SUCCESS, sessionInfo);
13161
+ }
13162
+ /**
13163
+ *
13164
+ * @param failureType
13165
+ */
13166
+ function notifyAuthFailure(failureType) {
13167
+ if (!authEE) {
13168
+ logger.error('SDK not initialized');
13169
+ return;
13170
+ }
13171
+ authEE.emit(AuthStatus.FAILURE, failureType);
13172
+ }
13173
+ /**
13174
+ *
13175
+ */
13176
+ function notifyLogout() {
13177
+ if (!authEE) {
13178
+ logger.error('SDK not initialized');
13179
+ return;
13180
+ }
13181
+ authEE.emit(AuthStatus.LOGOUT);
13182
+ }
13183
+ const initSession = (sessionDetails) => {
13184
+ if (sessionInfo == null) {
13185
+ sessionInfo = sessionDetails;
13186
+ initMixpanel(sessionInfo);
13187
+ sessionInfoResolver(sessionInfo);
13188
+ }
13189
+ };
13190
+ const getSessionDetails = (sessionInfoResp) => {
13191
+ const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
13192
+ const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
13193
+ const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
13194
+ ? prodMixpanelToken
13195
+ : devMixpanelToken;
13196
+ return {
13197
+ userGUID: sessionInfoResp.userGUID,
13198
+ mixpanelToken,
13199
+ isPublicUser: sessionInfoResp.configInfo.isPublicUser,
13200
+ releaseVersion: sessionInfoResp.releaseVersion,
13201
+ clusterId: sessionInfoResp.configInfo.selfClusterId,
13202
+ clusterName: sessionInfoResp.configInfo.selfClusterName,
13203
+ ...sessionInfoResp,
13204
+ };
13205
+ };
13206
+ /**
13207
+ * Check if we are logged into the ThoughtSpot cluster
13208
+ *
13209
+ * @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
13210
+ */
13211
+ async function isLoggedIn(thoughtSpotHost) {
13212
+ const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
13213
+ let response = null;
13214
+ try {
13215
+ response = await fetchSessionInfoService(authVerificationUrl);
13216
+ const sessionInfoResp = await response.json();
13217
+ const sessionDetails = getSessionDetails(sessionInfoResp);
13218
+ // Store user session details from session info
13219
+ initSession(sessionDetails);
13220
+ releaseVersion = sessionInfoResp.releaseVersion;
13221
+ }
13222
+ catch (e) {
13223
+ return false;
13224
+ }
13225
+ return response.status === 200;
13226
+ }
13227
+ /**
13228
+ * Return releaseVersion if available
13229
+ */
13230
+ function getReleaseVersion() {
13231
+ return releaseVersion;
13232
+ }
13233
+ /**
13234
+ * Return a promise that resolves with the session information when
13235
+ * authentication is successful. And info is available.
13236
+ *
13237
+ * @group Global methods
13238
+ */
13239
+ function getSessionInfo() {
13240
+ return sessionInfoPromise;
13241
+ }
13242
+ /**
13243
+ * Check if we are stuck at the SSO redirect URL
13244
+ */
13245
+ function isAtSSORedirectUrl() {
13246
+ return window.location.href.indexOf(SSO_REDIRECTION_MARKER_GUID) >= 0;
13247
+ }
13248
+ /**
13249
+ * Remove the SSO redirect URL marker
13250
+ */
13251
+ function removeSSORedirectUrlMarker() {
13252
+ // Note (sunny): This will leave a # around even if it was not in the URL
13253
+ // to begin with. Trying to remove the hash by changing window.location will
13254
+ // reload the page which we don't want. We'll live with adding an
13255
+ // unnecessary hash to the parent page URL until we find any use case where
13256
+ // that creates an issue.
13257
+ window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
13258
+ }
13259
+ /**
13260
+ * Perform token based authentication
13261
+ *
13262
+ * @param embedConfig The embed configuration
13263
+ */
13264
+ const doTokenAuth = async (embedConfig) => {
13265
+ const { thoughtSpotHost, username, authEndpoint, getAuthToken, } = embedConfig;
13266
+ if (!authEndpoint && !getAuthToken) {
13267
+ throw new Error('Either auth endpoint or getAuthToken function must be provided');
13268
+ }
13269
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
13270
+ if (!loggedInStatus) {
13271
+ const authToken = await getAuthenticationToken(embedConfig);
13272
+ let resp;
13273
+ try {
13274
+ resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
13275
+ }
13276
+ catch (e) {
13277
+ resp = await fetchAuthService(thoughtSpotHost, username, authToken);
13278
+ }
13279
+ // token login issues a 302 when successful
13280
+ loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
13281
+ if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
13282
+ // When 3rd party cookie access is blocked, this will fail because
13283
+ // cookies will not be sent with the call.
13284
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
13285
+ }
13286
+ }
13287
+ return loggedInStatus;
13288
+ };
13289
+ /**
13290
+ * Validate embedConfig parameters required for cookielessTokenAuth
13291
+ *
13292
+ * @param embedConfig The embed configuration
13293
+ */
13294
+ const doCookielessTokenAuth = async (embedConfig) => {
13295
+ const { authEndpoint, getAuthToken } = embedConfig;
13296
+ if (!authEndpoint && !getAuthToken) {
13297
+ throw new Error('Either auth endpoint or getAuthToken function must be provided');
13298
+ }
13299
+ let authSuccess = false;
13300
+ try {
13301
+ const authToken = await getAuthenticationToken(embedConfig);
13302
+ if (authToken) {
13303
+ authSuccess = true;
13304
+ }
13305
+ }
13306
+ catch {
13307
+ authSuccess = false;
13308
+ }
13309
+ return authSuccess;
13310
+ };
13311
+ /**
13312
+ * Perform basic authentication to the ThoughtSpot cluster using the cluster
13313
+ * credentials.
13314
+ *
13315
+ * Warning: This feature is primarily intended for developer testing. It is
13316
+ * strongly advised not to use this authentication method in production.
13317
+ *
13318
+ * @param embedConfig The embed configuration
13319
+ */
13320
+ const doBasicAuth = async (embedConfig) => {
13321
+ const { thoughtSpotHost, username, password } = embedConfig;
13322
+ const loggedIn = await isLoggedIn(thoughtSpotHost);
13323
+ if (!loggedIn) {
13324
+ const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
13325
+ loggedInStatus = response.ok;
13326
+ if (embedConfig.detectCookieAccessSlow) {
13327
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
13328
+ }
13329
+ }
13330
+ else {
13331
+ loggedInStatus = true;
13332
+ }
13333
+ return loggedInStatus;
13334
+ };
13335
+ /**
13336
+ *
13337
+ * @param ssoURL
13338
+ * @param triggerContainer
13339
+ * @param triggerText
13340
+ */
13341
+ async function samlPopupFlow(ssoURL, triggerContainer, triggerText) {
13342
+ const openPopup = () => {
13343
+ if (samlAuthWindow === null || samlAuthWindow.closed) {
13344
+ samlAuthWindow = window.open(ssoURL, '_blank', 'location=no,height=570,width=520,scrollbars=yes,status=yes');
13345
+ }
13346
+ else {
13347
+ samlAuthWindow.focus();
13348
+ }
13349
+ };
13350
+ authEE === null || authEE === void 0 ? void 0 : authEE.emit(AuthStatus.WAITING_FOR_POPUP);
13351
+ const containerEl = getDOMNode(triggerContainer);
13352
+ if (containerEl) {
13353
+ containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
13354
+ const authElem = document.getElementById('ts-auth-btn');
13355
+ authElem.textContent = triggerText;
13356
+ authElem.addEventListener('click', openPopup, { once: true });
13357
+ }
13358
+ samlCompletionPromise = samlCompletionPromise
13359
+ || new Promise((resolve, reject) => {
13360
+ window.addEventListener('message', (e) => {
13361
+ if (e.data.type === EmbedEvent.SAMLComplete) {
13362
+ e.source.close();
13363
+ resolve();
13364
+ }
13365
+ });
13366
+ });
13367
+ authEE === null || authEE === void 0 ? void 0 : authEE.once(AuthEvent.TRIGGER_SSO_POPUP, openPopup);
13368
+ return samlCompletionPromise;
13369
+ }
13370
+ /**
13371
+ * Perform SAML authentication
13372
+ *
13373
+ * @param embedConfig The embed configuration
13374
+ * @param ssoEndPoint
13375
+ */
13376
+ const doSSOAuth = async (embedConfig, ssoEndPoint) => {
13377
+ const { thoughtSpotHost } = embedConfig;
13378
+ const loggedIn = await isLoggedIn(thoughtSpotHost);
13379
+ if (loggedIn) {
13380
+ if (isAtSSORedirectUrl()) {
13381
+ removeSSORedirectUrlMarker();
13382
+ }
13383
+ loggedInStatus = true;
13384
+ return;
13385
+ }
13386
+ // we have already tried authentication and it did not succeed, restore
13387
+ // the current URL to the original one and invoke the callback.
13388
+ if (isAtSSORedirectUrl()) {
13389
+ removeSSORedirectUrlMarker();
13390
+ loggedInStatus = false;
13391
+ return;
13392
+ }
13393
+ const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
13394
+ if (embedConfig.inPopup) {
13395
+ await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
13396
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
13397
+ return;
13398
+ }
13399
+ window.location.href = ssoURL;
13400
+ };
13401
+ const doSamlAuth = async (embedConfig) => {
13402
+ const { thoughtSpotHost } = embedConfig;
13403
+ // redirect for SSO, when the SSO authentication is done, this page will be
13404
+ // loaded again and the same JS will execute again.
13405
+ const ssoRedirectUrl = embedConfig.inPopup
13406
+ ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
13407
+ : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
13408
+ // bring back the page to the same URL
13409
+ const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
13410
+ await doSSOAuth(embedConfig, ssoEndPoint);
13411
+ return loggedInStatus;
13412
+ };
13413
+ const doOIDCAuth = async (embedConfig) => {
13414
+ const { thoughtSpotHost } = embedConfig;
13415
+ // redirect for SSO, when the SSO authentication is done, this page will be
13416
+ // loaded again and the same JS will execute again.
13417
+ const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
13418
+ ? `${thoughtSpotHost}/v2/#/embed/saml-complete`
13419
+ : getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
13420
+ // bring back the page to the same URL
13421
+ const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
13422
+ await doSSOAuth(embedConfig, ssoEndPoint);
13423
+ return loggedInStatus;
13424
+ };
13425
+ const logout = async (embedConfig) => {
13426
+ const { thoughtSpotHost } = embedConfig;
13427
+ await fetchLogoutService(thoughtSpotHost);
13428
+ resetCachedAuthToken();
13429
+ const thoughtspotIframes = document.querySelectorAll('[data-ts-iframe=\'true\']');
13430
+ if (thoughtspotIframes === null || thoughtspotIframes === void 0 ? void 0 : thoughtspotIframes.length) {
13431
+ thoughtspotIframes.forEach((el) => {
13432
+ el.parentElement.innerHTML = embedConfig.loginFailedMessage;
13433
+ });
13434
+ }
13435
+ loggedInStatus = false;
13436
+ return loggedInStatus;
13437
+ };
13438
+ /**
13439
+ * Perform authentication on the ThoughtSpot cluster
13440
+ *
13441
+ * @param embedConfig The embed configuration
13442
+ */
13443
+ const authenticate = async (embedConfig) => {
13444
+ const { authType } = embedConfig;
13445
+ switch (authType) {
13446
+ case AuthType.SSO:
13447
+ case AuthType.SAMLRedirect:
13448
+ case AuthType.SAML:
13449
+ return doSamlAuth(embedConfig);
13450
+ case AuthType.OIDC:
13451
+ case AuthType.OIDCRedirect:
13452
+ return doOIDCAuth(embedConfig);
13453
+ case AuthType.AuthServer:
13454
+ case AuthType.TrustedAuthToken:
13455
+ return doTokenAuth(embedConfig);
13456
+ case AuthType.TrustedAuthTokenCookieless:
13457
+ return doCookielessTokenAuth(embedConfig);
13458
+ case AuthType.Basic:
13459
+ return doBasicAuth(embedConfig);
13460
+ default:
13461
+ return Promise.resolve(true);
13462
+ }
13290
13463
  };
13291
13464
 
13292
- var _createSet = createSet;
13293
-
13294
- /** Used as the size to enable large array optimizations. */
13295
- var LARGE_ARRAY_SIZE$1 = 200;
13296
-
13297
- /**
13298
- * The base implementation of `_.uniqBy` without support for iteratee shorthands.
13299
- *
13300
- * @private
13301
- * @param {Array} array The array to inspect.
13302
- * @param {Function} [iteratee] The iteratee invoked per element.
13303
- * @param {Function} [comparator] The comparator invoked per element.
13304
- * @returns {Array} Returns the new duplicate free array.
13305
- */
13306
- function baseUniq(array, iteratee, comparator) {
13307
- var index = -1,
13308
- includes = _arrayIncludes,
13309
- length = array.length,
13310
- isCommon = true,
13311
- result = [],
13312
- seen = result;
13313
-
13314
- if (comparator) {
13315
- isCommon = false;
13316
- includes = _arrayIncludesWith;
13317
- }
13318
- else if (length >= LARGE_ARRAY_SIZE$1) {
13319
- var set = iteratee ? null : _createSet(array);
13320
- if (set) {
13321
- return _setToArray(set);
13322
- }
13323
- isCommon = false;
13324
- includes = _cacheHas;
13325
- seen = new _SetCache;
13326
- }
13327
- else {
13328
- seen = iteratee ? [] : result;
13329
- }
13330
- outer:
13331
- while (++index < length) {
13332
- var value = array[index],
13333
- computed = iteratee ? iteratee(value) : value;
13334
-
13335
- value = (comparator || value !== 0) ? value : 0;
13336
- if (isCommon && computed === computed) {
13337
- var seenIndex = seen.length;
13338
- while (seenIndex--) {
13339
- if (seen[seenIndex] === computed) {
13340
- continue outer;
13341
- }
13342
- }
13343
- if (iteratee) {
13344
- seen.push(computed);
13345
- }
13346
- result.push(value);
13347
- }
13348
- else if (!includes(seen, computed, comparator)) {
13349
- if (seen !== result) {
13350
- seen.push(computed);
13351
- }
13352
- result.push(value);
13353
- }
13354
- }
13355
- return result;
13356
- }
13357
-
13358
- var _baseUniq = baseUniq;
13359
-
13360
- /**
13361
- * Creates a duplicate-free version of an array, using
13362
- * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
13363
- * for equality comparisons, in which only the first occurrence of each element
13364
- * is kept. The order of result values is determined by the order they occur
13365
- * in the array.
13366
- *
13367
- * @static
13368
- * @memberOf _
13369
- * @since 0.1.0
13370
- * @category Array
13371
- * @param {Array} array The array to inspect.
13372
- * @returns {Array} Returns the new duplicate free array.
13373
- * @example
13374
- *
13375
- * _.uniq([2, 1, 2]);
13376
- * // => [2, 1]
13377
- */
13378
- function uniq(array) {
13379
- return (array && array.length) ? _baseUniq(array) : [];
13380
- }
13381
-
13382
- var uniq_1 = uniq;
13383
-
13384
13465
  /* eslint-disable camelcase */
13385
13466
  const CONFIG_DEFAULTS = {
13386
13467
  loginFailedMessage: 'Not logged in',
@@ -13841,6 +13922,8 @@ function processTrigger(iFrame, messageType, thoughtSpotHost, data) {
13841
13922
  });
13842
13923
  }
13843
13924
 
13925
+ var name="@thoughtspot/visual-embed-sdk";var version="1.28.0-alpha.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":"^46.9.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};
13926
+
13844
13927
  /**
13845
13928
  * Copyright (c) 2022
13846
13929
  *
@@ -15345,7 +15428,7 @@ class SearchEmbed extends TsEmbed {
15345
15428
  }
15346
15429
  getEmbedParams() {
15347
15430
  var _a;
15348
- const { hideResults, expandAllDataSource, enableSearchAssist, forceTable, searchOptions, runtimeFilters, dataSource, dataSources, excludeRuntimeFiltersfromURL, hideSearchBar, dataPanelV2 = false, useLastSelectedSources = false, runtimeParameters, } = this.viewConfig;
15431
+ const { hideResults, enableSearchAssist, forceTable, searchOptions, runtimeFilters, dataSource, dataSources, excludeRuntimeFiltersfromURL, hideSearchBar, dataPanelV2 = false, useLastSelectedSources = false, runtimeParameters, } = this.viewConfig;
15349
15432
  const queryParams = this.getBaseQueryParams();
15350
15433
  queryParams[Param.HideActions] = [
15351
15434
  ...((_a = queryParams[Param.HideActions]) !== null && _a !== void 0 ? _a : []),
@@ -15495,16 +15578,6 @@ class SearchBarEmbed extends TsEmbed {
15495
15578
  * @summary TS Sage embed
15496
15579
  * @author Mourya Balabhadra <mourya.balabhadra@thoughtspot.com>
15497
15580
  */
15498
- const HiddenActionItemByDefaultForSageEmbed = [
15499
- Action.Save,
15500
- Action.Pin,
15501
- Action.EditACopy,
15502
- Action.SaveAsView,
15503
- Action.UpdateTML,
15504
- Action.EditTML,
15505
- Action.AnswerDelete,
15506
- Action.Share,
15507
- ];
15508
15581
  /**
15509
15582
  * Embed ThoughtSpot LLM and GPT-based Natural Language Search component.
15510
15583
  *
@@ -15524,7 +15597,6 @@ class SageEmbed extends V1Embed {
15524
15597
  * @returns {string} query string
15525
15598
  */
15526
15599
  getEmbedParams() {
15527
- var _a;
15528
15600
  const { disableWorksheetChange, hideWorksheetSelector, showObjectSuggestions, hideSampleQuestions, isProductTour, hideSearchBarTitle, hideSageAnswerHeader, hideAutocompleteSuggestions, } = this.viewConfig;
15529
15601
  const params = this.getBaseQueryParams();
15530
15602
  params[Param.EmbedApp] = true;
@@ -15540,10 +15612,6 @@ class SageEmbed extends V1Embed {
15540
15612
  params[Param.IsProductTour] = !!isProductTour;
15541
15613
  params[Param.HideSearchBarTitle] = !!hideSearchBarTitle;
15542
15614
  params[Param.HideSageAnswerHeader] = !!hideSageAnswerHeader;
15543
- params[Param.HideActions] = [
15544
- ...((_a = params[Param.HideActions]) !== null && _a !== void 0 ? _a : []),
15545
- ...HiddenActionItemByDefaultForSageEmbed,
15546
- ];
15547
15615
  return getQueryParamString(params, true);
15548
15616
  }
15549
15617
  /**
@@ -15584,4 +15652,4 @@ class SageEmbed extends V1Embed {
15584
15652
  }
15585
15653
  }
15586
15654
 
15587
- export { Action, AnswerService, AppEmbed, AuthEvent, AuthFailureType, AuthStatus, AuthType, ContextMenuTriggerOptions, DataSourceVisualMode, EmbedEvent, HomeLeftNavItem, HomepageModule, HostEvent, LiveboardEmbed, LogLevel, Page, PinboardEmbed, PrefetchFeatures, RuntimeFilterOp, SageEmbed, SearchBarEmbed, SearchEmbed, executeTML, exportTML, getEmbedConfig as getInitConfig, getSessionInfo, init, logout$1 as logout, prefetch };
15655
+ export { Action, AnswerService, AppEmbed, AuthEvent, AuthFailureType, AuthStatus, AuthType, ContextMenuTriggerOptions, DataSourceVisualMode, EmbedEvent, HomeLeftNavItem, HomepageModule, HostEvent, LiveboardEmbed, LogLevel, MIXPANEL_EVENT, Page, PinboardEmbed, PrefetchFeatures, RuntimeFilterOp, SageEmbed, SearchBarEmbed, SearchEmbed, executeTML, exportTML, getEmbedConfig as getInitConfig, getSessionInfo, init, logout$1 as logout, prefetch, uploadMixpanelEvent };