@thoughtspot/visual-embed-sdk 1.27.8 → 1.28.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/cjs/package.json +1 -1
- package/cjs/src/auth.d.ts.map +1 -1
- package/cjs/src/auth.js +2 -2
- package/cjs/src/auth.js.map +1 -1
- package/cjs/src/embed/base.d.ts +1 -1
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +5 -5
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/base.spec.js +1 -1
- package/cjs/src/embed/base.spec.js.map +1 -1
- package/cjs/src/embed/search.d.ts +1 -5
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +4 -4
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +1 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +6 -6
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +8 -14
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +4 -3
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +4 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts +1 -0
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +1 -0
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/index.spec.js +0 -12
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +6 -2
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +3 -2
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.d.ts +56 -2
- package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.js +55 -0
- package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
- package/dist/src/auth.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +1 -1
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +1 -5
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +1 -1
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +1 -0
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/types.d.ts +6 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/answerService/answerService.d.ts +56 -2
- package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +2267 -2210
- package/dist/tsembed-react.js +6915 -6858
- package/dist/tsembed.es.js +2741 -2684
- package/dist/tsembed.js +2039 -1980
- package/dist/visual-embed-sdk-react-full.d.ts +94 -9
- package/dist/visual-embed-sdk-react.d.ts +94 -9
- package/dist/visual-embed-sdk.d.ts +94 -9
- package/lib/package.json +1 -1
- package/lib/src/auth.d.ts.map +1 -1
- package/lib/src/auth.js +3 -3
- package/lib/src/auth.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -1
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +5 -5
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +2 -2
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/search.d.ts +1 -5
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +5 -5
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +1 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +9 -9
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +8 -14
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +4 -3
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +1 -0
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +1 -0
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/react/index.spec.js +0 -12
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +6 -2
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +3 -2
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService/authService.spec.js +1 -1
- package/lib/src/utils/authService/authService.spec.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.d.ts +56 -2
- package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.js +55 -0
- package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +102 -14
- package/package.json +1 -1
- package/src/auth.ts +6 -6
- package/src/embed/base.spec.ts +3 -3
- package/src/embed/base.ts +12 -12
- package/src/embed/search.ts +6 -11
- package/src/embed/ts-embed.spec.ts +19 -25
- package/src/embed/ts-embed.ts +37 -34
- package/src/index.ts +10 -1
- package/src/mixpanel-service.ts +1 -0
- package/src/react/all-types-export.ts +1 -0
- package/src/react/index.spec.tsx +0 -29
- package/src/types.ts +16 -13
- package/src/utils/authService/authService.spec.ts +4 -4
- package/src/utils/graphql/answerService/answerService.ts +56 -1
package/dist/tsembed.js
CHANGED
|
@@ -443,7 +443,8 @@
|
|
|
443
443
|
* A custom action has been triggered.
|
|
444
444
|
*
|
|
445
445
|
* @returns actionId - ID of the custom action
|
|
446
|
-
* @returns
|
|
446
|
+
* @returns payload {@link CustomActionPayload} - Response payload with the
|
|
447
|
+
* Answer or Liveboard data
|
|
447
448
|
* @example
|
|
448
449
|
* ```js
|
|
449
450
|
* appEmbed.on(EmbedEvent.customAction, payload => {
|
|
@@ -463,7 +464,7 @@
|
|
|
463
464
|
* @example
|
|
464
465
|
* ```js
|
|
465
466
|
* livebaordEmbed.on(EmbedEvent.VizPointDoubleClick, payload => {
|
|
466
|
-
* console.log('VizPointDoubleClick', payload)
|
|
467
|
+
* console.log('VizPointDoubleClick', payload);
|
|
467
468
|
* })
|
|
468
469
|
* ```
|
|
469
470
|
*/
|
|
@@ -5571,8 +5572,6 @@
|
|
|
5571
5572
|
|
|
5572
5573
|
var isEqual_1 = isEqual;
|
|
5573
5574
|
|
|
5574
|
-
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$1={".":{"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$1,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};
|
|
5575
|
-
|
|
5576
5575
|
const EndPoints = {
|
|
5577
5576
|
AUTH_VERIFICATION: '/callosum/v1/session/info',
|
|
5578
5577
|
SAML_LOGIN_TEMPLATE: (targetUrl) => `/callosum/v1/saml/login?targetURLPath=${targetUrl}`,
|
|
@@ -5735,535 +5734,1079 @@
|
|
|
5735
5734
|
cachedAuthToken = null;
|
|
5736
5735
|
};
|
|
5737
5736
|
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
} else {
|
|
5759
|
-
window$1 = window;
|
|
5760
|
-
}
|
|
5761
|
-
|
|
5762
|
-
/*
|
|
5763
|
-
* Saved references to long variable names, so that closure compiler can
|
|
5764
|
-
* minimize file size.
|
|
5765
|
-
*/
|
|
5766
|
-
|
|
5767
|
-
var ArrayProto = Array.prototype;
|
|
5768
|
-
var FuncProto = Function.prototype;
|
|
5769
|
-
var ObjProto = Object.prototype;
|
|
5770
|
-
var slice = ArrayProto.slice;
|
|
5771
|
-
var toString = ObjProto.toString;
|
|
5772
|
-
var hasOwnProperty$9 = ObjProto.hasOwnProperty;
|
|
5773
|
-
var windowConsole = window$1.console;
|
|
5774
|
-
var navigator = window$1.navigator;
|
|
5775
|
-
var document$1 = window$1.document;
|
|
5776
|
-
var windowOpera = window$1.opera;
|
|
5777
|
-
var screen = window$1.screen;
|
|
5778
|
-
var userAgent = navigator.userAgent;
|
|
5779
|
-
var nativeBind = FuncProto.bind;
|
|
5780
|
-
var nativeForEach = ArrayProto.forEach;
|
|
5781
|
-
var nativeIndexOf = ArrayProto.indexOf;
|
|
5782
|
-
var nativeMap = ArrayProto.map;
|
|
5783
|
-
var nativeIsArray = Array.isArray;
|
|
5784
|
-
var breaker = {};
|
|
5785
|
-
var _ = {
|
|
5786
|
-
trim: function(str) {
|
|
5787
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
|
|
5788
|
-
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
|
5789
|
-
}
|
|
5737
|
+
let config = {};
|
|
5738
|
+
/**
|
|
5739
|
+
* Gets the configuration embed was initialized with.
|
|
5740
|
+
*
|
|
5741
|
+
* @returns {@link EmbedConfig} The configuration embed was initialized with.
|
|
5742
|
+
* @version SDK: 1.19.0 | ThoughtSpot: *
|
|
5743
|
+
* @group Global methods
|
|
5744
|
+
*/
|
|
5745
|
+
const getEmbedConfig = () => config;
|
|
5746
|
+
/**
|
|
5747
|
+
* Sets the configuration embed was initialized with.
|
|
5748
|
+
* And returns the new configuration.
|
|
5749
|
+
*
|
|
5750
|
+
* @param newConfig The configuration to set.
|
|
5751
|
+
* @version SDK: 1.27.0 | ThoughtSpot: *
|
|
5752
|
+
* @group Global methods
|
|
5753
|
+
*/
|
|
5754
|
+
const setEmbedConfig = (newConfig) => {
|
|
5755
|
+
config = newConfig;
|
|
5756
|
+
return newConfig;
|
|
5790
5757
|
};
|
|
5791
5758
|
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
}
|
|
5804
|
-
}
|
|
5805
|
-
},
|
|
5806
|
-
/** @type {function(...*)} */
|
|
5807
|
-
warn: function() {
|
|
5808
|
-
if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
|
|
5809
|
-
var args = ['Mixpanel warning:'].concat(_.toArray(arguments));
|
|
5810
|
-
try {
|
|
5811
|
-
windowConsole.warn.apply(windowConsole, args);
|
|
5812
|
-
} catch (err) {
|
|
5813
|
-
_.each(args, function(arg) {
|
|
5814
|
-
windowConsole.warn(arg);
|
|
5815
|
-
});
|
|
5816
|
-
}
|
|
5817
|
-
}
|
|
5818
|
-
},
|
|
5819
|
-
/** @type {function(...*)} */
|
|
5820
|
-
error: function() {
|
|
5821
|
-
if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
|
|
5822
|
-
var args = ['Mixpanel error:'].concat(_.toArray(arguments));
|
|
5823
|
-
try {
|
|
5824
|
-
windowConsole.error.apply(windowConsole, args);
|
|
5825
|
-
} catch (err) {
|
|
5826
|
-
_.each(args, function(arg) {
|
|
5827
|
-
windowConsole.error(arg);
|
|
5828
|
-
});
|
|
5829
|
-
}
|
|
5830
|
-
}
|
|
5831
|
-
},
|
|
5832
|
-
/** @type {function(...*)} */
|
|
5833
|
-
critical: function() {
|
|
5834
|
-
if (!_.isUndefined(windowConsole) && windowConsole) {
|
|
5835
|
-
var args = ['Mixpanel error:'].concat(_.toArray(arguments));
|
|
5836
|
-
try {
|
|
5837
|
-
windowConsole.error.apply(windowConsole, args);
|
|
5838
|
-
} catch (err) {
|
|
5839
|
-
_.each(args, function(arg) {
|
|
5840
|
-
windowConsole.error(arg);
|
|
5841
|
-
});
|
|
5842
|
-
}
|
|
5843
|
-
}
|
|
5844
|
-
}
|
|
5759
|
+
const tokenizedFetch = async (input, init) => {
|
|
5760
|
+
const embedConfig = getEmbedConfig();
|
|
5761
|
+
if (embedConfig.authType !== exports.AuthType.TrustedAuthTokenCookieless) {
|
|
5762
|
+
return fetch(input, init);
|
|
5763
|
+
}
|
|
5764
|
+
const req = new Request(input, init);
|
|
5765
|
+
const authToken = await getAuthenticationToken(embedConfig);
|
|
5766
|
+
if (authToken) {
|
|
5767
|
+
req.headers.append('Authorization', `Bearer ${authToken}`);
|
|
5768
|
+
}
|
|
5769
|
+
return fetch(req);
|
|
5845
5770
|
};
|
|
5846
5771
|
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5772
|
+
/**
|
|
5773
|
+
*
|
|
5774
|
+
* @param root0
|
|
5775
|
+
* @param root0.query
|
|
5776
|
+
* @param root0.variables
|
|
5777
|
+
* @param root0.thoughtSpotHost
|
|
5778
|
+
* @param root0.isCompositeQuery
|
|
5779
|
+
*/
|
|
5780
|
+
async function graphqlQuery({ query, variables, thoughtSpotHost, isCompositeQuery = false, }) {
|
|
5781
|
+
const operationName = getOperationNameFromQuery(query);
|
|
5782
|
+
try {
|
|
5783
|
+
const response = await fetch(`${thoughtSpotHost}/prism/?op=${operationName}`, {
|
|
5784
|
+
method: 'POST',
|
|
5785
|
+
headers: {
|
|
5786
|
+
'content-type': 'application/json;charset=UTF-8',
|
|
5787
|
+
'x-requested-by': 'ThoughtSpot',
|
|
5788
|
+
accept: '*/*',
|
|
5789
|
+
'accept-language': 'en-us',
|
|
5790
|
+
},
|
|
5791
|
+
body: JSON.stringify({
|
|
5792
|
+
operationName,
|
|
5793
|
+
query,
|
|
5794
|
+
variables,
|
|
5795
|
+
}),
|
|
5796
|
+
credentials: 'include',
|
|
5797
|
+
});
|
|
5798
|
+
const result = await response.json();
|
|
5799
|
+
const dataValues = Object.values(result.data);
|
|
5800
|
+
return (isCompositeQuery) ? result.data : dataValues[0];
|
|
5801
|
+
}
|
|
5802
|
+
catch (error) {
|
|
5803
|
+
return error;
|
|
5804
|
+
}
|
|
5805
|
+
}
|
|
5860
5806
|
|
|
5807
|
+
const getSourceDetailQuery = `
|
|
5808
|
+
query GetSourceDetail($ids: [GUID!]!) {
|
|
5809
|
+
getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {
|
|
5810
|
+
id
|
|
5811
|
+
name
|
|
5812
|
+
description
|
|
5813
|
+
authorName
|
|
5814
|
+
authorDisplayName
|
|
5815
|
+
isExternal
|
|
5816
|
+
type
|
|
5817
|
+
created
|
|
5818
|
+
modified
|
|
5819
|
+
columns {
|
|
5820
|
+
id
|
|
5821
|
+
name
|
|
5822
|
+
author
|
|
5823
|
+
authorDisplayName
|
|
5824
|
+
description
|
|
5825
|
+
dataType
|
|
5826
|
+
type
|
|
5827
|
+
modified
|
|
5828
|
+
ownerName
|
|
5829
|
+
owner
|
|
5830
|
+
dataRecency
|
|
5831
|
+
sources {
|
|
5832
|
+
tableId
|
|
5833
|
+
tableName
|
|
5834
|
+
columnId
|
|
5835
|
+
columnName
|
|
5836
|
+
__typename
|
|
5837
|
+
}
|
|
5838
|
+
synonyms
|
|
5839
|
+
cohortAnswerId
|
|
5840
|
+
__typename
|
|
5841
|
+
}
|
|
5842
|
+
relationships
|
|
5843
|
+
destinationRelationships
|
|
5844
|
+
dataSourceId
|
|
5845
|
+
__typename
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
`;
|
|
5849
|
+
const sourceDetailCache = new Map();
|
|
5850
|
+
/**
|
|
5851
|
+
*
|
|
5852
|
+
* @param thoughtSpotHost
|
|
5853
|
+
* @param sourceId
|
|
5854
|
+
*/
|
|
5855
|
+
async function getSourceDetail(thoughtSpotHost, sourceId) {
|
|
5856
|
+
if (sourceDetailCache.get(sourceId)) {
|
|
5857
|
+
return sourceDetailCache.get(sourceId);
|
|
5858
|
+
}
|
|
5859
|
+
const details = await graphqlQuery({
|
|
5860
|
+
query: getSourceDetailQuery,
|
|
5861
|
+
variables: {
|
|
5862
|
+
ids: [sourceId],
|
|
5863
|
+
},
|
|
5864
|
+
thoughtSpotHost,
|
|
5865
|
+
});
|
|
5866
|
+
const souceDetails = details[0];
|
|
5867
|
+
if (souceDetails) {
|
|
5868
|
+
sourceDetailCache.set(sourceId, souceDetails);
|
|
5869
|
+
}
|
|
5870
|
+
return souceDetails;
|
|
5871
|
+
}
|
|
5861
5872
|
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
return /^\s*\bfunction\b/.test(f);
|
|
5939
|
-
} catch (x) {
|
|
5940
|
-
return false;
|
|
5941
|
-
}
|
|
5942
|
-
};
|
|
5943
|
-
|
|
5944
|
-
_.isArguments = function(obj) {
|
|
5945
|
-
return !!(obj && hasOwnProperty$9.call(obj, 'callee'));
|
|
5946
|
-
};
|
|
5947
|
-
|
|
5948
|
-
_.toArray = function(iterable) {
|
|
5949
|
-
if (!iterable) {
|
|
5950
|
-
return [];
|
|
5951
|
-
}
|
|
5952
|
-
if (iterable.toArray) {
|
|
5953
|
-
return iterable.toArray();
|
|
5954
|
-
}
|
|
5955
|
-
if (_.isArray(iterable)) {
|
|
5956
|
-
return slice.call(iterable);
|
|
5957
|
-
}
|
|
5958
|
-
if (_.isArguments(iterable)) {
|
|
5959
|
-
return slice.call(iterable);
|
|
5960
|
-
}
|
|
5961
|
-
return _.values(iterable);
|
|
5962
|
-
};
|
|
5963
|
-
|
|
5964
|
-
_.map = function(arr, callback, context) {
|
|
5965
|
-
if (nativeMap && arr.map === nativeMap) {
|
|
5966
|
-
return arr.map(callback, context);
|
|
5967
|
-
} else {
|
|
5968
|
-
var results = [];
|
|
5969
|
-
_.each(arr, function(item) {
|
|
5970
|
-
results.push(callback.call(context, item));
|
|
5971
|
-
});
|
|
5972
|
-
return results;
|
|
5973
|
-
}
|
|
5974
|
-
};
|
|
5975
|
-
|
|
5976
|
-
_.keys = function(obj) {
|
|
5977
|
-
var results = [];
|
|
5978
|
-
if (obj === null) {
|
|
5979
|
-
return results;
|
|
5980
|
-
}
|
|
5981
|
-
_.each(obj, function(value, key) {
|
|
5982
|
-
results[results.length] = key;
|
|
5983
|
-
});
|
|
5984
|
-
return results;
|
|
5985
|
-
};
|
|
5986
|
-
|
|
5987
|
-
_.values = function(obj) {
|
|
5988
|
-
var results = [];
|
|
5989
|
-
if (obj === null) {
|
|
5990
|
-
return results;
|
|
5991
|
-
}
|
|
5992
|
-
_.each(obj, function(value) {
|
|
5993
|
-
results[results.length] = value;
|
|
5994
|
-
});
|
|
5995
|
-
return results;
|
|
5996
|
-
};
|
|
5997
|
-
|
|
5998
|
-
_.include = function(obj, target) {
|
|
5999
|
-
var found = false;
|
|
6000
|
-
if (obj === null) {
|
|
6001
|
-
return found;
|
|
6002
|
-
}
|
|
6003
|
-
if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
|
|
6004
|
-
return obj.indexOf(target) != -1;
|
|
6005
|
-
}
|
|
6006
|
-
_.each(obj, function(value) {
|
|
6007
|
-
if (found || (found = (value === target))) {
|
|
6008
|
-
return breaker;
|
|
6009
|
-
}
|
|
6010
|
-
});
|
|
6011
|
-
return found;
|
|
6012
|
-
};
|
|
6013
|
-
|
|
6014
|
-
_.includes = function(str, needle) {
|
|
6015
|
-
return str.indexOf(needle) !== -1;
|
|
6016
|
-
};
|
|
6017
|
-
|
|
6018
|
-
// Underscore Addons
|
|
6019
|
-
_.inherit = function(subclass, superclass) {
|
|
6020
|
-
subclass.prototype = new superclass();
|
|
6021
|
-
subclass.prototype.constructor = subclass;
|
|
6022
|
-
subclass.superclass = superclass.prototype;
|
|
6023
|
-
return subclass;
|
|
6024
|
-
};
|
|
6025
|
-
|
|
6026
|
-
_.isObject = function(obj) {
|
|
6027
|
-
return (obj === Object(obj) && !_.isArray(obj));
|
|
6028
|
-
};
|
|
6029
|
-
|
|
6030
|
-
_.isEmptyObject = function(obj) {
|
|
6031
|
-
if (_.isObject(obj)) {
|
|
6032
|
-
for (var key in obj) {
|
|
6033
|
-
if (hasOwnProperty$9.call(obj, key)) {
|
|
6034
|
-
return false;
|
|
6035
|
-
}
|
|
6036
|
-
}
|
|
6037
|
-
return true;
|
|
6038
|
-
}
|
|
6039
|
-
return false;
|
|
6040
|
-
};
|
|
6041
|
-
|
|
6042
|
-
_.isUndefined = function(obj) {
|
|
6043
|
-
return obj === void 0;
|
|
6044
|
-
};
|
|
6045
|
-
|
|
6046
|
-
_.isString = function(obj) {
|
|
6047
|
-
return toString.call(obj) == '[object String]';
|
|
6048
|
-
};
|
|
5873
|
+
const bachSessionId = `
|
|
5874
|
+
id {
|
|
5875
|
+
sessionId
|
|
5876
|
+
genNo
|
|
5877
|
+
acSession {
|
|
5878
|
+
sessionId
|
|
5879
|
+
genNo
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5882
|
+
`;
|
|
5883
|
+
const getUnaggregatedAnswerSession = `
|
|
5884
|
+
mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
|
|
5885
|
+
Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
|
|
5886
|
+
${bachSessionId}
|
|
5887
|
+
answer {
|
|
5888
|
+
visualizations {
|
|
5889
|
+
... on TableViz {
|
|
5890
|
+
columns {
|
|
5891
|
+
column {
|
|
5892
|
+
id
|
|
5893
|
+
name
|
|
5894
|
+
referencedColumns {
|
|
5895
|
+
guid
|
|
5896
|
+
displayName
|
|
5897
|
+
}
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5900
|
+
}
|
|
5901
|
+
}
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
}
|
|
5905
|
+
`;
|
|
5906
|
+
const removeColumns = `
|
|
5907
|
+
mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
|
|
5908
|
+
Answer__removeColumns(
|
|
5909
|
+
session: $session
|
|
5910
|
+
logicalColumnIds: $logicalColumnIds
|
|
5911
|
+
columnIds: $columnIds
|
|
5912
|
+
) {
|
|
5913
|
+
${bachSessionId}
|
|
5914
|
+
}
|
|
5915
|
+
}
|
|
5916
|
+
`;
|
|
5917
|
+
const addColumns = `
|
|
5918
|
+
mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
|
|
5919
|
+
Answer__addColumn(session: $session, columns: $columns) {
|
|
5920
|
+
${bachSessionId}
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
`;
|
|
5924
|
+
const getAnswerData = `
|
|
5925
|
+
query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
|
|
5926
|
+
getAnswer(session: $session) {
|
|
5927
|
+
${bachSessionId}
|
|
5928
|
+
answer {
|
|
5929
|
+
id
|
|
5930
|
+
visualizations {
|
|
5931
|
+
id
|
|
5932
|
+
... on TableViz {
|
|
5933
|
+
columns {
|
|
5934
|
+
column {
|
|
5935
|
+
id
|
|
5936
|
+
name
|
|
5937
|
+
type
|
|
5938
|
+
aggregationType
|
|
5939
|
+
dataType
|
|
5940
|
+
}
|
|
5941
|
+
}
|
|
5942
|
+
data(deadline: $deadline, pagination: $dataPaginationParams)
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5945
|
+
}
|
|
5946
|
+
}
|
|
5947
|
+
}
|
|
5948
|
+
`;
|
|
6049
5949
|
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
5950
|
+
// eslint-disable-next-line no-shadow
|
|
5951
|
+
var OperationType;
|
|
5952
|
+
(function (OperationType) {
|
|
5953
|
+
OperationType["GetChartWithData"] = "GetChartWithData";
|
|
5954
|
+
OperationType["GetTableWithHeadlineData"] = "GetTableWithHeadlineData";
|
|
5955
|
+
})(OperationType || (OperationType = {}));
|
|
5956
|
+
/**
|
|
5957
|
+
* Class representing the answer service provided with the
|
|
5958
|
+
* custom action payload. This service could be used to run
|
|
5959
|
+
* graphql queries in the context of the answer on which the
|
|
5960
|
+
* custom action was triggered.
|
|
5961
|
+
*
|
|
5962
|
+
* @example
|
|
5963
|
+
* ```js
|
|
5964
|
+
* embed.on(EmbedEvent.CustomAction, e => {
|
|
5965
|
+
* const underlying = await e.answerService.getUnderlyingDataForPoint([
|
|
5966
|
+
* 'col name 1'
|
|
5967
|
+
* ]);
|
|
5968
|
+
* const data = await underlying.fetchData(0, 100);
|
|
5969
|
+
* })
|
|
5970
|
+
* ```
|
|
5971
|
+
* @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
|
|
5972
|
+
* @group Events
|
|
5973
|
+
*/
|
|
5974
|
+
class AnswerService {
|
|
5975
|
+
/**
|
|
5976
|
+
* Should not need to be called directly.
|
|
5977
|
+
*
|
|
5978
|
+
* @param session
|
|
5979
|
+
* @param answer
|
|
5980
|
+
* @param thoughtSpotHost
|
|
5981
|
+
* @param selectedPoints
|
|
5982
|
+
*/
|
|
5983
|
+
constructor(session, answer, thoughtSpotHost, selectedPoints) {
|
|
5984
|
+
this.session = session;
|
|
5985
|
+
this.answer = answer;
|
|
5986
|
+
this.thoughtSpotHost = thoughtSpotHost;
|
|
5987
|
+
this.selectedPoints = selectedPoints;
|
|
5988
|
+
this.session = removeTypename(session);
|
|
5989
|
+
}
|
|
5990
|
+
/**
|
|
5991
|
+
* Get the details about the source used in the answer.
|
|
5992
|
+
* This can be used to get the list of all columns in the data source for example.
|
|
5993
|
+
*/
|
|
5994
|
+
async getSourceDetail() {
|
|
5995
|
+
const sourceId = this.answer.sources[0].header.guid;
|
|
5996
|
+
return getSourceDetail(this.thoughtSpotHost, sourceId);
|
|
5997
|
+
}
|
|
5998
|
+
/**
|
|
5999
|
+
* Remove columnIds and return updated answer session.
|
|
6000
|
+
*
|
|
6001
|
+
* @param columnIds
|
|
6002
|
+
* @returns
|
|
6003
|
+
*/
|
|
6004
|
+
async removeColumns(columnIds) {
|
|
6005
|
+
return this.executeQuery(removeColumns, {
|
|
6006
|
+
logicalColumnIds: columnIds,
|
|
6007
|
+
});
|
|
6008
|
+
}
|
|
6009
|
+
/**
|
|
6010
|
+
* Add columnIds and return updated answer session.
|
|
6011
|
+
*
|
|
6012
|
+
* @param columnIds
|
|
6013
|
+
* @returns
|
|
6014
|
+
*/
|
|
6015
|
+
async addColumns(columnIds) {
|
|
6016
|
+
return this.executeQuery(addColumns, {
|
|
6017
|
+
columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
|
|
6018
|
+
});
|
|
6019
|
+
}
|
|
6020
|
+
/**
|
|
6021
|
+
* Fetch data from the answer.
|
|
6022
|
+
*
|
|
6023
|
+
* @param offset
|
|
6024
|
+
* @param size
|
|
6025
|
+
* @returns
|
|
6026
|
+
*/
|
|
6027
|
+
async fetchData(offset = 0, size = 1000) {
|
|
6028
|
+
const { answer } = await this.executeQuery(getAnswerData, {
|
|
6029
|
+
deadline: 0,
|
|
6030
|
+
dataPaginationParams: {
|
|
6031
|
+
isClientPaginated: true,
|
|
6032
|
+
offset,
|
|
6033
|
+
size,
|
|
6034
|
+
},
|
|
6035
|
+
});
|
|
6036
|
+
const { columns, data } = answer.visualizations.find((viz) => !!viz.data) || {};
|
|
6037
|
+
return {
|
|
6038
|
+
columns,
|
|
6039
|
+
data,
|
|
6040
|
+
};
|
|
6041
|
+
}
|
|
6042
|
+
/**
|
|
6043
|
+
* Fetch the data for the answer as a CSV blob. This might be
|
|
6044
|
+
* quicker for larger data.
|
|
6045
|
+
*
|
|
6046
|
+
* @param userLocale
|
|
6047
|
+
* @param includeInfo Include the CSV header in the output
|
|
6048
|
+
* @returns Response
|
|
6049
|
+
*/
|
|
6050
|
+
async fetchCSVBlob(userLocale = 'en-us', includeInfo = false) {
|
|
6051
|
+
const fetchUrl = this.getFetchCSVBlobUrl(userLocale, includeInfo);
|
|
6052
|
+
return tokenizedFetch(fetchUrl, {
|
|
6053
|
+
credentials: 'include',
|
|
6054
|
+
});
|
|
6055
|
+
}
|
|
6056
|
+
/**
|
|
6057
|
+
* Just get the internal URL for this answer's data
|
|
6058
|
+
* as a CSV blob.
|
|
6059
|
+
*
|
|
6060
|
+
* @param userLocale
|
|
6061
|
+
* @param includeInfo
|
|
6062
|
+
* @returns
|
|
6063
|
+
*/
|
|
6064
|
+
getFetchCSVBlobUrl(userLocale = 'en-us', includeInfo = false) {
|
|
6065
|
+
return `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
|
|
6066
|
+
}
|
|
6067
|
+
/**
|
|
6068
|
+
* Get underlying data given a point and the output column names.
|
|
6069
|
+
* In case of a context menu action, the selectedPoints are
|
|
6070
|
+
* automatically passed.
|
|
6071
|
+
*
|
|
6072
|
+
* @param outputColumnNames
|
|
6073
|
+
* @param selectedPoints
|
|
6074
|
+
* @example
|
|
6075
|
+
* ```js
|
|
6076
|
+
* embed.on(EmbedEvent.CustomAction, e => {
|
|
6077
|
+
* const underlying = await e.answerService.getUnderlyingDataForPoint([
|
|
6078
|
+
* 'col name 1' // The column should exist in the data source.
|
|
6079
|
+
* ]);
|
|
6080
|
+
* const data = await underlying.fetchData(0, 100);
|
|
6081
|
+
* })
|
|
6082
|
+
* ```
|
|
6083
|
+
* @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
|
|
6084
|
+
*/
|
|
6085
|
+
async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
|
|
6086
|
+
if (!selectedPoints && !this.selectedPoints) {
|
|
6087
|
+
throw new Error('Needs to be triggered in context of a point');
|
|
6088
|
+
}
|
|
6089
|
+
if (!selectedPoints) {
|
|
6090
|
+
selectedPoints = getSelectedPointsForUnderlyingDataQuery(this.selectedPoints);
|
|
6091
|
+
}
|
|
6092
|
+
const sourceDetail = await this.getSourceDetail();
|
|
6093
|
+
const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
|
|
6094
|
+
const unAggAnswer = await graphqlQuery({
|
|
6095
|
+
query: getUnaggregatedAnswerSession,
|
|
6096
|
+
variables: {
|
|
6097
|
+
session: this.session,
|
|
6098
|
+
columns: selectedPoints,
|
|
6099
|
+
},
|
|
6100
|
+
thoughtSpotHost: this.thoughtSpotHost,
|
|
6101
|
+
});
|
|
6102
|
+
const unaggAnswerSession = new AnswerService(unAggAnswer.id, unAggAnswer.answer, this.thoughtSpotHost);
|
|
6103
|
+
const currentColumns = new Set(unAggAnswer.answer.visualizations[0].columns
|
|
6104
|
+
.map((c) => c.column.referencedColumns[0].guid));
|
|
6105
|
+
const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
|
|
6106
|
+
if (columnsToAdd.length) {
|
|
6107
|
+
await unaggAnswerSession.addColumns(columnsToAdd);
|
|
6108
|
+
}
|
|
6109
|
+
const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
|
|
6110
|
+
if (columnsToRemove.length) {
|
|
6111
|
+
await unaggAnswerSession.removeColumns(columnsToRemove);
|
|
6112
|
+
}
|
|
6113
|
+
return unaggAnswerSession;
|
|
6114
|
+
}
|
|
6115
|
+
/**
|
|
6116
|
+
* Execute a custom graphql query in the context of the answer.
|
|
6117
|
+
*
|
|
6118
|
+
* @param query graphql query
|
|
6119
|
+
* @param variables graphql variables
|
|
6120
|
+
* @returns
|
|
6121
|
+
*/
|
|
6122
|
+
async executeQuery(query, variables) {
|
|
6123
|
+
const data = await graphqlQuery({
|
|
6124
|
+
query,
|
|
6125
|
+
variables: {
|
|
6126
|
+
session: this.session,
|
|
6127
|
+
...variables,
|
|
6128
|
+
},
|
|
6129
|
+
thoughtSpotHost: this.thoughtSpotHost,
|
|
6130
|
+
isCompositeQuery: false,
|
|
6131
|
+
});
|
|
6132
|
+
this.session = deepMerge(this.session, (data === null || data === void 0 ? void 0 : data.id) || {});
|
|
6133
|
+
return data;
|
|
6134
|
+
}
|
|
6135
|
+
/**
|
|
6136
|
+
* Get the internal session details for the answer.
|
|
6137
|
+
*
|
|
6138
|
+
* @returns
|
|
6139
|
+
*/
|
|
6140
|
+
getSession() {
|
|
6141
|
+
return this.session;
|
|
6142
|
+
}
|
|
6143
|
+
}
|
|
6144
|
+
/**
|
|
6145
|
+
*
|
|
6146
|
+
* @param sourceDetail
|
|
6147
|
+
* @param colNames
|
|
6148
|
+
*/
|
|
6149
|
+
function getGuidsFromColumnNames(sourceDetail, colNames) {
|
|
6150
|
+
const cols = sourceDetail.columns.reduce((colSet, col) => {
|
|
6151
|
+
colSet[col.name] = col;
|
|
6152
|
+
return colSet;
|
|
6153
|
+
}, {});
|
|
6154
|
+
return new Set(colNames.map((colName) => {
|
|
6155
|
+
const col = cols[colName];
|
|
6156
|
+
return col.id;
|
|
6157
|
+
}));
|
|
6158
|
+
}
|
|
6159
|
+
/**
|
|
6160
|
+
*
|
|
6161
|
+
* @param selectedPoints
|
|
6162
|
+
*/
|
|
6163
|
+
function getSelectedPointsForUnderlyingDataQuery(selectedPoints) {
|
|
6164
|
+
const underlyingDataPoint = [];
|
|
6165
|
+
/**
|
|
6166
|
+
*
|
|
6167
|
+
* @param colVal
|
|
6168
|
+
*/
|
|
6169
|
+
function addPointFromColVal(colVal) {
|
|
6170
|
+
var _a;
|
|
6171
|
+
const dataType = colVal.column.dataType;
|
|
6172
|
+
const id = colVal.column.id;
|
|
6173
|
+
let dataValue;
|
|
6174
|
+
if (dataType === 'DATE') {
|
|
6175
|
+
if (Number.isFinite(colVal.value)) {
|
|
6176
|
+
dataValue = [{
|
|
6177
|
+
epochRange: {
|
|
6178
|
+
startEpoch: colVal.value,
|
|
6179
|
+
},
|
|
6180
|
+
}];
|
|
6181
|
+
// Case for custom calendar.
|
|
6182
|
+
}
|
|
6183
|
+
else if ((_a = colVal.value) === null || _a === void 0 ? void 0 : _a.v) {
|
|
6184
|
+
dataValue = [{
|
|
6185
|
+
epochRange: {
|
|
6186
|
+
startEpoch: colVal.value.v.s,
|
|
6187
|
+
endEpoch: colVal.value.v.e,
|
|
6188
|
+
},
|
|
6189
|
+
}];
|
|
6190
|
+
}
|
|
6191
|
+
}
|
|
6192
|
+
else {
|
|
6193
|
+
dataValue = [{ value: colVal.value }];
|
|
6194
|
+
}
|
|
6195
|
+
underlyingDataPoint.push({
|
|
6196
|
+
columnId: colVal.column.id,
|
|
6197
|
+
dataValue,
|
|
6198
|
+
});
|
|
6199
|
+
}
|
|
6200
|
+
selectedPoints.forEach((p) => {
|
|
6201
|
+
p.selectedAttributes.forEach(addPointFromColVal);
|
|
6202
|
+
});
|
|
6203
|
+
return underlyingDataPoint;
|
|
6204
|
+
}
|
|
6057
6205
|
|
|
6058
|
-
|
|
6059
|
-
|
|
6206
|
+
const ERROR_MESSAGE = {
|
|
6207
|
+
INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
|
|
6208
|
+
LIVEBOARD_VIZ_ID_VALIDATION: 'Please provide either liveboardId or pinboardId',
|
|
6209
|
+
TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
|
|
6210
|
+
SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
|
|
6211
|
+
SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
|
|
6060
6212
|
};
|
|
6061
6213
|
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6214
|
+
/**
|
|
6215
|
+
* Copyright (c) 2023
|
|
6216
|
+
*
|
|
6217
|
+
* Utilities related to reading configuration objects
|
|
6218
|
+
*
|
|
6219
|
+
* @summary Config-related utils
|
|
6220
|
+
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
|
|
6221
|
+
*/
|
|
6222
|
+
const urlRegex = new RegExp([
|
|
6223
|
+
'(^(https?:)//)?',
|
|
6224
|
+
'(([^:/?#]*)(?::([0-9]+))?)',
|
|
6225
|
+
'(/{0,1}[^?#]*)',
|
|
6226
|
+
'(\\?[^#]*|)',
|
|
6227
|
+
'(#.*|)$', // hash
|
|
6228
|
+
].join(''));
|
|
6229
|
+
/**
|
|
6230
|
+
* Parse and construct the ThoughtSpot hostname or IP address
|
|
6231
|
+
* from the embed configuration object.
|
|
6232
|
+
*
|
|
6233
|
+
* @param config
|
|
6234
|
+
*/
|
|
6235
|
+
const getThoughtSpotHost = (config) => {
|
|
6236
|
+
if (!config.thoughtSpotHost) {
|
|
6237
|
+
throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
|
|
6238
|
+
}
|
|
6239
|
+
const urlParts = config.thoughtSpotHost.match(urlRegex);
|
|
6240
|
+
if (!urlParts) {
|
|
6241
|
+
throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
|
|
6242
|
+
}
|
|
6243
|
+
const protocol = urlParts[2] || window.location.protocol;
|
|
6244
|
+
const host = urlParts[3];
|
|
6245
|
+
let path = urlParts[6];
|
|
6246
|
+
// Lose the trailing / if any
|
|
6247
|
+
if (path.charAt(path.length - 1) === '/') {
|
|
6248
|
+
path = path.substring(0, path.length - 1);
|
|
6249
|
+
}
|
|
6250
|
+
// const urlParams = urlParts[7];
|
|
6251
|
+
// const hash = urlParts[8];
|
|
6252
|
+
return `${protocol}//${host}${path}`;
|
|
6253
|
+
};
|
|
6254
|
+
const getV2BasePath = (config) => {
|
|
6255
|
+
if (config.basepath) {
|
|
6256
|
+
return config.basepath;
|
|
6257
|
+
}
|
|
6258
|
+
const tsHost = getThoughtSpotHost(config);
|
|
6259
|
+
// This is to handle when e2e's. Search is run on pods for
|
|
6260
|
+
// comp-blink-test-pipeline with baseUrl=https://localhost:8443.
|
|
6261
|
+
// This is to handle when the developer is developing in their local
|
|
6262
|
+
// environment.
|
|
6263
|
+
if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
|
|
6264
|
+
return '';
|
|
6265
|
+
}
|
|
6266
|
+
return 'v2';
|
|
6267
|
+
};
|
|
6268
|
+
/**
|
|
6269
|
+
* It is a good idea to keep URLs under 2000 chars.
|
|
6270
|
+
* If this is ever breached, since we pass view configuration through
|
|
6271
|
+
* URL params, we would like to log a warning.
|
|
6272
|
+
* Reference: https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
|
|
6273
|
+
*/
|
|
6274
|
+
const URL_MAX_LENGTH = 2000;
|
|
6275
|
+
/**
|
|
6276
|
+
* The default CSS dimensions of the embedded app
|
|
6277
|
+
*/
|
|
6278
|
+
const DEFAULT_EMBED_WIDTH = '100%';
|
|
6279
|
+
const DEFAULT_EMBED_HEIGHT = '100%';
|
|
6079
6280
|
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
return n < 10 ? '0' + n : n;
|
|
6084
|
-
}
|
|
6085
|
-
return d.getUTCFullYear() + '-' +
|
|
6086
|
-
pad(d.getUTCMonth() + 1) + '-' +
|
|
6087
|
-
pad(d.getUTCDate()) + 'T' +
|
|
6088
|
-
pad(d.getUTCHours()) + ':' +
|
|
6089
|
-
pad(d.getUTCMinutes()) + ':' +
|
|
6090
|
-
pad(d.getUTCSeconds());
|
|
6281
|
+
var Config = {
|
|
6282
|
+
DEBUG: false,
|
|
6283
|
+
LIB_VERSION: '2.45.0'
|
|
6091
6284
|
};
|
|
6092
6285
|
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6286
|
+
// since es6 imports are static and we run unit tests from the console, window won't be defined when importing this file
|
|
6287
|
+
var window$1;
|
|
6288
|
+
if (typeof(window) === 'undefined') {
|
|
6289
|
+
var loc = {
|
|
6290
|
+
hostname: ''
|
|
6291
|
+
};
|
|
6292
|
+
window$1 = {
|
|
6293
|
+
navigator: { userAgent: '' },
|
|
6294
|
+
document: {
|
|
6295
|
+
location: loc,
|
|
6296
|
+
referrer: ''
|
|
6297
|
+
},
|
|
6298
|
+
screen: { width: 0, height: 0 },
|
|
6299
|
+
location: loc
|
|
6300
|
+
};
|
|
6301
|
+
} else {
|
|
6302
|
+
window$1 = window;
|
|
6303
|
+
}
|
|
6102
6304
|
|
|
6103
6305
|
/*
|
|
6104
|
-
*
|
|
6105
|
-
*
|
|
6106
|
-
* truncate all the values recursively.
|
|
6306
|
+
* Saved references to long variable names, so that closure compiler can
|
|
6307
|
+
* minimize file size.
|
|
6107
6308
|
*/
|
|
6108
|
-
_.truncate = function(obj, length) {
|
|
6109
|
-
var ret;
|
|
6110
6309
|
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6310
|
+
var ArrayProto = Array.prototype;
|
|
6311
|
+
var FuncProto = Function.prototype;
|
|
6312
|
+
var ObjProto = Object.prototype;
|
|
6313
|
+
var slice = ArrayProto.slice;
|
|
6314
|
+
var toString = ObjProto.toString;
|
|
6315
|
+
var hasOwnProperty$9 = ObjProto.hasOwnProperty;
|
|
6316
|
+
var windowConsole = window$1.console;
|
|
6317
|
+
var navigator = window$1.navigator;
|
|
6318
|
+
var document$1 = window$1.document;
|
|
6319
|
+
var windowOpera = window$1.opera;
|
|
6320
|
+
var screen = window$1.screen;
|
|
6321
|
+
var userAgent = navigator.userAgent;
|
|
6322
|
+
var nativeBind = FuncProto.bind;
|
|
6323
|
+
var nativeForEach = ArrayProto.forEach;
|
|
6324
|
+
var nativeIndexOf = ArrayProto.indexOf;
|
|
6325
|
+
var nativeMap = ArrayProto.map;
|
|
6326
|
+
var nativeIsArray = Array.isArray;
|
|
6327
|
+
var breaker = {};
|
|
6328
|
+
var _ = {
|
|
6329
|
+
trim: function(str) {
|
|
6330
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
|
|
6331
|
+
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
|
6125
6332
|
}
|
|
6333
|
+
};
|
|
6126
6334
|
|
|
6127
|
-
|
|
6335
|
+
// Console override
|
|
6336
|
+
var console$1 = {
|
|
6337
|
+
/** @type {function(...*)} */
|
|
6338
|
+
log: function() {
|
|
6339
|
+
if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
|
|
6340
|
+
try {
|
|
6341
|
+
windowConsole.log.apply(windowConsole, arguments);
|
|
6342
|
+
} catch (err) {
|
|
6343
|
+
_.each(arguments, function(arg) {
|
|
6344
|
+
windowConsole.log(arg);
|
|
6345
|
+
});
|
|
6346
|
+
}
|
|
6347
|
+
}
|
|
6348
|
+
},
|
|
6349
|
+
/** @type {function(...*)} */
|
|
6350
|
+
warn: function() {
|
|
6351
|
+
if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
|
|
6352
|
+
var args = ['Mixpanel warning:'].concat(_.toArray(arguments));
|
|
6353
|
+
try {
|
|
6354
|
+
windowConsole.warn.apply(windowConsole, args);
|
|
6355
|
+
} catch (err) {
|
|
6356
|
+
_.each(args, function(arg) {
|
|
6357
|
+
windowConsole.warn(arg);
|
|
6358
|
+
});
|
|
6359
|
+
}
|
|
6360
|
+
}
|
|
6361
|
+
},
|
|
6362
|
+
/** @type {function(...*)} */
|
|
6363
|
+
error: function() {
|
|
6364
|
+
if (Config.DEBUG && !_.isUndefined(windowConsole) && windowConsole) {
|
|
6365
|
+
var args = ['Mixpanel error:'].concat(_.toArray(arguments));
|
|
6366
|
+
try {
|
|
6367
|
+
windowConsole.error.apply(windowConsole, args);
|
|
6368
|
+
} catch (err) {
|
|
6369
|
+
_.each(args, function(arg) {
|
|
6370
|
+
windowConsole.error(arg);
|
|
6371
|
+
});
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
},
|
|
6375
|
+
/** @type {function(...*)} */
|
|
6376
|
+
critical: function() {
|
|
6377
|
+
if (!_.isUndefined(windowConsole) && windowConsole) {
|
|
6378
|
+
var args = ['Mixpanel error:'].concat(_.toArray(arguments));
|
|
6379
|
+
try {
|
|
6380
|
+
windowConsole.error.apply(windowConsole, args);
|
|
6381
|
+
} catch (err) {
|
|
6382
|
+
_.each(args, function(arg) {
|
|
6383
|
+
windowConsole.error(arg);
|
|
6384
|
+
});
|
|
6385
|
+
}
|
|
6386
|
+
}
|
|
6387
|
+
}
|
|
6128
6388
|
};
|
|
6129
6389
|
|
|
6130
|
-
|
|
6131
|
-
return function(
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
};
|
|
6390
|
+
var log_func_with_prefix = function(func, prefix) {
|
|
6391
|
+
return function() {
|
|
6392
|
+
arguments[0] = '[' + prefix + '] ' + arguments[0];
|
|
6393
|
+
return func.apply(console$1, arguments);
|
|
6394
|
+
};
|
|
6395
|
+
};
|
|
6396
|
+
var console_with_prefix = function(prefix) {
|
|
6397
|
+
return {
|
|
6398
|
+
log: log_func_with_prefix(console$1.log, prefix),
|
|
6399
|
+
error: log_func_with_prefix(console$1.error, prefix),
|
|
6400
|
+
critical: log_func_with_prefix(console$1.critical, prefix)
|
|
6401
|
+
};
|
|
6402
|
+
};
|
|
6144
6403
|
|
|
6145
|
-
escapable.lastIndex = 0;
|
|
6146
|
-
return escapable.test(string) ?
|
|
6147
|
-
'"' + string.replace(escapable, function(a) {
|
|
6148
|
-
var c = meta[a];
|
|
6149
|
-
return typeof c === 'string' ? c :
|
|
6150
|
-
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
|
6151
|
-
}) + '"' :
|
|
6152
|
-
'"' + string + '"';
|
|
6153
|
-
};
|
|
6154
6404
|
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6405
|
+
// UNDERSCORE
|
|
6406
|
+
// Embed part of the Underscore Library
|
|
6407
|
+
_.bind = function(func, context) {
|
|
6408
|
+
var args, bound;
|
|
6409
|
+
if (nativeBind && func.bind === nativeBind) {
|
|
6410
|
+
return nativeBind.apply(func, slice.call(arguments, 1));
|
|
6411
|
+
}
|
|
6412
|
+
if (!_.isFunction(func)) {
|
|
6413
|
+
throw new TypeError();
|
|
6414
|
+
}
|
|
6415
|
+
args = slice.call(arguments, 2);
|
|
6416
|
+
bound = function() {
|
|
6417
|
+
if (!(this instanceof bound)) {
|
|
6418
|
+
return func.apply(context, args.concat(slice.call(arguments)));
|
|
6419
|
+
}
|
|
6420
|
+
var ctor = {};
|
|
6421
|
+
ctor.prototype = func.prototype;
|
|
6422
|
+
var self = new ctor();
|
|
6423
|
+
ctor.prototype = null;
|
|
6424
|
+
var result = func.apply(self, args.concat(slice.call(arguments)));
|
|
6425
|
+
if (Object(result) === result) {
|
|
6426
|
+
return result;
|
|
6427
|
+
}
|
|
6428
|
+
return self;
|
|
6429
|
+
};
|
|
6430
|
+
return bound;
|
|
6431
|
+
};
|
|
6165
6432
|
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6433
|
+
/**
|
|
6434
|
+
* @param {*=} obj
|
|
6435
|
+
* @param {function(...*)=} iterator
|
|
6436
|
+
* @param {Object=} context
|
|
6437
|
+
*/
|
|
6438
|
+
_.each = function(obj, iterator, context) {
|
|
6439
|
+
if (obj === null || obj === undefined) {
|
|
6440
|
+
return;
|
|
6441
|
+
}
|
|
6442
|
+
if (nativeForEach && obj.forEach === nativeForEach) {
|
|
6443
|
+
obj.forEach(iterator, context);
|
|
6444
|
+
} else if (obj.length === +obj.length) {
|
|
6445
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
|
6446
|
+
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) {
|
|
6447
|
+
return;
|
|
6170
6448
|
}
|
|
6449
|
+
}
|
|
6450
|
+
} else {
|
|
6451
|
+
for (var key in obj) {
|
|
6452
|
+
if (hasOwnProperty$9.call(obj, key)) {
|
|
6453
|
+
if (iterator.call(context, obj[key], key, obj) === breaker) {
|
|
6454
|
+
return;
|
|
6455
|
+
}
|
|
6456
|
+
}
|
|
6457
|
+
}
|
|
6458
|
+
}
|
|
6459
|
+
};
|
|
6171
6460
|
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6461
|
+
_.extend = function(obj) {
|
|
6462
|
+
_.each(slice.call(arguments, 1), function(source) {
|
|
6463
|
+
for (var prop in source) {
|
|
6464
|
+
if (source[prop] !== void 0) {
|
|
6465
|
+
obj[prop] = source[prop];
|
|
6466
|
+
}
|
|
6467
|
+
}
|
|
6468
|
+
});
|
|
6469
|
+
return obj;
|
|
6470
|
+
};
|
|
6176
6471
|
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6472
|
+
_.isArray = nativeIsArray || function(obj) {
|
|
6473
|
+
return toString.call(obj) === '[object Array]';
|
|
6474
|
+
};
|
|
6180
6475
|
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6476
|
+
// from a comment on http://dbj.org/dbj/?p=286
|
|
6477
|
+
// fails on only one very rare and deliberate custom object:
|
|
6478
|
+
// var bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
|
|
6479
|
+
_.isFunction = function(f) {
|
|
6480
|
+
try {
|
|
6481
|
+
return /^\s*\bfunction\b/.test(f);
|
|
6482
|
+
} catch (x) {
|
|
6483
|
+
return false;
|
|
6484
|
+
}
|
|
6485
|
+
};
|
|
6186
6486
|
|
|
6187
|
-
|
|
6487
|
+
_.isArguments = function(obj) {
|
|
6488
|
+
return !!(obj && hasOwnProperty$9.call(obj, 'callee'));
|
|
6489
|
+
};
|
|
6188
6490
|
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6491
|
+
_.toArray = function(iterable) {
|
|
6492
|
+
if (!iterable) {
|
|
6493
|
+
return [];
|
|
6494
|
+
}
|
|
6495
|
+
if (iterable.toArray) {
|
|
6496
|
+
return iterable.toArray();
|
|
6497
|
+
}
|
|
6498
|
+
if (_.isArray(iterable)) {
|
|
6499
|
+
return slice.call(iterable);
|
|
6500
|
+
}
|
|
6501
|
+
if (_.isArguments(iterable)) {
|
|
6502
|
+
return slice.call(iterable);
|
|
6503
|
+
}
|
|
6504
|
+
return _.values(iterable);
|
|
6505
|
+
};
|
|
6197
6506
|
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6507
|
+
_.map = function(arr, callback, context) {
|
|
6508
|
+
if (nativeMap && arr.map === nativeMap) {
|
|
6509
|
+
return arr.map(callback, context);
|
|
6510
|
+
} else {
|
|
6511
|
+
var results = [];
|
|
6512
|
+
_.each(arr, function(item) {
|
|
6513
|
+
results.push(callback.call(context, item));
|
|
6514
|
+
});
|
|
6515
|
+
return results;
|
|
6516
|
+
}
|
|
6517
|
+
};
|
|
6201
6518
|
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6519
|
+
_.keys = function(obj) {
|
|
6520
|
+
var results = [];
|
|
6521
|
+
if (obj === null) {
|
|
6522
|
+
return results;
|
|
6523
|
+
}
|
|
6524
|
+
_.each(obj, function(value, key) {
|
|
6525
|
+
results[results.length] = key;
|
|
6526
|
+
});
|
|
6527
|
+
return results;
|
|
6528
|
+
};
|
|
6206
6529
|
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6530
|
+
_.values = function(obj) {
|
|
6531
|
+
var results = [];
|
|
6532
|
+
if (obj === null) {
|
|
6533
|
+
return results;
|
|
6534
|
+
}
|
|
6535
|
+
_.each(obj, function(value) {
|
|
6536
|
+
results[results.length] = value;
|
|
6537
|
+
});
|
|
6538
|
+
return results;
|
|
6539
|
+
};
|
|
6211
6540
|
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6541
|
+
_.include = function(obj, target) {
|
|
6542
|
+
var found = false;
|
|
6543
|
+
if (obj === null) {
|
|
6544
|
+
return found;
|
|
6545
|
+
}
|
|
6546
|
+
if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
|
|
6547
|
+
return obj.indexOf(target) != -1;
|
|
6548
|
+
}
|
|
6549
|
+
_.each(obj, function(value) {
|
|
6550
|
+
if (found || (found = (value === target))) {
|
|
6551
|
+
return breaker;
|
|
6552
|
+
}
|
|
6553
|
+
});
|
|
6554
|
+
return found;
|
|
6555
|
+
};
|
|
6222
6556
|
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
v = str(k, value);
|
|
6227
|
-
if (v) {
|
|
6228
|
-
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
|
6229
|
-
}
|
|
6230
|
-
}
|
|
6231
|
-
}
|
|
6557
|
+
_.includes = function(str, needle) {
|
|
6558
|
+
return str.indexOf(needle) !== -1;
|
|
6559
|
+
};
|
|
6232
6560
|
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6561
|
+
// Underscore Addons
|
|
6562
|
+
_.inherit = function(subclass, superclass) {
|
|
6563
|
+
subclass.prototype = new superclass();
|
|
6564
|
+
subclass.prototype.constructor = subclass;
|
|
6565
|
+
subclass.superclass = superclass.prototype;
|
|
6566
|
+
return subclass;
|
|
6567
|
+
};
|
|
6568
|
+
|
|
6569
|
+
_.isObject = function(obj) {
|
|
6570
|
+
return (obj === Object(obj) && !_.isArray(obj));
|
|
6571
|
+
};
|
|
6572
|
+
|
|
6573
|
+
_.isEmptyObject = function(obj) {
|
|
6574
|
+
if (_.isObject(obj)) {
|
|
6575
|
+
for (var key in obj) {
|
|
6576
|
+
if (hasOwnProperty$9.call(obj, key)) {
|
|
6577
|
+
return false;
|
|
6240
6578
|
}
|
|
6241
|
-
}
|
|
6579
|
+
}
|
|
6580
|
+
return true;
|
|
6581
|
+
}
|
|
6582
|
+
return false;
|
|
6583
|
+
};
|
|
6242
6584
|
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
'': value
|
|
6247
|
-
});
|
|
6248
|
-
};
|
|
6249
|
-
})();
|
|
6585
|
+
_.isUndefined = function(obj) {
|
|
6586
|
+
return obj === void 0;
|
|
6587
|
+
};
|
|
6250
6588
|
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
_.
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6589
|
+
_.isString = function(obj) {
|
|
6590
|
+
return toString.call(obj) == '[object String]';
|
|
6591
|
+
};
|
|
6592
|
+
|
|
6593
|
+
_.isDate = function(obj) {
|
|
6594
|
+
return toString.call(obj) == '[object Date]';
|
|
6595
|
+
};
|
|
6596
|
+
|
|
6597
|
+
_.isNumber = function(obj) {
|
|
6598
|
+
return toString.call(obj) == '[object Number]';
|
|
6599
|
+
};
|
|
6600
|
+
|
|
6601
|
+
_.isElement = function(obj) {
|
|
6602
|
+
return !!(obj && obj.nodeType === 1);
|
|
6603
|
+
};
|
|
6604
|
+
|
|
6605
|
+
_.encodeDates = function(obj) {
|
|
6606
|
+
_.each(obj, function(v, k) {
|
|
6607
|
+
if (_.isDate(v)) {
|
|
6608
|
+
obj[k] = _.formatDate(v);
|
|
6609
|
+
} else if (_.isObject(v)) {
|
|
6610
|
+
obj[k] = _.encodeDates(v); // recurse
|
|
6611
|
+
}
|
|
6612
|
+
});
|
|
6613
|
+
return obj;
|
|
6614
|
+
};
|
|
6615
|
+
|
|
6616
|
+
_.timestamp = function() {
|
|
6617
|
+
Date.now = Date.now || function() {
|
|
6618
|
+
return +new Date;
|
|
6619
|
+
};
|
|
6620
|
+
return Date.now();
|
|
6621
|
+
};
|
|
6622
|
+
|
|
6623
|
+
_.formatDate = function(d) {
|
|
6624
|
+
// YYYY-MM-DDTHH:MM:SS in UTC
|
|
6625
|
+
function pad(n) {
|
|
6626
|
+
return n < 10 ? '0' + n : n;
|
|
6627
|
+
}
|
|
6628
|
+
return d.getUTCFullYear() + '-' +
|
|
6629
|
+
pad(d.getUTCMonth() + 1) + '-' +
|
|
6630
|
+
pad(d.getUTCDate()) + 'T' +
|
|
6631
|
+
pad(d.getUTCHours()) + ':' +
|
|
6632
|
+
pad(d.getUTCMinutes()) + ':' +
|
|
6633
|
+
pad(d.getUTCSeconds());
|
|
6634
|
+
};
|
|
6635
|
+
|
|
6636
|
+
_.strip_empty_properties = function(p) {
|
|
6637
|
+
var ret = {};
|
|
6638
|
+
_.each(p, function(v, k) {
|
|
6639
|
+
if (_.isString(v) && v.length > 0) {
|
|
6640
|
+
ret[k] = v;
|
|
6641
|
+
}
|
|
6642
|
+
});
|
|
6643
|
+
return ret;
|
|
6644
|
+
};
|
|
6645
|
+
|
|
6646
|
+
/*
|
|
6647
|
+
* this function returns a copy of object after truncating it. If
|
|
6648
|
+
* passed an Array or Object it will iterate through obj and
|
|
6649
|
+
* truncate all the values recursively.
|
|
6650
|
+
*/
|
|
6651
|
+
_.truncate = function(obj, length) {
|
|
6652
|
+
var ret;
|
|
6653
|
+
|
|
6654
|
+
if (typeof(obj) === 'string') {
|
|
6655
|
+
ret = obj.slice(0, length);
|
|
6656
|
+
} else if (_.isArray(obj)) {
|
|
6657
|
+
ret = [];
|
|
6658
|
+
_.each(obj, function(val) {
|
|
6659
|
+
ret.push(_.truncate(val, length));
|
|
6660
|
+
});
|
|
6661
|
+
} else if (_.isObject(obj)) {
|
|
6662
|
+
ret = {};
|
|
6663
|
+
_.each(obj, function(val, key) {
|
|
6664
|
+
ret[key] = _.truncate(val, length);
|
|
6665
|
+
});
|
|
6666
|
+
} else {
|
|
6667
|
+
ret = obj;
|
|
6668
|
+
}
|
|
6669
|
+
|
|
6670
|
+
return ret;
|
|
6671
|
+
};
|
|
6672
|
+
|
|
6673
|
+
_.JSONEncode = (function() {
|
|
6674
|
+
return function(mixed_val) {
|
|
6675
|
+
var value = mixed_val;
|
|
6676
|
+
var quote = function(string) {
|
|
6677
|
+
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
|
|
6678
|
+
var meta = { // table of character substitutions
|
|
6679
|
+
'\b': '\\b',
|
|
6680
|
+
'\t': '\\t',
|
|
6681
|
+
'\n': '\\n',
|
|
6682
|
+
'\f': '\\f',
|
|
6683
|
+
'\r': '\\r',
|
|
6684
|
+
'"': '\\"',
|
|
6685
|
+
'\\': '\\\\'
|
|
6686
|
+
};
|
|
6687
|
+
|
|
6688
|
+
escapable.lastIndex = 0;
|
|
6689
|
+
return escapable.test(string) ?
|
|
6690
|
+
'"' + string.replace(escapable, function(a) {
|
|
6691
|
+
var c = meta[a];
|
|
6692
|
+
return typeof c === 'string' ? c :
|
|
6693
|
+
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
|
6694
|
+
}) + '"' :
|
|
6695
|
+
'"' + string + '"';
|
|
6696
|
+
};
|
|
6697
|
+
|
|
6698
|
+
var str = function(key, holder) {
|
|
6699
|
+
var gap = '';
|
|
6700
|
+
var indent = ' ';
|
|
6701
|
+
var i = 0; // The loop counter.
|
|
6702
|
+
var k = ''; // The member key.
|
|
6703
|
+
var v = ''; // The member value.
|
|
6704
|
+
var length = 0;
|
|
6705
|
+
var mind = gap;
|
|
6706
|
+
var partial = [];
|
|
6707
|
+
var value = holder[key];
|
|
6708
|
+
|
|
6709
|
+
// If the value has a toJSON method, call it to obtain a replacement value.
|
|
6710
|
+
if (value && typeof value === 'object' &&
|
|
6711
|
+
typeof value.toJSON === 'function') {
|
|
6712
|
+
value = value.toJSON(key);
|
|
6713
|
+
}
|
|
6714
|
+
|
|
6715
|
+
// What happens next depends on the value's type.
|
|
6716
|
+
switch (typeof value) {
|
|
6717
|
+
case 'string':
|
|
6718
|
+
return quote(value);
|
|
6719
|
+
|
|
6720
|
+
case 'number':
|
|
6721
|
+
// JSON numbers must be finite. Encode non-finite numbers as null.
|
|
6722
|
+
return isFinite(value) ? String(value) : 'null';
|
|
6723
|
+
|
|
6724
|
+
case 'boolean':
|
|
6725
|
+
case 'null':
|
|
6726
|
+
// If the value is a boolean or null, convert it to a string. Note:
|
|
6727
|
+
// typeof null does not produce 'null'. The case is included here in
|
|
6728
|
+
// the remote chance that this gets fixed someday.
|
|
6729
|
+
|
|
6730
|
+
return String(value);
|
|
6731
|
+
|
|
6732
|
+
case 'object':
|
|
6733
|
+
// If the type is 'object', we might be dealing with an object or an array or
|
|
6734
|
+
// null.
|
|
6735
|
+
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
|
6736
|
+
// so watch out for that case.
|
|
6737
|
+
if (!value) {
|
|
6738
|
+
return 'null';
|
|
6739
|
+
}
|
|
6740
|
+
|
|
6741
|
+
// Make an array to hold the partial results of stringifying this object value.
|
|
6742
|
+
gap += indent;
|
|
6743
|
+
partial = [];
|
|
6744
|
+
|
|
6745
|
+
// Is the value an array?
|
|
6746
|
+
if (toString.apply(value) === '[object Array]') {
|
|
6747
|
+
// The value is an array. Stringify every element. Use null as a placeholder
|
|
6748
|
+
// for non-JSON values.
|
|
6749
|
+
|
|
6750
|
+
length = value.length;
|
|
6751
|
+
for (i = 0; i < length; i += 1) {
|
|
6752
|
+
partial[i] = str(i, value) || 'null';
|
|
6753
|
+
}
|
|
6754
|
+
|
|
6755
|
+
// Join all of the elements together, separated with commas, and wrap them in
|
|
6756
|
+
// brackets.
|
|
6757
|
+
v = partial.length === 0 ? '[]' :
|
|
6758
|
+
gap ? '[\n' + gap +
|
|
6759
|
+
partial.join(',\n' + gap) + '\n' +
|
|
6760
|
+
mind + ']' :
|
|
6761
|
+
'[' + partial.join(',') + ']';
|
|
6762
|
+
gap = mind;
|
|
6763
|
+
return v;
|
|
6764
|
+
}
|
|
6765
|
+
|
|
6766
|
+
// Iterate through all of the keys in the object.
|
|
6767
|
+
for (k in value) {
|
|
6768
|
+
if (hasOwnProperty$9.call(value, k)) {
|
|
6769
|
+
v = str(k, value);
|
|
6770
|
+
if (v) {
|
|
6771
|
+
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
|
6772
|
+
}
|
|
6773
|
+
}
|
|
6774
|
+
}
|
|
6775
|
+
|
|
6776
|
+
// Join all of the member texts together, separated with commas,
|
|
6777
|
+
// and wrap them in braces.
|
|
6778
|
+
v = partial.length === 0 ? '{}' :
|
|
6779
|
+
gap ? '{' + partial.join(',') + '' +
|
|
6780
|
+
mind + '}' : '{' + partial.join(',') + '}';
|
|
6781
|
+
gap = mind;
|
|
6782
|
+
return v;
|
|
6783
|
+
}
|
|
6784
|
+
};
|
|
6785
|
+
|
|
6786
|
+
// Make a fake root object containing our value under the key of ''.
|
|
6787
|
+
// Return the result of stringifying the value.
|
|
6788
|
+
return str('', {
|
|
6789
|
+
'': value
|
|
6790
|
+
});
|
|
6791
|
+
};
|
|
6792
|
+
})();
|
|
6793
|
+
|
|
6794
|
+
/**
|
|
6795
|
+
* From https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js
|
|
6796
|
+
* Slightly modified to throw a real Error rather than a POJO
|
|
6797
|
+
*/
|
|
6798
|
+
_.JSONDecode = (function() {
|
|
6799
|
+
var at, // The index of the current character
|
|
6800
|
+
ch, // The current character
|
|
6801
|
+
escapee = {
|
|
6802
|
+
'"': '"',
|
|
6803
|
+
'\\': '\\',
|
|
6804
|
+
'/': '/',
|
|
6805
|
+
'b': '\b',
|
|
6806
|
+
'f': '\f',
|
|
6807
|
+
'n': '\n',
|
|
6808
|
+
'r': '\r',
|
|
6809
|
+
't': '\t'
|
|
6267
6810
|
},
|
|
6268
6811
|
text,
|
|
6269
6812
|
error = function(m) {
|
|
@@ -11299,1405 +11842,497 @@
|
|
|
11299
11842
|
|
|
11300
11843
|
// perform some housekeeping around GDPR opt-in/out state
|
|
11301
11844
|
MixpanelLib.prototype._gdpr_init = function() {
|
|
11302
|
-
var is_localStorage_requested = this.get_config('opt_out_tracking_persistence_type') === 'localStorage';
|
|
11303
|
-
|
|
11304
|
-
// try to convert opt-in/out cookies to localStorage if possible
|
|
11305
|
-
if (is_localStorage_requested && _.localStorage.is_supported()) {
|
|
11306
|
-
if (!this.has_opted_in_tracking() && this.has_opted_in_tracking({'persistence_type': 'cookie'})) {
|
|
11307
|
-
this.opt_in_tracking({'enable_persistence': false});
|
|
11308
|
-
}
|
|
11309
|
-
if (!this.has_opted_out_tracking() && this.has_opted_out_tracking({'persistence_type': 'cookie'})) {
|
|
11310
|
-
this.opt_out_tracking({'clear_persistence': false});
|
|
11311
|
-
}
|
|
11312
|
-
this.clear_opt_in_out_tracking({
|
|
11313
|
-
'persistence_type': 'cookie',
|
|
11314
|
-
'enable_persistence': false
|
|
11315
|
-
});
|
|
11316
|
-
}
|
|
11317
|
-
|
|
11318
|
-
// check whether the user has already opted out - if so, clear & disable persistence
|
|
11319
|
-
if (this.has_opted_out_tracking()) {
|
|
11320
|
-
this._gdpr_update_persistence({'clear_persistence': true});
|
|
11321
|
-
|
|
11322
|
-
// check whether we should opt out by default
|
|
11323
|
-
// note: we don't clear persistence here by default since opt-out default state is often
|
|
11324
|
-
// used as an initial state while GDPR information is being collected
|
|
11325
|
-
} else if (!this.has_opted_in_tracking() && (
|
|
11326
|
-
this.get_config('opt_out_tracking_by_default') || _.cookie.get('mp_optout')
|
|
11327
|
-
)) {
|
|
11328
|
-
_.cookie.remove('mp_optout');
|
|
11329
|
-
this.opt_out_tracking({
|
|
11330
|
-
'clear_persistence': this.get_config('opt_out_persistence_by_default')
|
|
11331
|
-
});
|
|
11332
|
-
}
|
|
11333
|
-
};
|
|
11334
|
-
|
|
11335
|
-
/**
|
|
11336
|
-
* Enable or disable persistence based on options
|
|
11337
|
-
* only enable/disable if persistence is not already in this state
|
|
11338
|
-
* @param {boolean} [options.clear_persistence] If true, will delete all data stored by the sdk in persistence and disable it
|
|
11339
|
-
* @param {boolean} [options.enable_persistence] If true, will re-enable sdk persistence
|
|
11340
|
-
*/
|
|
11341
|
-
MixpanelLib.prototype._gdpr_update_persistence = function(options) {
|
|
11342
|
-
var disabled;
|
|
11343
|
-
if (options && options['clear_persistence']) {
|
|
11344
|
-
disabled = true;
|
|
11345
|
-
} else if (options && options['enable_persistence']) {
|
|
11346
|
-
disabled = false;
|
|
11347
|
-
} else {
|
|
11348
|
-
return;
|
|
11349
|
-
}
|
|
11350
|
-
|
|
11351
|
-
if (!this.get_config('disable_persistence') && this['persistence'].disabled !== disabled) {
|
|
11352
|
-
this['persistence'].set_disabled(disabled);
|
|
11353
|
-
}
|
|
11354
|
-
|
|
11355
|
-
if (disabled) {
|
|
11356
|
-
_.each(this.request_batchers, function(batcher) {
|
|
11357
|
-
batcher.clear();
|
|
11358
|
-
});
|
|
11359
|
-
}
|
|
11360
|
-
};
|
|
11361
|
-
|
|
11362
|
-
// call a base gdpr function after constructing the appropriate token and options args
|
|
11363
|
-
MixpanelLib.prototype._gdpr_call_func = function(func, options) {
|
|
11364
|
-
options = _.extend({
|
|
11365
|
-
'track': _.bind(this.track, this),
|
|
11366
|
-
'persistence_type': this.get_config('opt_out_tracking_persistence_type'),
|
|
11367
|
-
'cookie_prefix': this.get_config('opt_out_tracking_cookie_prefix'),
|
|
11368
|
-
'cookie_expiration': this.get_config('cookie_expiration'),
|
|
11369
|
-
'cross_site_cookie': this.get_config('cross_site_cookie'),
|
|
11370
|
-
'cross_subdomain_cookie': this.get_config('cross_subdomain_cookie'),
|
|
11371
|
-
'cookie_domain': this.get_config('cookie_domain'),
|
|
11372
|
-
'secure_cookie': this.get_config('secure_cookie'),
|
|
11373
|
-
'ignore_dnt': this.get_config('ignore_dnt')
|
|
11374
|
-
}, options);
|
|
11375
|
-
|
|
11376
|
-
// check if localStorage can be used for recording opt out status, fall back to cookie if not
|
|
11377
|
-
if (!_.localStorage.is_supported()) {
|
|
11378
|
-
options['persistence_type'] = 'cookie';
|
|
11379
|
-
}
|
|
11380
|
-
|
|
11381
|
-
return func(this.get_config('token'), {
|
|
11382
|
-
track: options['track'],
|
|
11383
|
-
trackEventName: options['track_event_name'],
|
|
11384
|
-
trackProperties: options['track_properties'],
|
|
11385
|
-
persistenceType: options['persistence_type'],
|
|
11386
|
-
persistencePrefix: options['cookie_prefix'],
|
|
11387
|
-
cookieDomain: options['cookie_domain'],
|
|
11388
|
-
cookieExpiration: options['cookie_expiration'],
|
|
11389
|
-
crossSiteCookie: options['cross_site_cookie'],
|
|
11390
|
-
crossSubdomainCookie: options['cross_subdomain_cookie'],
|
|
11391
|
-
secureCookie: options['secure_cookie'],
|
|
11392
|
-
ignoreDnt: options['ignore_dnt']
|
|
11393
|
-
});
|
|
11394
|
-
};
|
|
11395
|
-
|
|
11396
|
-
/**
|
|
11397
|
-
* Opt the user in to data tracking and cookies/localstorage for this Mixpanel instance
|
|
11398
|
-
*
|
|
11399
|
-
* ### Usage
|
|
11400
|
-
*
|
|
11401
|
-
* // opt user in
|
|
11402
|
-
* mixpanel.opt_in_tracking();
|
|
11403
|
-
*
|
|
11404
|
-
* // opt user in with specific event name, properties, cookie configuration
|
|
11405
|
-
* mixpanel.opt_in_tracking({
|
|
11406
|
-
* track_event_name: 'User opted in',
|
|
11407
|
-
* track_event_properties: {
|
|
11408
|
-
* 'Email': 'jdoe@example.com'
|
|
11409
|
-
* },
|
|
11410
|
-
* cookie_expiration: 30,
|
|
11411
|
-
* secure_cookie: true
|
|
11412
|
-
* });
|
|
11413
|
-
*
|
|
11414
|
-
* @param {Object} [options] A dictionary of config options to override
|
|
11415
|
-
* @param {function} [options.track] Function used for tracking a Mixpanel event to record the opt-in action (default is this Mixpanel instance's track method)
|
|
11416
|
-
* @param {string} [options.track_event_name=$opt_in] Event name to be used for tracking the opt-in action
|
|
11417
|
-
* @param {Object} [options.track_properties] Set of properties to be tracked along with the opt-in action
|
|
11418
|
-
* @param {boolean} [options.enable_persistence=true] If true, will re-enable sdk persistence
|
|
11419
|
-
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11420
|
-
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11421
|
-
* @param {Number} [options.cookie_expiration] Number of days until the opt-in cookie expires (overrides value specified in this Mixpanel instance's config)
|
|
11422
|
-
* @param {string} [options.cookie_domain] Custom cookie domain (overrides value specified in this Mixpanel instance's config)
|
|
11423
|
-
* @param {boolean} [options.cross_site_cookie] Whether the opt-in cookie is set as cross-site-enabled (overrides value specified in this Mixpanel instance's config)
|
|
11424
|
-
* @param {boolean} [options.cross_subdomain_cookie] Whether the opt-in cookie is set as cross-subdomain or not (overrides value specified in this Mixpanel instance's config)
|
|
11425
|
-
* @param {boolean} [options.secure_cookie] Whether the opt-in cookie is set as secure or not (overrides value specified in this Mixpanel instance's config)
|
|
11426
|
-
*/
|
|
11427
|
-
MixpanelLib.prototype.opt_in_tracking = function(options) {
|
|
11428
|
-
options = _.extend({
|
|
11429
|
-
'enable_persistence': true
|
|
11430
|
-
}, options);
|
|
11431
|
-
|
|
11432
|
-
this._gdpr_call_func(optIn, options);
|
|
11433
|
-
this._gdpr_update_persistence(options);
|
|
11434
|
-
};
|
|
11435
|
-
|
|
11436
|
-
/**
|
|
11437
|
-
* Opt the user out of data tracking and cookies/localstorage for this Mixpanel instance
|
|
11438
|
-
*
|
|
11439
|
-
* ### Usage
|
|
11440
|
-
*
|
|
11441
|
-
* // opt user out
|
|
11442
|
-
* mixpanel.opt_out_tracking();
|
|
11443
|
-
*
|
|
11444
|
-
* // opt user out with different cookie configuration from Mixpanel instance
|
|
11445
|
-
* mixpanel.opt_out_tracking({
|
|
11446
|
-
* cookie_expiration: 30,
|
|
11447
|
-
* secure_cookie: true
|
|
11448
|
-
* });
|
|
11449
|
-
*
|
|
11450
|
-
* @param {Object} [options] A dictionary of config options to override
|
|
11451
|
-
* @param {boolean} [options.delete_user=true] If true, will delete the currently identified user's profile and clear all charges after opting the user out
|
|
11452
|
-
* @param {boolean} [options.clear_persistence=true] If true, will delete all data stored by the sdk in persistence
|
|
11453
|
-
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11454
|
-
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11455
|
-
* @param {Number} [options.cookie_expiration] Number of days until the opt-in cookie expires (overrides value specified in this Mixpanel instance's config)
|
|
11456
|
-
* @param {string} [options.cookie_domain] Custom cookie domain (overrides value specified in this Mixpanel instance's config)
|
|
11457
|
-
* @param {boolean} [options.cross_site_cookie] Whether the opt-in cookie is set as cross-site-enabled (overrides value specified in this Mixpanel instance's config)
|
|
11458
|
-
* @param {boolean} [options.cross_subdomain_cookie] Whether the opt-in cookie is set as cross-subdomain or not (overrides value specified in this Mixpanel instance's config)
|
|
11459
|
-
* @param {boolean} [options.secure_cookie] Whether the opt-in cookie is set as secure or not (overrides value specified in this Mixpanel instance's config)
|
|
11460
|
-
*/
|
|
11461
|
-
MixpanelLib.prototype.opt_out_tracking = function(options) {
|
|
11462
|
-
options = _.extend({
|
|
11463
|
-
'clear_persistence': true,
|
|
11464
|
-
'delete_user': true
|
|
11465
|
-
}, options);
|
|
11466
|
-
|
|
11467
|
-
// delete user and clear charges since these methods may be disabled by opt-out
|
|
11468
|
-
if (options['delete_user'] && this['people'] && this['people']._identify_called()) {
|
|
11469
|
-
this['people'].delete_user();
|
|
11470
|
-
this['people'].clear_charges();
|
|
11471
|
-
}
|
|
11472
|
-
|
|
11473
|
-
this._gdpr_call_func(optOut, options);
|
|
11474
|
-
this._gdpr_update_persistence(options);
|
|
11475
|
-
};
|
|
11476
|
-
|
|
11477
|
-
/**
|
|
11478
|
-
* Check whether the user has opted in to data tracking and cookies/localstorage for this Mixpanel instance
|
|
11479
|
-
*
|
|
11480
|
-
* ### Usage
|
|
11481
|
-
*
|
|
11482
|
-
* var has_opted_in = mixpanel.has_opted_in_tracking();
|
|
11483
|
-
* // use has_opted_in value
|
|
11484
|
-
*
|
|
11485
|
-
* @param {Object} [options] A dictionary of config options to override
|
|
11486
|
-
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11487
|
-
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11488
|
-
* @returns {boolean} current opt-in status
|
|
11489
|
-
*/
|
|
11490
|
-
MixpanelLib.prototype.has_opted_in_tracking = function(options) {
|
|
11491
|
-
return this._gdpr_call_func(hasOptedIn, options);
|
|
11492
|
-
};
|
|
11493
|
-
|
|
11494
|
-
/**
|
|
11495
|
-
* Check whether the user has opted out of data tracking and cookies/localstorage for this Mixpanel instance
|
|
11496
|
-
*
|
|
11497
|
-
* ### Usage
|
|
11498
|
-
*
|
|
11499
|
-
* var has_opted_out = mixpanel.has_opted_out_tracking();
|
|
11500
|
-
* // use has_opted_out value
|
|
11501
|
-
*
|
|
11502
|
-
* @param {Object} [options] A dictionary of config options to override
|
|
11503
|
-
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11504
|
-
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11505
|
-
* @returns {boolean} current opt-out status
|
|
11506
|
-
*/
|
|
11507
|
-
MixpanelLib.prototype.has_opted_out_tracking = function(options) {
|
|
11508
|
-
return this._gdpr_call_func(hasOptedOut, options);
|
|
11509
|
-
};
|
|
11510
|
-
|
|
11511
|
-
/**
|
|
11512
|
-
* Clear the user's opt in/out status of data tracking and cookies/localstorage for this Mixpanel instance
|
|
11513
|
-
*
|
|
11514
|
-
* ### Usage
|
|
11515
|
-
*
|
|
11516
|
-
* // clear user's opt-in/out status
|
|
11517
|
-
* mixpanel.clear_opt_in_out_tracking();
|
|
11518
|
-
*
|
|
11519
|
-
* // clear user's opt-in/out status with specific cookie configuration - should match
|
|
11520
|
-
* // configuration used when opt_in_tracking/opt_out_tracking methods were called.
|
|
11521
|
-
* mixpanel.clear_opt_in_out_tracking({
|
|
11522
|
-
* cookie_expiration: 30,
|
|
11523
|
-
* secure_cookie: true
|
|
11524
|
-
* });
|
|
11525
|
-
*
|
|
11526
|
-
* @param {Object} [options] A dictionary of config options to override
|
|
11527
|
-
* @param {boolean} [options.enable_persistence=true] If true, will re-enable sdk persistence
|
|
11528
|
-
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11529
|
-
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11530
|
-
* @param {Number} [options.cookie_expiration] Number of days until the opt-in cookie expires (overrides value specified in this Mixpanel instance's config)
|
|
11531
|
-
* @param {string} [options.cookie_domain] Custom cookie domain (overrides value specified in this Mixpanel instance's config)
|
|
11532
|
-
* @param {boolean} [options.cross_site_cookie] Whether the opt-in cookie is set as cross-site-enabled (overrides value specified in this Mixpanel instance's config)
|
|
11533
|
-
* @param {boolean} [options.cross_subdomain_cookie] Whether the opt-in cookie is set as cross-subdomain or not (overrides value specified in this Mixpanel instance's config)
|
|
11534
|
-
* @param {boolean} [options.secure_cookie] Whether the opt-in cookie is set as secure or not (overrides value specified in this Mixpanel instance's config)
|
|
11535
|
-
*/
|
|
11536
|
-
MixpanelLib.prototype.clear_opt_in_out_tracking = function(options) {
|
|
11537
|
-
options = _.extend({
|
|
11538
|
-
'enable_persistence': true
|
|
11539
|
-
}, options);
|
|
11540
|
-
|
|
11541
|
-
this._gdpr_call_func(clearOptInOut, options);
|
|
11542
|
-
this._gdpr_update_persistence(options);
|
|
11543
|
-
};
|
|
11544
|
-
|
|
11545
|
-
MixpanelLib.prototype.report_error = function(msg, err) {
|
|
11546
|
-
console$1.error.apply(console$1.error, arguments);
|
|
11547
|
-
try {
|
|
11548
|
-
if (!err && !(msg instanceof Error)) {
|
|
11549
|
-
msg = new Error(msg);
|
|
11550
|
-
}
|
|
11551
|
-
this.get_config('error_reporter')(msg, err);
|
|
11552
|
-
} catch(err) {
|
|
11553
|
-
console$1.error(err);
|
|
11554
|
-
}
|
|
11555
|
-
};
|
|
11556
|
-
|
|
11557
|
-
// EXPORTS (for closure compiler)
|
|
11558
|
-
|
|
11559
|
-
// MixpanelLib Exports
|
|
11560
|
-
MixpanelLib.prototype['init'] = MixpanelLib.prototype.init;
|
|
11561
|
-
MixpanelLib.prototype['reset'] = MixpanelLib.prototype.reset;
|
|
11562
|
-
MixpanelLib.prototype['disable'] = MixpanelLib.prototype.disable;
|
|
11563
|
-
MixpanelLib.prototype['time_event'] = MixpanelLib.prototype.time_event;
|
|
11564
|
-
MixpanelLib.prototype['track'] = MixpanelLib.prototype.track;
|
|
11565
|
-
MixpanelLib.prototype['track_links'] = MixpanelLib.prototype.track_links;
|
|
11566
|
-
MixpanelLib.prototype['track_forms'] = MixpanelLib.prototype.track_forms;
|
|
11567
|
-
MixpanelLib.prototype['track_pageview'] = MixpanelLib.prototype.track_pageview;
|
|
11568
|
-
MixpanelLib.prototype['register'] = MixpanelLib.prototype.register;
|
|
11569
|
-
MixpanelLib.prototype['register_once'] = MixpanelLib.prototype.register_once;
|
|
11570
|
-
MixpanelLib.prototype['unregister'] = MixpanelLib.prototype.unregister;
|
|
11571
|
-
MixpanelLib.prototype['identify'] = MixpanelLib.prototype.identify;
|
|
11572
|
-
MixpanelLib.prototype['alias'] = MixpanelLib.prototype.alias;
|
|
11573
|
-
MixpanelLib.prototype['name_tag'] = MixpanelLib.prototype.name_tag;
|
|
11574
|
-
MixpanelLib.prototype['set_config'] = MixpanelLib.prototype.set_config;
|
|
11575
|
-
MixpanelLib.prototype['get_config'] = MixpanelLib.prototype.get_config;
|
|
11576
|
-
MixpanelLib.prototype['get_property'] = MixpanelLib.prototype.get_property;
|
|
11577
|
-
MixpanelLib.prototype['get_distinct_id'] = MixpanelLib.prototype.get_distinct_id;
|
|
11578
|
-
MixpanelLib.prototype['toString'] = MixpanelLib.prototype.toString;
|
|
11579
|
-
MixpanelLib.prototype['opt_out_tracking'] = MixpanelLib.prototype.opt_out_tracking;
|
|
11580
|
-
MixpanelLib.prototype['opt_in_tracking'] = MixpanelLib.prototype.opt_in_tracking;
|
|
11581
|
-
MixpanelLib.prototype['has_opted_out_tracking'] = MixpanelLib.prototype.has_opted_out_tracking;
|
|
11582
|
-
MixpanelLib.prototype['has_opted_in_tracking'] = MixpanelLib.prototype.has_opted_in_tracking;
|
|
11583
|
-
MixpanelLib.prototype['clear_opt_in_out_tracking'] = MixpanelLib.prototype.clear_opt_in_out_tracking;
|
|
11584
|
-
MixpanelLib.prototype['get_group'] = MixpanelLib.prototype.get_group;
|
|
11585
|
-
MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
|
|
11586
|
-
MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
|
|
11587
|
-
MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
|
|
11588
|
-
MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
|
|
11589
|
-
MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
|
|
11590
|
-
MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;
|
|
11591
|
-
|
|
11592
|
-
// MixpanelPersistence Exports
|
|
11593
|
-
MixpanelPersistence.prototype['properties'] = MixpanelPersistence.prototype.properties;
|
|
11594
|
-
MixpanelPersistence.prototype['update_search_keyword'] = MixpanelPersistence.prototype.update_search_keyword;
|
|
11595
|
-
MixpanelPersistence.prototype['update_referrer_info'] = MixpanelPersistence.prototype.update_referrer_info;
|
|
11596
|
-
MixpanelPersistence.prototype['get_cross_subdomain'] = MixpanelPersistence.prototype.get_cross_subdomain;
|
|
11597
|
-
MixpanelPersistence.prototype['clear'] = MixpanelPersistence.prototype.clear;
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
var instances = {};
|
|
11601
|
-
var extend_mp = function() {
|
|
11602
|
-
// add all the sub mixpanel instances
|
|
11603
|
-
_.each(instances, function(instance, name) {
|
|
11604
|
-
if (name !== PRIMARY_INSTANCE_NAME) { mixpanel_master[name] = instance; }
|
|
11605
|
-
});
|
|
11606
|
-
|
|
11607
|
-
// add private functions as _
|
|
11608
|
-
mixpanel_master['_'] = _;
|
|
11609
|
-
};
|
|
11610
|
-
|
|
11611
|
-
var override_mp_init_func = function() {
|
|
11612
|
-
// we override the snippets init function to handle the case where a
|
|
11613
|
-
// user initializes the mixpanel library after the script loads & runs
|
|
11614
|
-
mixpanel_master['init'] = function(token, config, name) {
|
|
11615
|
-
if (name) {
|
|
11616
|
-
// initialize a sub library
|
|
11617
|
-
if (!mixpanel_master[name]) {
|
|
11618
|
-
mixpanel_master[name] = instances[name] = create_mplib(token, config, name);
|
|
11619
|
-
mixpanel_master[name]._loaded();
|
|
11620
|
-
}
|
|
11621
|
-
return mixpanel_master[name];
|
|
11622
|
-
} else {
|
|
11623
|
-
var instance = mixpanel_master;
|
|
11624
|
-
|
|
11625
|
-
if (instances[PRIMARY_INSTANCE_NAME]) {
|
|
11626
|
-
// main mixpanel lib already initialized
|
|
11627
|
-
instance = instances[PRIMARY_INSTANCE_NAME];
|
|
11628
|
-
} else if (token) {
|
|
11629
|
-
// intialize the main mixpanel lib
|
|
11630
|
-
instance = create_mplib(token, config, PRIMARY_INSTANCE_NAME);
|
|
11631
|
-
instance._loaded();
|
|
11632
|
-
instances[PRIMARY_INSTANCE_NAME] = instance;
|
|
11633
|
-
}
|
|
11634
|
-
|
|
11635
|
-
mixpanel_master = instance;
|
|
11636
|
-
if (init_type === INIT_SNIPPET) {
|
|
11637
|
-
window$1[PRIMARY_INSTANCE_NAME] = mixpanel_master;
|
|
11638
|
-
}
|
|
11639
|
-
extend_mp();
|
|
11640
|
-
}
|
|
11641
|
-
};
|
|
11642
|
-
};
|
|
11643
|
-
|
|
11644
|
-
var add_dom_loaded_handler = function() {
|
|
11645
|
-
// Cross browser DOM Loaded support
|
|
11646
|
-
function dom_loaded_handler() {
|
|
11647
|
-
// function flag since we only want to execute this once
|
|
11648
|
-
if (dom_loaded_handler.done) { return; }
|
|
11649
|
-
dom_loaded_handler.done = true;
|
|
11650
|
-
|
|
11651
|
-
DOM_LOADED = true;
|
|
11652
|
-
ENQUEUE_REQUESTS = false;
|
|
11653
|
-
|
|
11654
|
-
_.each(instances, function(inst) {
|
|
11655
|
-
inst._dom_loaded();
|
|
11656
|
-
});
|
|
11657
|
-
}
|
|
11658
|
-
|
|
11659
|
-
function do_scroll_check() {
|
|
11660
|
-
try {
|
|
11661
|
-
document$1.documentElement.doScroll('left');
|
|
11662
|
-
} catch(e) {
|
|
11663
|
-
setTimeout(do_scroll_check, 1);
|
|
11664
|
-
return;
|
|
11665
|
-
}
|
|
11666
|
-
|
|
11667
|
-
dom_loaded_handler();
|
|
11668
|
-
}
|
|
11669
|
-
|
|
11670
|
-
if (document$1.addEventListener) {
|
|
11671
|
-
if (document$1.readyState === 'complete') {
|
|
11672
|
-
// safari 4 can fire the DOMContentLoaded event before loading all
|
|
11673
|
-
// external JS (including this file). you will see some copypasta
|
|
11674
|
-
// on the internet that checks for 'complete' and 'loaded', but
|
|
11675
|
-
// 'loaded' is an IE thing
|
|
11676
|
-
dom_loaded_handler();
|
|
11677
|
-
} else {
|
|
11678
|
-
document$1.addEventListener('DOMContentLoaded', dom_loaded_handler, false);
|
|
11679
|
-
}
|
|
11680
|
-
} else if (document$1.attachEvent) {
|
|
11681
|
-
// IE
|
|
11682
|
-
document$1.attachEvent('onreadystatechange', dom_loaded_handler);
|
|
11683
|
-
|
|
11684
|
-
// check to make sure we arn't in a frame
|
|
11685
|
-
var toplevel = false;
|
|
11686
|
-
try {
|
|
11687
|
-
toplevel = window$1.frameElement === null;
|
|
11688
|
-
} catch(e) {
|
|
11689
|
-
// noop
|
|
11690
|
-
}
|
|
11691
|
-
|
|
11692
|
-
if (document$1.documentElement.doScroll && toplevel) {
|
|
11693
|
-
do_scroll_check();
|
|
11694
|
-
}
|
|
11695
|
-
}
|
|
11696
|
-
|
|
11697
|
-
// fallback handler, always will work
|
|
11698
|
-
_.register_event(window$1, 'load', dom_loaded_handler, true);
|
|
11699
|
-
};
|
|
11700
|
-
|
|
11701
|
-
function init_as_module() {
|
|
11702
|
-
init_type = INIT_MODULE;
|
|
11703
|
-
mixpanel_master = new MixpanelLib();
|
|
11704
|
-
|
|
11705
|
-
override_mp_init_func();
|
|
11706
|
-
mixpanel_master['init']();
|
|
11707
|
-
add_dom_loaded_handler();
|
|
11708
|
-
|
|
11709
|
-
return mixpanel_master;
|
|
11710
|
-
}
|
|
11711
|
-
|
|
11712
|
-
var mixpanel = init_as_module();
|
|
11713
|
-
|
|
11714
|
-
var mixpanel_cjs = mixpanel;
|
|
11715
|
-
|
|
11716
|
-
var mixpanel$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null), mixpanel_cjs, {
|
|
11717
|
-
'default': mixpanel_cjs
|
|
11718
|
-
}));
|
|
11719
|
-
|
|
11720
|
-
// Needed to avoid error in CJS builds on some bundlers.
|
|
11721
|
-
const mixpanelLib = mixpanel_cjs || mixpanel$1;
|
|
11722
|
-
let mixpanelInstance;
|
|
11723
|
-
const MIXPANEL_EVENT = {
|
|
11724
|
-
VISUAL_SDK_RENDER_START: 'visual-sdk-render-start',
|
|
11725
|
-
VISUAL_SDK_CALLED_INIT: 'visual-sdk-called-init',
|
|
11726
|
-
VISUAL_SDK_RENDER_COMPLETE: 'visual-sdk-render-complete',
|
|
11727
|
-
VISUAL_SDK_RENDER_FAILED: 'visual-sdk-render-failed',
|
|
11728
|
-
VISUAL_SDK_TRIGGER: 'visual-sdk-trigger',
|
|
11729
|
-
VISUAL_SDK_ON: 'visual-sdk-on',
|
|
11730
|
-
VISUAL_SDK_IFRAME_LOAD_PERFORMANCE: 'visual-sdk-iframe-load-performance',
|
|
11731
|
-
VISUAL_SDK_EMBED_CREATE: 'visual-sdk-embed-create',
|
|
11732
|
-
};
|
|
11733
|
-
let isMixpanelInitialized = false;
|
|
11734
|
-
let eventQueue = [];
|
|
11735
|
-
/**
|
|
11736
|
-
* Pushes the event with its Property key-value map to mixpanel.
|
|
11737
|
-
*
|
|
11738
|
-
* @param eventId
|
|
11739
|
-
* @param eventProps
|
|
11740
|
-
*/
|
|
11741
|
-
function uploadMixpanelEvent(eventId, eventProps = {}) {
|
|
11742
|
-
if (!isMixpanelInitialized) {
|
|
11743
|
-
eventQueue.push({ eventId, eventProps });
|
|
11744
|
-
return;
|
|
11745
|
-
}
|
|
11746
|
-
mixpanelInstance.track(eventId, eventProps);
|
|
11747
|
-
}
|
|
11748
|
-
/**
|
|
11749
|
-
*
|
|
11750
|
-
*/
|
|
11751
|
-
function emptyQueue() {
|
|
11752
|
-
if (!isMixpanelInitialized) {
|
|
11753
|
-
return;
|
|
11754
|
-
}
|
|
11755
|
-
eventQueue.forEach((event) => {
|
|
11756
|
-
uploadMixpanelEvent(event.eventId, event.eventProps);
|
|
11757
|
-
});
|
|
11758
|
-
eventQueue = [];
|
|
11759
|
-
}
|
|
11760
|
-
/**
|
|
11761
|
-
*
|
|
11762
|
-
* @param sessionInfo
|
|
11763
|
-
*/
|
|
11764
|
-
function initMixpanel(sessionInfo) {
|
|
11765
|
-
var _a;
|
|
11766
|
-
if (!sessionInfo || !sessionInfo.mixpanelToken) {
|
|
11767
|
-
return;
|
|
11768
|
-
}
|
|
11769
|
-
// On a public cluster the user is anonymous, so don't set the identify to
|
|
11770
|
-
// userGUID
|
|
11771
|
-
const isPublicCluster = !!sessionInfo.isPublicUser;
|
|
11772
|
-
const token = sessionInfo.mixpanelToken;
|
|
11773
|
-
try {
|
|
11774
|
-
if (token) {
|
|
11775
|
-
mixpanelInstance = mixpanelLib.init(token, undefined, 'tsEmbed');
|
|
11776
|
-
if (!isPublicCluster) {
|
|
11777
|
-
mixpanelInstance.identify(sessionInfo.userGUID);
|
|
11778
|
-
}
|
|
11779
|
-
mixpanelInstance.register_once({
|
|
11780
|
-
clusterId: sessionInfo.clusterId,
|
|
11781
|
-
clusterName: sessionInfo.clusterName,
|
|
11782
|
-
releaseVersion: sessionInfo.releaseVersion,
|
|
11783
|
-
hostAppUrl: ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.host) || '',
|
|
11784
|
-
});
|
|
11785
|
-
isMixpanelInitialized = true;
|
|
11786
|
-
emptyQueue();
|
|
11787
|
-
}
|
|
11788
|
-
}
|
|
11789
|
-
catch (e) {
|
|
11790
|
-
logger.error('Error initializing mixpanel', e);
|
|
11791
|
-
}
|
|
11792
|
-
}
|
|
11793
|
-
|
|
11794
|
-
let config = {};
|
|
11795
|
-
/**
|
|
11796
|
-
* Gets the configuration embed was initialized with.
|
|
11797
|
-
*
|
|
11798
|
-
* @returns {@link EmbedConfig} The configuration embed was initialized with.
|
|
11799
|
-
* @version SDK: 1.19.0 | ThoughtSpot: *
|
|
11800
|
-
* @group Global methods
|
|
11801
|
-
*/
|
|
11802
|
-
const getEmbedConfig = () => config;
|
|
11803
|
-
/**
|
|
11804
|
-
* Sets the configuration embed was initialized with.
|
|
11805
|
-
* And returns the new configuration.
|
|
11806
|
-
*
|
|
11807
|
-
* @param newConfig The configuration to set.
|
|
11808
|
-
* @version SDK: 1.27.0 | ThoughtSpot: *
|
|
11809
|
-
* @group Global methods
|
|
11810
|
-
*/
|
|
11811
|
-
const setEmbedConfig = (newConfig) => {
|
|
11812
|
-
config = newConfig;
|
|
11813
|
-
return newConfig;
|
|
11814
|
-
};
|
|
11815
|
-
|
|
11816
|
-
const tokenizedFetch = async (input, init) => {
|
|
11817
|
-
const embedConfig = getEmbedConfig();
|
|
11818
|
-
if (embedConfig.authType !== exports.AuthType.TrustedAuthTokenCookieless) {
|
|
11819
|
-
return fetch(input, init);
|
|
11820
|
-
}
|
|
11821
|
-
const req = new Request(input, init);
|
|
11822
|
-
const authToken = await getAuthenticationToken(embedConfig);
|
|
11823
|
-
if (authToken) {
|
|
11824
|
-
req.headers.append('Authorization', `Bearer ${authToken}`);
|
|
11825
|
-
}
|
|
11826
|
-
return fetch(req);
|
|
11827
|
-
};
|
|
11828
|
-
|
|
11829
|
-
/**
|
|
11830
|
-
*
|
|
11831
|
-
* @param url
|
|
11832
|
-
* @param options
|
|
11833
|
-
*/
|
|
11834
|
-
function tokenisedFailureLoggedFetch(url, options = {}) {
|
|
11835
|
-
return tokenizedFetch(url, options).then(async (r) => {
|
|
11836
|
-
var _a;
|
|
11837
|
-
if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
|
|
11838
|
-
logger.error('Failure', await ((_a = r.text) === null || _a === void 0 ? void 0 : _a.call(r)));
|
|
11839
|
-
}
|
|
11840
|
-
return r;
|
|
11841
|
-
});
|
|
11842
|
-
}
|
|
11843
|
-
/**
|
|
11844
|
-
*
|
|
11845
|
-
* @param authVerificationUrl
|
|
11846
|
-
*/
|
|
11847
|
-
function fetchSessionInfoService(authVerificationUrl) {
|
|
11848
|
-
return tokenisedFailureLoggedFetch(authVerificationUrl, {
|
|
11849
|
-
credentials: 'include',
|
|
11850
|
-
});
|
|
11851
|
-
}
|
|
11852
|
-
/**
|
|
11853
|
-
*
|
|
11854
|
-
* @param thoughtSpotHost
|
|
11855
|
-
*/
|
|
11856
|
-
async function fetchLogoutService(thoughtSpotHost) {
|
|
11857
|
-
return tokenisedFailureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
|
|
11858
|
-
credentials: 'include',
|
|
11859
|
-
method: 'POST',
|
|
11860
|
-
headers: {
|
|
11861
|
-
'x-requested-by': 'ThoughtSpot',
|
|
11862
|
-
},
|
|
11863
|
-
});
|
|
11864
|
-
}
|
|
11865
|
-
|
|
11866
|
-
// eslint-disable-next-line import/no-mutable-exports
|
|
11867
|
-
let loggedInStatus = false;
|
|
11868
|
-
// eslint-disable-next-line import/no-mutable-exports
|
|
11869
|
-
let samlAuthWindow = null;
|
|
11870
|
-
// eslint-disable-next-line import/no-mutable-exports
|
|
11871
|
-
let samlCompletionPromise = null;
|
|
11872
|
-
let sessionInfo = null;
|
|
11873
|
-
let sessionInfoResolver = null;
|
|
11874
|
-
const sessionInfoPromise = new Promise((resolve) => {
|
|
11875
|
-
sessionInfoResolver = resolve;
|
|
11876
|
-
});
|
|
11877
|
-
let releaseVersion = '';
|
|
11878
|
-
const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
|
|
11879
|
-
(function (AuthFailureType) {
|
|
11880
|
-
AuthFailureType["SDK"] = "SDK";
|
|
11881
|
-
AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
|
|
11882
|
-
AuthFailureType["EXPIRY"] = "EXPIRY";
|
|
11883
|
-
AuthFailureType["OTHER"] = "OTHER";
|
|
11884
|
-
})(exports.AuthFailureType || (exports.AuthFailureType = {}));
|
|
11885
|
-
(function (AuthStatus) {
|
|
11886
|
-
/**
|
|
11887
|
-
* Emits when the SDK fails to authenticate
|
|
11888
|
-
*/
|
|
11889
|
-
AuthStatus["FAILURE"] = "FAILURE";
|
|
11890
|
-
/**
|
|
11891
|
-
* Emits when the SDK authenticates successfully
|
|
11892
|
-
*/
|
|
11893
|
-
AuthStatus["SDK_SUCCESS"] = "SDK_SUCCESS";
|
|
11894
|
-
/**
|
|
11895
|
-
* Emits when the app sends an authentication success message
|
|
11896
|
-
*/
|
|
11897
|
-
AuthStatus["SUCCESS"] = "SUCCESS";
|
|
11898
|
-
/**
|
|
11899
|
-
* Emits when a user logs out
|
|
11900
|
-
*/
|
|
11901
|
-
AuthStatus["LOGOUT"] = "LOGOUT";
|
|
11902
|
-
/**
|
|
11903
|
-
* Emitted when inPopup is true in the SAMLRedirect flow and the
|
|
11904
|
-
* popup is waiting to be triggered either programmatically
|
|
11905
|
-
* or by the trigger button.
|
|
11906
|
-
*
|
|
11907
|
-
* @version SDK: 1.19.0
|
|
11908
|
-
*/
|
|
11909
|
-
AuthStatus["WAITING_FOR_POPUP"] = "WAITING_FOR_POPUP";
|
|
11910
|
-
})(exports.AuthStatus || (exports.AuthStatus = {}));
|
|
11911
|
-
(function (AuthEvent) {
|
|
11912
|
-
/**
|
|
11913
|
-
* Manually trigger the SSO popup. This is useful when
|
|
11914
|
-
* authStatus is SAMLRedirect/OIDCRedirect and inPopup is set to true
|
|
11915
|
-
*/
|
|
11916
|
-
AuthEvent["TRIGGER_SSO_POPUP"] = "TRIGGER_SSO_POPUP";
|
|
11917
|
-
})(exports.AuthEvent || (exports.AuthEvent = {}));
|
|
11918
|
-
let authEE;
|
|
11919
|
-
/**
|
|
11920
|
-
*
|
|
11921
|
-
* @param eventEmitter
|
|
11922
|
-
*/
|
|
11923
|
-
function setAuthEE(eventEmitter) {
|
|
11924
|
-
authEE = eventEmitter;
|
|
11925
|
-
}
|
|
11926
|
-
/**
|
|
11927
|
-
*
|
|
11928
|
-
*/
|
|
11929
|
-
function notifyAuthSDKSuccess() {
|
|
11930
|
-
if (!authEE) {
|
|
11931
|
-
logger.error('SDK not initialized');
|
|
11932
|
-
return;
|
|
11933
|
-
}
|
|
11934
|
-
authEE.emit(exports.AuthStatus.SDK_SUCCESS);
|
|
11935
|
-
}
|
|
11936
|
-
/**
|
|
11937
|
-
*
|
|
11938
|
-
*/
|
|
11939
|
-
function notifyAuthSuccess() {
|
|
11940
|
-
if (!authEE) {
|
|
11941
|
-
logger.error('SDK not initialized');
|
|
11942
|
-
return;
|
|
11943
|
-
}
|
|
11944
|
-
authEE.emit(exports.AuthStatus.SUCCESS, sessionInfo);
|
|
11945
|
-
}
|
|
11946
|
-
/**
|
|
11947
|
-
*
|
|
11948
|
-
* @param failureType
|
|
11949
|
-
*/
|
|
11950
|
-
function notifyAuthFailure(failureType) {
|
|
11951
|
-
if (!authEE) {
|
|
11952
|
-
logger.error('SDK not initialized');
|
|
11953
|
-
return;
|
|
11954
|
-
}
|
|
11955
|
-
authEE.emit(exports.AuthStatus.FAILURE, failureType);
|
|
11956
|
-
}
|
|
11957
|
-
/**
|
|
11958
|
-
*
|
|
11959
|
-
*/
|
|
11960
|
-
function notifyLogout() {
|
|
11961
|
-
if (!authEE) {
|
|
11962
|
-
logger.error('SDK not initialized');
|
|
11963
|
-
return;
|
|
11964
|
-
}
|
|
11965
|
-
authEE.emit(exports.AuthStatus.LOGOUT);
|
|
11966
|
-
}
|
|
11967
|
-
const initSession = (sessionDetails) => {
|
|
11968
|
-
if (sessionInfo == null) {
|
|
11969
|
-
sessionInfo = sessionDetails;
|
|
11970
|
-
initMixpanel(sessionInfo);
|
|
11971
|
-
sessionInfoResolver(sessionInfo);
|
|
11972
|
-
}
|
|
11973
|
-
};
|
|
11974
|
-
const getSessionDetails = (sessionInfoResp) => {
|
|
11975
|
-
const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
|
|
11976
|
-
const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
|
|
11977
|
-
const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
|
|
11978
|
-
? prodMixpanelToken
|
|
11979
|
-
: devMixpanelToken;
|
|
11980
|
-
return {
|
|
11981
|
-
userGUID: sessionInfoResp.userGUID,
|
|
11982
|
-
mixpanelToken,
|
|
11983
|
-
isPublicUser: sessionInfoResp.configInfo.isPublicUser,
|
|
11984
|
-
releaseVersion: sessionInfoResp.releaseVersion,
|
|
11985
|
-
clusterId: sessionInfoResp.configInfo.selfClusterId,
|
|
11986
|
-
clusterName: sessionInfoResp.configInfo.selfClusterName,
|
|
11987
|
-
...sessionInfoResp,
|
|
11988
|
-
};
|
|
11989
|
-
};
|
|
11990
|
-
/**
|
|
11991
|
-
* Check if we are logged into the ThoughtSpot cluster
|
|
11992
|
-
*
|
|
11993
|
-
* @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
|
|
11994
|
-
*/
|
|
11995
|
-
async function isLoggedIn(thoughtSpotHost) {
|
|
11996
|
-
const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
|
|
11997
|
-
let response = null;
|
|
11998
|
-
try {
|
|
11999
|
-
response = await fetchSessionInfoService(authVerificationUrl);
|
|
12000
|
-
const sessionInfoResp = await response.json();
|
|
12001
|
-
const sessionDetails = getSessionDetails(sessionInfoResp);
|
|
12002
|
-
// Store user session details from session info
|
|
12003
|
-
initSession(sessionDetails);
|
|
12004
|
-
releaseVersion = sessionInfoResp.releaseVersion;
|
|
12005
|
-
}
|
|
12006
|
-
catch (e) {
|
|
12007
|
-
return false;
|
|
12008
|
-
}
|
|
12009
|
-
return response.status === 200;
|
|
12010
|
-
}
|
|
12011
|
-
/**
|
|
12012
|
-
* Return releaseVersion if available
|
|
12013
|
-
*/
|
|
12014
|
-
function getReleaseVersion() {
|
|
12015
|
-
return releaseVersion;
|
|
12016
|
-
}
|
|
12017
|
-
/**
|
|
12018
|
-
* Return a promise that resolves with the session information when
|
|
12019
|
-
* authentication is successful. And info is available.
|
|
12020
|
-
*
|
|
12021
|
-
* @group Global methods
|
|
12022
|
-
*/
|
|
12023
|
-
function getSessionInfo() {
|
|
12024
|
-
return sessionInfoPromise;
|
|
12025
|
-
}
|
|
12026
|
-
/**
|
|
12027
|
-
* Check if we are stuck at the SSO redirect URL
|
|
12028
|
-
*/
|
|
12029
|
-
function isAtSSORedirectUrl() {
|
|
12030
|
-
return window.location.href.indexOf(SSO_REDIRECTION_MARKER_GUID) >= 0;
|
|
12031
|
-
}
|
|
12032
|
-
/**
|
|
12033
|
-
* Remove the SSO redirect URL marker
|
|
12034
|
-
*/
|
|
12035
|
-
function removeSSORedirectUrlMarker() {
|
|
12036
|
-
// Note (sunny): This will leave a # around even if it was not in the URL
|
|
12037
|
-
// to begin with. Trying to remove the hash by changing window.location will
|
|
12038
|
-
// reload the page which we don't want. We'll live with adding an
|
|
12039
|
-
// unnecessary hash to the parent page URL until we find any use case where
|
|
12040
|
-
// that creates an issue.
|
|
12041
|
-
window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
|
|
12042
|
-
}
|
|
12043
|
-
/**
|
|
12044
|
-
* Perform token based authentication
|
|
12045
|
-
*
|
|
12046
|
-
* @param embedConfig The embed configuration
|
|
12047
|
-
*/
|
|
12048
|
-
const doTokenAuth = async (embedConfig) => {
|
|
12049
|
-
const { thoughtSpotHost, username, authEndpoint, getAuthToken, } = embedConfig;
|
|
12050
|
-
if (!authEndpoint && !getAuthToken) {
|
|
12051
|
-
throw new Error('Either auth endpoint or getAuthToken function must be provided');
|
|
12052
|
-
}
|
|
12053
|
-
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
12054
|
-
if (!loggedInStatus) {
|
|
12055
|
-
const authToken = await getAuthenticationToken(embedConfig);
|
|
12056
|
-
let resp;
|
|
12057
|
-
try {
|
|
12058
|
-
resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
|
|
12059
|
-
}
|
|
12060
|
-
catch (e) {
|
|
12061
|
-
resp = await fetchAuthService(thoughtSpotHost, username, authToken);
|
|
12062
|
-
}
|
|
12063
|
-
// token login issues a 302 when successful
|
|
12064
|
-
loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
|
|
12065
|
-
if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
|
|
12066
|
-
// When 3rd party cookie access is blocked, this will fail because
|
|
12067
|
-
// cookies will not be sent with the call.
|
|
12068
|
-
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
12069
|
-
}
|
|
12070
|
-
}
|
|
12071
|
-
return loggedInStatus;
|
|
12072
|
-
};
|
|
12073
|
-
/**
|
|
12074
|
-
* Validate embedConfig parameters required for cookielessTokenAuth
|
|
12075
|
-
*
|
|
12076
|
-
* @param embedConfig The embed configuration
|
|
12077
|
-
*/
|
|
12078
|
-
const doCookielessTokenAuth = async (embedConfig) => {
|
|
12079
|
-
const { authEndpoint, getAuthToken } = embedConfig;
|
|
12080
|
-
if (!authEndpoint && !getAuthToken) {
|
|
12081
|
-
throw new Error('Either auth endpoint or getAuthToken function must be provided');
|
|
12082
|
-
}
|
|
12083
|
-
let authSuccess = false;
|
|
12084
|
-
try {
|
|
12085
|
-
const authToken = await getAuthenticationToken(embedConfig);
|
|
12086
|
-
if (authToken) {
|
|
12087
|
-
authSuccess = true;
|
|
12088
|
-
}
|
|
12089
|
-
}
|
|
12090
|
-
catch {
|
|
12091
|
-
authSuccess = false;
|
|
12092
|
-
}
|
|
12093
|
-
return authSuccess;
|
|
12094
|
-
};
|
|
12095
|
-
/**
|
|
12096
|
-
* Perform basic authentication to the ThoughtSpot cluster using the cluster
|
|
12097
|
-
* credentials.
|
|
12098
|
-
*
|
|
12099
|
-
* Warning: This feature is primarily intended for developer testing. It is
|
|
12100
|
-
* strongly advised not to use this authentication method in production.
|
|
12101
|
-
*
|
|
12102
|
-
* @param embedConfig The embed configuration
|
|
12103
|
-
*/
|
|
12104
|
-
const doBasicAuth = async (embedConfig) => {
|
|
12105
|
-
const { thoughtSpotHost, username, password } = embedConfig;
|
|
12106
|
-
const loggedIn = await isLoggedIn(thoughtSpotHost);
|
|
12107
|
-
if (!loggedIn) {
|
|
12108
|
-
const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
|
|
12109
|
-
loggedInStatus = response.ok;
|
|
12110
|
-
if (embedConfig.detectCookieAccessSlow) {
|
|
12111
|
-
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
12112
|
-
}
|
|
12113
|
-
}
|
|
12114
|
-
else {
|
|
12115
|
-
loggedInStatus = true;
|
|
12116
|
-
}
|
|
12117
|
-
return loggedInStatus;
|
|
12118
|
-
};
|
|
12119
|
-
/**
|
|
12120
|
-
*
|
|
12121
|
-
* @param ssoURL
|
|
12122
|
-
* @param triggerContainer
|
|
12123
|
-
* @param triggerText
|
|
12124
|
-
*/
|
|
12125
|
-
async function samlPopupFlow(ssoURL, triggerContainer, triggerText) {
|
|
12126
|
-
const openPopup = () => {
|
|
12127
|
-
if (samlAuthWindow === null || samlAuthWindow.closed) {
|
|
12128
|
-
samlAuthWindow = window.open(ssoURL, '_blank', 'location=no,height=570,width=520,scrollbars=yes,status=yes');
|
|
12129
|
-
}
|
|
12130
|
-
else {
|
|
12131
|
-
samlAuthWindow.focus();
|
|
12132
|
-
}
|
|
12133
|
-
};
|
|
12134
|
-
authEE === null || authEE === void 0 ? void 0 : authEE.emit(exports.AuthStatus.WAITING_FOR_POPUP);
|
|
12135
|
-
const containerEl = getDOMNode(triggerContainer);
|
|
12136
|
-
if (containerEl) {
|
|
12137
|
-
containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
|
|
12138
|
-
const authElem = document.getElementById('ts-auth-btn');
|
|
12139
|
-
authElem.textContent = triggerText;
|
|
12140
|
-
authElem.addEventListener('click', openPopup, { once: true });
|
|
12141
|
-
}
|
|
12142
|
-
samlCompletionPromise = samlCompletionPromise
|
|
12143
|
-
|| new Promise((resolve, reject) => {
|
|
12144
|
-
window.addEventListener('message', (e) => {
|
|
12145
|
-
if (e.data.type === exports.EmbedEvent.SAMLComplete) {
|
|
12146
|
-
e.source.close();
|
|
12147
|
-
resolve();
|
|
12148
|
-
}
|
|
12149
|
-
});
|
|
12150
|
-
});
|
|
12151
|
-
authEE === null || authEE === void 0 ? void 0 : authEE.once(exports.AuthEvent.TRIGGER_SSO_POPUP, openPopup);
|
|
12152
|
-
return samlCompletionPromise;
|
|
12153
|
-
}
|
|
12154
|
-
/**
|
|
12155
|
-
* Perform SAML authentication
|
|
12156
|
-
*
|
|
12157
|
-
* @param embedConfig The embed configuration
|
|
12158
|
-
* @param ssoEndPoint
|
|
12159
|
-
*/
|
|
12160
|
-
const doSSOAuth = async (embedConfig, ssoEndPoint) => {
|
|
12161
|
-
const { thoughtSpotHost } = embedConfig;
|
|
12162
|
-
const loggedIn = await isLoggedIn(thoughtSpotHost);
|
|
12163
|
-
if (loggedIn) {
|
|
12164
|
-
if (isAtSSORedirectUrl()) {
|
|
12165
|
-
removeSSORedirectUrlMarker();
|
|
12166
|
-
}
|
|
12167
|
-
loggedInStatus = true;
|
|
12168
|
-
return;
|
|
12169
|
-
}
|
|
12170
|
-
// we have already tried authentication and it did not succeed, restore
|
|
12171
|
-
// the current URL to the original one and invoke the callback.
|
|
12172
|
-
if (isAtSSORedirectUrl()) {
|
|
12173
|
-
removeSSORedirectUrlMarker();
|
|
12174
|
-
loggedInStatus = false;
|
|
12175
|
-
return;
|
|
12176
|
-
}
|
|
12177
|
-
const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
|
|
12178
|
-
if (embedConfig.inPopup) {
|
|
12179
|
-
await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
|
|
12180
|
-
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
12181
|
-
return;
|
|
12182
|
-
}
|
|
12183
|
-
window.location.href = ssoURL;
|
|
12184
|
-
};
|
|
12185
|
-
const doSamlAuth = async (embedConfig) => {
|
|
12186
|
-
const { thoughtSpotHost } = embedConfig;
|
|
12187
|
-
// redirect for SSO, when the SSO authentication is done, this page will be
|
|
12188
|
-
// loaded again and the same JS will execute again.
|
|
12189
|
-
const ssoRedirectUrl = embedConfig.inPopup
|
|
12190
|
-
? `${thoughtSpotHost}/v2/#/embed/saml-complete`
|
|
12191
|
-
: getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
|
|
12192
|
-
// bring back the page to the same URL
|
|
12193
|
-
const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
|
|
12194
|
-
await doSSOAuth(embedConfig, ssoEndPoint);
|
|
12195
|
-
return loggedInStatus;
|
|
12196
|
-
};
|
|
12197
|
-
const doOIDCAuth = async (embedConfig) => {
|
|
12198
|
-
const { thoughtSpotHost } = embedConfig;
|
|
12199
|
-
// redirect for SSO, when the SSO authentication is done, this page will be
|
|
12200
|
-
// loaded again and the same JS will execute again.
|
|
12201
|
-
const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
|
|
12202
|
-
? `${thoughtSpotHost}/v2/#/embed/saml-complete`
|
|
12203
|
-
: getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
|
|
12204
|
-
// bring back the page to the same URL
|
|
12205
|
-
const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
|
|
12206
|
-
await doSSOAuth(embedConfig, ssoEndPoint);
|
|
12207
|
-
return loggedInStatus;
|
|
12208
|
-
};
|
|
12209
|
-
const logout = async (embedConfig) => {
|
|
12210
|
-
const { thoughtSpotHost } = embedConfig;
|
|
12211
|
-
await fetchLogoutService(thoughtSpotHost);
|
|
12212
|
-
resetCachedAuthToken();
|
|
12213
|
-
const thoughtspotIframes = document.querySelectorAll("[data-ts-iframe='true']");
|
|
12214
|
-
if (thoughtspotIframes === null || thoughtspotIframes === void 0 ? void 0 : thoughtspotIframes.length) {
|
|
12215
|
-
thoughtspotIframes.forEach((el) => {
|
|
12216
|
-
el.parentElement.innerHTML = embedConfig.loginFailedMessage;
|
|
12217
|
-
});
|
|
12218
|
-
}
|
|
12219
|
-
loggedInStatus = false;
|
|
12220
|
-
return loggedInStatus;
|
|
12221
|
-
};
|
|
12222
|
-
/**
|
|
12223
|
-
* Perform authentication on the ThoughtSpot cluster
|
|
12224
|
-
*
|
|
12225
|
-
* @param embedConfig The embed configuration
|
|
12226
|
-
*/
|
|
12227
|
-
const authenticate = async (embedConfig) => {
|
|
12228
|
-
const { authType } = embedConfig;
|
|
12229
|
-
switch (authType) {
|
|
12230
|
-
case exports.AuthType.SSO:
|
|
12231
|
-
case exports.AuthType.SAMLRedirect:
|
|
12232
|
-
case exports.AuthType.SAML:
|
|
12233
|
-
return doSamlAuth(embedConfig);
|
|
12234
|
-
case exports.AuthType.OIDC:
|
|
12235
|
-
case exports.AuthType.OIDCRedirect:
|
|
12236
|
-
return doOIDCAuth(embedConfig);
|
|
12237
|
-
case exports.AuthType.AuthServer:
|
|
12238
|
-
case exports.AuthType.TrustedAuthToken:
|
|
12239
|
-
return doTokenAuth(embedConfig);
|
|
12240
|
-
case exports.AuthType.TrustedAuthTokenCookieless:
|
|
12241
|
-
return doCookielessTokenAuth(embedConfig);
|
|
12242
|
-
case exports.AuthType.Basic:
|
|
12243
|
-
return doBasicAuth(embedConfig);
|
|
12244
|
-
default:
|
|
12245
|
-
return Promise.resolve(true);
|
|
12246
|
-
}
|
|
11845
|
+
var is_localStorage_requested = this.get_config('opt_out_tracking_persistence_type') === 'localStorage';
|
|
11846
|
+
|
|
11847
|
+
// try to convert opt-in/out cookies to localStorage if possible
|
|
11848
|
+
if (is_localStorage_requested && _.localStorage.is_supported()) {
|
|
11849
|
+
if (!this.has_opted_in_tracking() && this.has_opted_in_tracking({'persistence_type': 'cookie'})) {
|
|
11850
|
+
this.opt_in_tracking({'enable_persistence': false});
|
|
11851
|
+
}
|
|
11852
|
+
if (!this.has_opted_out_tracking() && this.has_opted_out_tracking({'persistence_type': 'cookie'})) {
|
|
11853
|
+
this.opt_out_tracking({'clear_persistence': false});
|
|
11854
|
+
}
|
|
11855
|
+
this.clear_opt_in_out_tracking({
|
|
11856
|
+
'persistence_type': 'cookie',
|
|
11857
|
+
'enable_persistence': false
|
|
11858
|
+
});
|
|
11859
|
+
}
|
|
11860
|
+
|
|
11861
|
+
// check whether the user has already opted out - if so, clear & disable persistence
|
|
11862
|
+
if (this.has_opted_out_tracking()) {
|
|
11863
|
+
this._gdpr_update_persistence({'clear_persistence': true});
|
|
11864
|
+
|
|
11865
|
+
// check whether we should opt out by default
|
|
11866
|
+
// note: we don't clear persistence here by default since opt-out default state is often
|
|
11867
|
+
// used as an initial state while GDPR information is being collected
|
|
11868
|
+
} else if (!this.has_opted_in_tracking() && (
|
|
11869
|
+
this.get_config('opt_out_tracking_by_default') || _.cookie.get('mp_optout')
|
|
11870
|
+
)) {
|
|
11871
|
+
_.cookie.remove('mp_optout');
|
|
11872
|
+
this.opt_out_tracking({
|
|
11873
|
+
'clear_persistence': this.get_config('opt_out_persistence_by_default')
|
|
11874
|
+
});
|
|
11875
|
+
}
|
|
11876
|
+
};
|
|
11877
|
+
|
|
11878
|
+
/**
|
|
11879
|
+
* Enable or disable persistence based on options
|
|
11880
|
+
* only enable/disable if persistence is not already in this state
|
|
11881
|
+
* @param {boolean} [options.clear_persistence] If true, will delete all data stored by the sdk in persistence and disable it
|
|
11882
|
+
* @param {boolean} [options.enable_persistence] If true, will re-enable sdk persistence
|
|
11883
|
+
*/
|
|
11884
|
+
MixpanelLib.prototype._gdpr_update_persistence = function(options) {
|
|
11885
|
+
var disabled;
|
|
11886
|
+
if (options && options['clear_persistence']) {
|
|
11887
|
+
disabled = true;
|
|
11888
|
+
} else if (options && options['enable_persistence']) {
|
|
11889
|
+
disabled = false;
|
|
11890
|
+
} else {
|
|
11891
|
+
return;
|
|
11892
|
+
}
|
|
11893
|
+
|
|
11894
|
+
if (!this.get_config('disable_persistence') && this['persistence'].disabled !== disabled) {
|
|
11895
|
+
this['persistence'].set_disabled(disabled);
|
|
11896
|
+
}
|
|
11897
|
+
|
|
11898
|
+
if (disabled) {
|
|
11899
|
+
_.each(this.request_batchers, function(batcher) {
|
|
11900
|
+
batcher.clear();
|
|
11901
|
+
});
|
|
11902
|
+
}
|
|
11903
|
+
};
|
|
11904
|
+
|
|
11905
|
+
// call a base gdpr function after constructing the appropriate token and options args
|
|
11906
|
+
MixpanelLib.prototype._gdpr_call_func = function(func, options) {
|
|
11907
|
+
options = _.extend({
|
|
11908
|
+
'track': _.bind(this.track, this),
|
|
11909
|
+
'persistence_type': this.get_config('opt_out_tracking_persistence_type'),
|
|
11910
|
+
'cookie_prefix': this.get_config('opt_out_tracking_cookie_prefix'),
|
|
11911
|
+
'cookie_expiration': this.get_config('cookie_expiration'),
|
|
11912
|
+
'cross_site_cookie': this.get_config('cross_site_cookie'),
|
|
11913
|
+
'cross_subdomain_cookie': this.get_config('cross_subdomain_cookie'),
|
|
11914
|
+
'cookie_domain': this.get_config('cookie_domain'),
|
|
11915
|
+
'secure_cookie': this.get_config('secure_cookie'),
|
|
11916
|
+
'ignore_dnt': this.get_config('ignore_dnt')
|
|
11917
|
+
}, options);
|
|
11918
|
+
|
|
11919
|
+
// check if localStorage can be used for recording opt out status, fall back to cookie if not
|
|
11920
|
+
if (!_.localStorage.is_supported()) {
|
|
11921
|
+
options['persistence_type'] = 'cookie';
|
|
11922
|
+
}
|
|
11923
|
+
|
|
11924
|
+
return func(this.get_config('token'), {
|
|
11925
|
+
track: options['track'],
|
|
11926
|
+
trackEventName: options['track_event_name'],
|
|
11927
|
+
trackProperties: options['track_properties'],
|
|
11928
|
+
persistenceType: options['persistence_type'],
|
|
11929
|
+
persistencePrefix: options['cookie_prefix'],
|
|
11930
|
+
cookieDomain: options['cookie_domain'],
|
|
11931
|
+
cookieExpiration: options['cookie_expiration'],
|
|
11932
|
+
crossSiteCookie: options['cross_site_cookie'],
|
|
11933
|
+
crossSubdomainCookie: options['cross_subdomain_cookie'],
|
|
11934
|
+
secureCookie: options['secure_cookie'],
|
|
11935
|
+
ignoreDnt: options['ignore_dnt']
|
|
11936
|
+
});
|
|
11937
|
+
};
|
|
11938
|
+
|
|
11939
|
+
/**
|
|
11940
|
+
* Opt the user in to data tracking and cookies/localstorage for this Mixpanel instance
|
|
11941
|
+
*
|
|
11942
|
+
* ### Usage
|
|
11943
|
+
*
|
|
11944
|
+
* // opt user in
|
|
11945
|
+
* mixpanel.opt_in_tracking();
|
|
11946
|
+
*
|
|
11947
|
+
* // opt user in with specific event name, properties, cookie configuration
|
|
11948
|
+
* mixpanel.opt_in_tracking({
|
|
11949
|
+
* track_event_name: 'User opted in',
|
|
11950
|
+
* track_event_properties: {
|
|
11951
|
+
* 'Email': 'jdoe@example.com'
|
|
11952
|
+
* },
|
|
11953
|
+
* cookie_expiration: 30,
|
|
11954
|
+
* secure_cookie: true
|
|
11955
|
+
* });
|
|
11956
|
+
*
|
|
11957
|
+
* @param {Object} [options] A dictionary of config options to override
|
|
11958
|
+
* @param {function} [options.track] Function used for tracking a Mixpanel event to record the opt-in action (default is this Mixpanel instance's track method)
|
|
11959
|
+
* @param {string} [options.track_event_name=$opt_in] Event name to be used for tracking the opt-in action
|
|
11960
|
+
* @param {Object} [options.track_properties] Set of properties to be tracked along with the opt-in action
|
|
11961
|
+
* @param {boolean} [options.enable_persistence=true] If true, will re-enable sdk persistence
|
|
11962
|
+
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11963
|
+
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11964
|
+
* @param {Number} [options.cookie_expiration] Number of days until the opt-in cookie expires (overrides value specified in this Mixpanel instance's config)
|
|
11965
|
+
* @param {string} [options.cookie_domain] Custom cookie domain (overrides value specified in this Mixpanel instance's config)
|
|
11966
|
+
* @param {boolean} [options.cross_site_cookie] Whether the opt-in cookie is set as cross-site-enabled (overrides value specified in this Mixpanel instance's config)
|
|
11967
|
+
* @param {boolean} [options.cross_subdomain_cookie] Whether the opt-in cookie is set as cross-subdomain or not (overrides value specified in this Mixpanel instance's config)
|
|
11968
|
+
* @param {boolean} [options.secure_cookie] Whether the opt-in cookie is set as secure or not (overrides value specified in this Mixpanel instance's config)
|
|
11969
|
+
*/
|
|
11970
|
+
MixpanelLib.prototype.opt_in_tracking = function(options) {
|
|
11971
|
+
options = _.extend({
|
|
11972
|
+
'enable_persistence': true
|
|
11973
|
+
}, options);
|
|
11974
|
+
|
|
11975
|
+
this._gdpr_call_func(optIn, options);
|
|
11976
|
+
this._gdpr_update_persistence(options);
|
|
11977
|
+
};
|
|
11978
|
+
|
|
11979
|
+
/**
|
|
11980
|
+
* Opt the user out of data tracking and cookies/localstorage for this Mixpanel instance
|
|
11981
|
+
*
|
|
11982
|
+
* ### Usage
|
|
11983
|
+
*
|
|
11984
|
+
* // opt user out
|
|
11985
|
+
* mixpanel.opt_out_tracking();
|
|
11986
|
+
*
|
|
11987
|
+
* // opt user out with different cookie configuration from Mixpanel instance
|
|
11988
|
+
* mixpanel.opt_out_tracking({
|
|
11989
|
+
* cookie_expiration: 30,
|
|
11990
|
+
* secure_cookie: true
|
|
11991
|
+
* });
|
|
11992
|
+
*
|
|
11993
|
+
* @param {Object} [options] A dictionary of config options to override
|
|
11994
|
+
* @param {boolean} [options.delete_user=true] If true, will delete the currently identified user's profile and clear all charges after opting the user out
|
|
11995
|
+
* @param {boolean} [options.clear_persistence=true] If true, will delete all data stored by the sdk in persistence
|
|
11996
|
+
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
11997
|
+
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
11998
|
+
* @param {Number} [options.cookie_expiration] Number of days until the opt-in cookie expires (overrides value specified in this Mixpanel instance's config)
|
|
11999
|
+
* @param {string} [options.cookie_domain] Custom cookie domain (overrides value specified in this Mixpanel instance's config)
|
|
12000
|
+
* @param {boolean} [options.cross_site_cookie] Whether the opt-in cookie is set as cross-site-enabled (overrides value specified in this Mixpanel instance's config)
|
|
12001
|
+
* @param {boolean} [options.cross_subdomain_cookie] Whether the opt-in cookie is set as cross-subdomain or not (overrides value specified in this Mixpanel instance's config)
|
|
12002
|
+
* @param {boolean} [options.secure_cookie] Whether the opt-in cookie is set as secure or not (overrides value specified in this Mixpanel instance's config)
|
|
12003
|
+
*/
|
|
12004
|
+
MixpanelLib.prototype.opt_out_tracking = function(options) {
|
|
12005
|
+
options = _.extend({
|
|
12006
|
+
'clear_persistence': true,
|
|
12007
|
+
'delete_user': true
|
|
12008
|
+
}, options);
|
|
12009
|
+
|
|
12010
|
+
// delete user and clear charges since these methods may be disabled by opt-out
|
|
12011
|
+
if (options['delete_user'] && this['people'] && this['people']._identify_called()) {
|
|
12012
|
+
this['people'].delete_user();
|
|
12013
|
+
this['people'].clear_charges();
|
|
12014
|
+
}
|
|
12015
|
+
|
|
12016
|
+
this._gdpr_call_func(optOut, options);
|
|
12017
|
+
this._gdpr_update_persistence(options);
|
|
12018
|
+
};
|
|
12019
|
+
|
|
12020
|
+
/**
|
|
12021
|
+
* Check whether the user has opted in to data tracking and cookies/localstorage for this Mixpanel instance
|
|
12022
|
+
*
|
|
12023
|
+
* ### Usage
|
|
12024
|
+
*
|
|
12025
|
+
* var has_opted_in = mixpanel.has_opted_in_tracking();
|
|
12026
|
+
* // use has_opted_in value
|
|
12027
|
+
*
|
|
12028
|
+
* @param {Object} [options] A dictionary of config options to override
|
|
12029
|
+
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
12030
|
+
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
12031
|
+
* @returns {boolean} current opt-in status
|
|
12032
|
+
*/
|
|
12033
|
+
MixpanelLib.prototype.has_opted_in_tracking = function(options) {
|
|
12034
|
+
return this._gdpr_call_func(hasOptedIn, options);
|
|
12035
|
+
};
|
|
12036
|
+
|
|
12037
|
+
/**
|
|
12038
|
+
* Check whether the user has opted out of data tracking and cookies/localstorage for this Mixpanel instance
|
|
12039
|
+
*
|
|
12040
|
+
* ### Usage
|
|
12041
|
+
*
|
|
12042
|
+
* var has_opted_out = mixpanel.has_opted_out_tracking();
|
|
12043
|
+
* // use has_opted_out value
|
|
12044
|
+
*
|
|
12045
|
+
* @param {Object} [options] A dictionary of config options to override
|
|
12046
|
+
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
12047
|
+
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
12048
|
+
* @returns {boolean} current opt-out status
|
|
12049
|
+
*/
|
|
12050
|
+
MixpanelLib.prototype.has_opted_out_tracking = function(options) {
|
|
12051
|
+
return this._gdpr_call_func(hasOptedOut, options);
|
|
12052
|
+
};
|
|
12053
|
+
|
|
12054
|
+
/**
|
|
12055
|
+
* Clear the user's opt in/out status of data tracking and cookies/localstorage for this Mixpanel instance
|
|
12056
|
+
*
|
|
12057
|
+
* ### Usage
|
|
12058
|
+
*
|
|
12059
|
+
* // clear user's opt-in/out status
|
|
12060
|
+
* mixpanel.clear_opt_in_out_tracking();
|
|
12061
|
+
*
|
|
12062
|
+
* // clear user's opt-in/out status with specific cookie configuration - should match
|
|
12063
|
+
* // configuration used when opt_in_tracking/opt_out_tracking methods were called.
|
|
12064
|
+
* mixpanel.clear_opt_in_out_tracking({
|
|
12065
|
+
* cookie_expiration: 30,
|
|
12066
|
+
* secure_cookie: true
|
|
12067
|
+
* });
|
|
12068
|
+
*
|
|
12069
|
+
* @param {Object} [options] A dictionary of config options to override
|
|
12070
|
+
* @param {boolean} [options.enable_persistence=true] If true, will re-enable sdk persistence
|
|
12071
|
+
* @param {string} [options.persistence_type=localStorage] Persistence mechanism used - cookie or localStorage - falls back to cookie if localStorage is unavailable
|
|
12072
|
+
* @param {string} [options.cookie_prefix=__mp_opt_in_out] Custom prefix to be used in the cookie/localstorage name
|
|
12073
|
+
* @param {Number} [options.cookie_expiration] Number of days until the opt-in cookie expires (overrides value specified in this Mixpanel instance's config)
|
|
12074
|
+
* @param {string} [options.cookie_domain] Custom cookie domain (overrides value specified in this Mixpanel instance's config)
|
|
12075
|
+
* @param {boolean} [options.cross_site_cookie] Whether the opt-in cookie is set as cross-site-enabled (overrides value specified in this Mixpanel instance's config)
|
|
12076
|
+
* @param {boolean} [options.cross_subdomain_cookie] Whether the opt-in cookie is set as cross-subdomain or not (overrides value specified in this Mixpanel instance's config)
|
|
12077
|
+
* @param {boolean} [options.secure_cookie] Whether the opt-in cookie is set as secure or not (overrides value specified in this Mixpanel instance's config)
|
|
12078
|
+
*/
|
|
12079
|
+
MixpanelLib.prototype.clear_opt_in_out_tracking = function(options) {
|
|
12080
|
+
options = _.extend({
|
|
12081
|
+
'enable_persistence': true
|
|
12082
|
+
}, options);
|
|
12083
|
+
|
|
12084
|
+
this._gdpr_call_func(clearOptInOut, options);
|
|
12085
|
+
this._gdpr_update_persistence(options);
|
|
12086
|
+
};
|
|
12087
|
+
|
|
12088
|
+
MixpanelLib.prototype.report_error = function(msg, err) {
|
|
12089
|
+
console$1.error.apply(console$1.error, arguments);
|
|
12090
|
+
try {
|
|
12091
|
+
if (!err && !(msg instanceof Error)) {
|
|
12092
|
+
msg = new Error(msg);
|
|
12093
|
+
}
|
|
12094
|
+
this.get_config('error_reporter')(msg, err);
|
|
12095
|
+
} catch(err) {
|
|
12096
|
+
console$1.error(err);
|
|
12097
|
+
}
|
|
12247
12098
|
};
|
|
12248
12099
|
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12100
|
+
// EXPORTS (for closure compiler)
|
|
12101
|
+
|
|
12102
|
+
// MixpanelLib Exports
|
|
12103
|
+
MixpanelLib.prototype['init'] = MixpanelLib.prototype.init;
|
|
12104
|
+
MixpanelLib.prototype['reset'] = MixpanelLib.prototype.reset;
|
|
12105
|
+
MixpanelLib.prototype['disable'] = MixpanelLib.prototype.disable;
|
|
12106
|
+
MixpanelLib.prototype['time_event'] = MixpanelLib.prototype.time_event;
|
|
12107
|
+
MixpanelLib.prototype['track'] = MixpanelLib.prototype.track;
|
|
12108
|
+
MixpanelLib.prototype['track_links'] = MixpanelLib.prototype.track_links;
|
|
12109
|
+
MixpanelLib.prototype['track_forms'] = MixpanelLib.prototype.track_forms;
|
|
12110
|
+
MixpanelLib.prototype['track_pageview'] = MixpanelLib.prototype.track_pageview;
|
|
12111
|
+
MixpanelLib.prototype['register'] = MixpanelLib.prototype.register;
|
|
12112
|
+
MixpanelLib.prototype['register_once'] = MixpanelLib.prototype.register_once;
|
|
12113
|
+
MixpanelLib.prototype['unregister'] = MixpanelLib.prototype.unregister;
|
|
12114
|
+
MixpanelLib.prototype['identify'] = MixpanelLib.prototype.identify;
|
|
12115
|
+
MixpanelLib.prototype['alias'] = MixpanelLib.prototype.alias;
|
|
12116
|
+
MixpanelLib.prototype['name_tag'] = MixpanelLib.prototype.name_tag;
|
|
12117
|
+
MixpanelLib.prototype['set_config'] = MixpanelLib.prototype.set_config;
|
|
12118
|
+
MixpanelLib.prototype['get_config'] = MixpanelLib.prototype.get_config;
|
|
12119
|
+
MixpanelLib.prototype['get_property'] = MixpanelLib.prototype.get_property;
|
|
12120
|
+
MixpanelLib.prototype['get_distinct_id'] = MixpanelLib.prototype.get_distinct_id;
|
|
12121
|
+
MixpanelLib.prototype['toString'] = MixpanelLib.prototype.toString;
|
|
12122
|
+
MixpanelLib.prototype['opt_out_tracking'] = MixpanelLib.prototype.opt_out_tracking;
|
|
12123
|
+
MixpanelLib.prototype['opt_in_tracking'] = MixpanelLib.prototype.opt_in_tracking;
|
|
12124
|
+
MixpanelLib.prototype['has_opted_out_tracking'] = MixpanelLib.prototype.has_opted_out_tracking;
|
|
12125
|
+
MixpanelLib.prototype['has_opted_in_tracking'] = MixpanelLib.prototype.has_opted_in_tracking;
|
|
12126
|
+
MixpanelLib.prototype['clear_opt_in_out_tracking'] = MixpanelLib.prototype.clear_opt_in_out_tracking;
|
|
12127
|
+
MixpanelLib.prototype['get_group'] = MixpanelLib.prototype.get_group;
|
|
12128
|
+
MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
|
|
12129
|
+
MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
|
|
12130
|
+
MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
|
|
12131
|
+
MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
|
|
12132
|
+
MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
|
|
12133
|
+
MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;
|
|
12134
|
+
|
|
12135
|
+
// MixpanelPersistence Exports
|
|
12136
|
+
MixpanelPersistence.prototype['properties'] = MixpanelPersistence.prototype.properties;
|
|
12137
|
+
MixpanelPersistence.prototype['update_search_keyword'] = MixpanelPersistence.prototype.update_search_keyword;
|
|
12138
|
+
MixpanelPersistence.prototype['update_referrer_info'] = MixpanelPersistence.prototype.update_referrer_info;
|
|
12139
|
+
MixpanelPersistence.prototype['get_cross_subdomain'] = MixpanelPersistence.prototype.get_cross_subdomain;
|
|
12140
|
+
MixpanelPersistence.prototype['clear'] = MixpanelPersistence.prototype.clear;
|
|
12141
|
+
|
|
12142
|
+
|
|
12143
|
+
var instances = {};
|
|
12144
|
+
var extend_mp = function() {
|
|
12145
|
+
// add all the sub mixpanel instances
|
|
12146
|
+
_.each(instances, function(instance, name) {
|
|
12147
|
+
if (name !== PRIMARY_INSTANCE_NAME) { mixpanel_master[name] = instance; }
|
|
12148
|
+
});
|
|
12149
|
+
|
|
12150
|
+
// add private functions as _
|
|
12151
|
+
mixpanel_master['_'] = _;
|
|
12255
12152
|
};
|
|
12256
12153
|
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
|
|
12268
|
-
|
|
12269
|
-
|
|
12270
|
-
'(#.*|)$', // hash
|
|
12271
|
-
].join(''));
|
|
12272
|
-
/**
|
|
12273
|
-
* Parse and construct the ThoughtSpot hostname or IP address
|
|
12274
|
-
* from the embed configuration object.
|
|
12275
|
-
*
|
|
12276
|
-
* @param config
|
|
12277
|
-
*/
|
|
12278
|
-
const getThoughtSpotHost = (config) => {
|
|
12279
|
-
if (!config.thoughtSpotHost) {
|
|
12280
|
-
throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
|
|
12281
|
-
}
|
|
12282
|
-
const urlParts = config.thoughtSpotHost.match(urlRegex);
|
|
12283
|
-
if (!urlParts) {
|
|
12284
|
-
throw new Error(ERROR_MESSAGE.INVALID_THOUGHTSPOT_HOST);
|
|
12285
|
-
}
|
|
12286
|
-
const protocol = urlParts[2] || window.location.protocol;
|
|
12287
|
-
const host = urlParts[3];
|
|
12288
|
-
let path = urlParts[6];
|
|
12289
|
-
// Lose the trailing / if any
|
|
12290
|
-
if (path.charAt(path.length - 1) === '/') {
|
|
12291
|
-
path = path.substring(0, path.length - 1);
|
|
12292
|
-
}
|
|
12293
|
-
// const urlParams = urlParts[7];
|
|
12294
|
-
// const hash = urlParts[8];
|
|
12295
|
-
return `${protocol}//${host}${path}`;
|
|
12296
|
-
};
|
|
12297
|
-
const getV2BasePath = (config) => {
|
|
12298
|
-
if (config.basepath) {
|
|
12299
|
-
return config.basepath;
|
|
12300
|
-
}
|
|
12301
|
-
const tsHost = getThoughtSpotHost(config);
|
|
12302
|
-
// This is to handle when e2e's. Search is run on pods for
|
|
12303
|
-
// comp-blink-test-pipeline with baseUrl=https://localhost:8443.
|
|
12304
|
-
// This is to handle when the developer is developing in their local
|
|
12305
|
-
// environment.
|
|
12306
|
-
if (tsHost.includes('://localhost') && !tsHost.includes(':8443')) {
|
|
12307
|
-
return '';
|
|
12308
|
-
}
|
|
12309
|
-
return 'v2';
|
|
12310
|
-
};
|
|
12311
|
-
/**
|
|
12312
|
-
* It is a good idea to keep URLs under 2000 chars.
|
|
12313
|
-
* If this is ever breached, since we pass view configuration through
|
|
12314
|
-
* URL params, we would like to log a warning.
|
|
12315
|
-
* Reference: https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
|
|
12316
|
-
*/
|
|
12317
|
-
const URL_MAX_LENGTH = 2000;
|
|
12318
|
-
/**
|
|
12319
|
-
* The default CSS dimensions of the embedded app
|
|
12320
|
-
*/
|
|
12321
|
-
const DEFAULT_EMBED_WIDTH = '100%';
|
|
12322
|
-
const DEFAULT_EMBED_HEIGHT = '100%';
|
|
12154
|
+
var override_mp_init_func = function() {
|
|
12155
|
+
// we override the snippets init function to handle the case where a
|
|
12156
|
+
// user initializes the mixpanel library after the script loads & runs
|
|
12157
|
+
mixpanel_master['init'] = function(token, config, name) {
|
|
12158
|
+
if (name) {
|
|
12159
|
+
// initialize a sub library
|
|
12160
|
+
if (!mixpanel_master[name]) {
|
|
12161
|
+
mixpanel_master[name] = instances[name] = create_mplib(token, config, name);
|
|
12162
|
+
mixpanel_master[name]._loaded();
|
|
12163
|
+
}
|
|
12164
|
+
return mixpanel_master[name];
|
|
12165
|
+
} else {
|
|
12166
|
+
var instance = mixpanel_master;
|
|
12323
12167
|
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
const operationName = getOperationNameFromQuery(query);
|
|
12334
|
-
try {
|
|
12335
|
-
const response = await fetch(`${thoughtSpotHost}/prism/?op=${operationName}`, {
|
|
12336
|
-
method: 'POST',
|
|
12337
|
-
headers: {
|
|
12338
|
-
'content-type': 'application/json;charset=UTF-8',
|
|
12339
|
-
'x-requested-by': 'ThoughtSpot',
|
|
12340
|
-
accept: '*/*',
|
|
12341
|
-
'accept-language': 'en-us',
|
|
12342
|
-
},
|
|
12343
|
-
body: JSON.stringify({
|
|
12344
|
-
operationName,
|
|
12345
|
-
query,
|
|
12346
|
-
variables,
|
|
12347
|
-
}),
|
|
12348
|
-
credentials: 'include',
|
|
12349
|
-
});
|
|
12350
|
-
const result = await response.json();
|
|
12351
|
-
const dataValues = Object.values(result.data);
|
|
12352
|
-
return (isCompositeQuery) ? result.data : dataValues[0];
|
|
12353
|
-
}
|
|
12354
|
-
catch (error) {
|
|
12355
|
-
return error;
|
|
12356
|
-
}
|
|
12357
|
-
}
|
|
12168
|
+
if (instances[PRIMARY_INSTANCE_NAME]) {
|
|
12169
|
+
// main mixpanel lib already initialized
|
|
12170
|
+
instance = instances[PRIMARY_INSTANCE_NAME];
|
|
12171
|
+
} else if (token) {
|
|
12172
|
+
// intialize the main mixpanel lib
|
|
12173
|
+
instance = create_mplib(token, config, PRIMARY_INSTANCE_NAME);
|
|
12174
|
+
instance._loaded();
|
|
12175
|
+
instances[PRIMARY_INSTANCE_NAME] = instance;
|
|
12176
|
+
}
|
|
12358
12177
|
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
author
|
|
12375
|
-
authorDisplayName
|
|
12376
|
-
description
|
|
12377
|
-
dataType
|
|
12378
|
-
type
|
|
12379
|
-
modified
|
|
12380
|
-
ownerName
|
|
12381
|
-
owner
|
|
12382
|
-
dataRecency
|
|
12383
|
-
sources {
|
|
12384
|
-
tableId
|
|
12385
|
-
tableName
|
|
12386
|
-
columnId
|
|
12387
|
-
columnName
|
|
12388
|
-
__typename
|
|
12389
|
-
}
|
|
12390
|
-
synonyms
|
|
12391
|
-
cohortAnswerId
|
|
12392
|
-
__typename
|
|
12393
|
-
}
|
|
12394
|
-
relationships
|
|
12395
|
-
destinationRelationships
|
|
12396
|
-
dataSourceId
|
|
12397
|
-
__typename
|
|
12398
|
-
}
|
|
12399
|
-
}
|
|
12400
|
-
`;
|
|
12401
|
-
const sourceDetailCache = new Map();
|
|
12402
|
-
/**
|
|
12403
|
-
*
|
|
12404
|
-
* @param thoughtSpotHost
|
|
12405
|
-
* @param sourceId
|
|
12406
|
-
*/
|
|
12407
|
-
async function getSourceDetail(thoughtSpotHost, sourceId) {
|
|
12408
|
-
if (sourceDetailCache.get(sourceId)) {
|
|
12409
|
-
return sourceDetailCache.get(sourceId);
|
|
12410
|
-
}
|
|
12411
|
-
const details = await graphqlQuery({
|
|
12412
|
-
query: getSourceDetailQuery,
|
|
12413
|
-
variables: {
|
|
12414
|
-
ids: [sourceId],
|
|
12415
|
-
},
|
|
12416
|
-
thoughtSpotHost,
|
|
12417
|
-
});
|
|
12418
|
-
const souceDetails = details[0];
|
|
12419
|
-
if (souceDetails) {
|
|
12420
|
-
sourceDetailCache.set(sourceId, souceDetails);
|
|
12421
|
-
}
|
|
12422
|
-
return souceDetails;
|
|
12423
|
-
}
|
|
12178
|
+
mixpanel_master = instance;
|
|
12179
|
+
if (init_type === INIT_SNIPPET) {
|
|
12180
|
+
window$1[PRIMARY_INSTANCE_NAME] = mixpanel_master;
|
|
12181
|
+
}
|
|
12182
|
+
extend_mp();
|
|
12183
|
+
}
|
|
12184
|
+
};
|
|
12185
|
+
};
|
|
12186
|
+
|
|
12187
|
+
var add_dom_loaded_handler = function() {
|
|
12188
|
+
// Cross browser DOM Loaded support
|
|
12189
|
+
function dom_loaded_handler() {
|
|
12190
|
+
// function flag since we only want to execute this once
|
|
12191
|
+
if (dom_loaded_handler.done) { return; }
|
|
12192
|
+
dom_loaded_handler.done = true;
|
|
12424
12193
|
|
|
12425
|
-
|
|
12426
|
-
|
|
12427
|
-
sessionId
|
|
12428
|
-
genNo
|
|
12429
|
-
acSession {
|
|
12430
|
-
sessionId
|
|
12431
|
-
genNo
|
|
12432
|
-
}
|
|
12433
|
-
}
|
|
12434
|
-
`;
|
|
12435
|
-
const getUnaggregatedAnswerSession = `
|
|
12436
|
-
mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
|
|
12437
|
-
Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
|
|
12438
|
-
${bachSessionId}
|
|
12439
|
-
answer {
|
|
12440
|
-
visualizations {
|
|
12441
|
-
... on TableViz {
|
|
12442
|
-
columns {
|
|
12443
|
-
column {
|
|
12444
|
-
id
|
|
12445
|
-
name
|
|
12446
|
-
referencedColumns {
|
|
12447
|
-
guid
|
|
12448
|
-
displayName
|
|
12449
|
-
}
|
|
12450
|
-
}
|
|
12451
|
-
}
|
|
12452
|
-
}
|
|
12453
|
-
}
|
|
12454
|
-
}
|
|
12455
|
-
}
|
|
12456
|
-
}
|
|
12457
|
-
`;
|
|
12458
|
-
const removeColumns = `
|
|
12459
|
-
mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
|
|
12460
|
-
Answer__removeColumns(
|
|
12461
|
-
session: $session
|
|
12462
|
-
logicalColumnIds: $logicalColumnIds
|
|
12463
|
-
columnIds: $columnIds
|
|
12464
|
-
) {
|
|
12465
|
-
${bachSessionId}
|
|
12466
|
-
}
|
|
12467
|
-
}
|
|
12468
|
-
`;
|
|
12469
|
-
const addColumns = `
|
|
12470
|
-
mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
|
|
12471
|
-
Answer__addColumn(session: $session, columns: $columns) {
|
|
12472
|
-
${bachSessionId}
|
|
12473
|
-
}
|
|
12474
|
-
}
|
|
12475
|
-
`;
|
|
12476
|
-
const getAnswerData = `
|
|
12477
|
-
query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
|
|
12478
|
-
getAnswer(session: $session) {
|
|
12479
|
-
${bachSessionId}
|
|
12480
|
-
answer {
|
|
12481
|
-
id
|
|
12482
|
-
visualizations {
|
|
12483
|
-
id
|
|
12484
|
-
... on TableViz {
|
|
12485
|
-
columns {
|
|
12486
|
-
column {
|
|
12487
|
-
id
|
|
12488
|
-
name
|
|
12489
|
-
type
|
|
12490
|
-
aggregationType
|
|
12491
|
-
dataType
|
|
12492
|
-
}
|
|
12493
|
-
}
|
|
12494
|
-
data(deadline: $deadline, pagination: $dataPaginationParams)
|
|
12495
|
-
}
|
|
12496
|
-
}
|
|
12497
|
-
}
|
|
12498
|
-
}
|
|
12499
|
-
}
|
|
12500
|
-
`;
|
|
12194
|
+
DOM_LOADED = true;
|
|
12195
|
+
ENQUEUE_REQUESTS = false;
|
|
12501
12196
|
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
|
|
12508
|
-
|
|
12509
|
-
|
|
12510
|
-
|
|
12511
|
-
|
|
12512
|
-
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
|
|
12529
|
-
|
|
12530
|
-
|
|
12531
|
-
|
|
12532
|
-
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
|
|
12595
|
-
if (!selectedPoints && !this.selectedPoints) {
|
|
12596
|
-
throw new Error('Needs to be triggered in context of a point');
|
|
12597
|
-
}
|
|
12598
|
-
if (!selectedPoints) {
|
|
12599
|
-
selectedPoints = getSelectedPointsForUnderlyingDataQuery(this.selectedPoints);
|
|
12600
|
-
}
|
|
12601
|
-
const sourceDetail = await this.getSourceDetail();
|
|
12602
|
-
const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
|
|
12603
|
-
const unAggAnswer = await graphqlQuery({
|
|
12604
|
-
query: getUnaggregatedAnswerSession,
|
|
12605
|
-
variables: {
|
|
12606
|
-
session: this.session,
|
|
12607
|
-
columns: selectedPoints,
|
|
12608
|
-
},
|
|
12609
|
-
thoughtSpotHost: this.thoughtSpotHost,
|
|
12610
|
-
});
|
|
12611
|
-
const unaggAnswerSession = new AnswerService(unAggAnswer.id, unAggAnswer.answer, this.thoughtSpotHost);
|
|
12612
|
-
const currentColumns = new Set(unAggAnswer.answer.visualizations[0].columns
|
|
12613
|
-
.map((c) => c.column.referencedColumns[0].guid));
|
|
12614
|
-
const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
|
|
12615
|
-
if (columnsToAdd.length) {
|
|
12616
|
-
await unaggAnswerSession.addColumns(columnsToAdd);
|
|
12617
|
-
}
|
|
12618
|
-
const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
|
|
12619
|
-
if (columnsToRemove.length) {
|
|
12620
|
-
await unaggAnswerSession.removeColumns(columnsToRemove);
|
|
12621
|
-
}
|
|
12622
|
-
return unaggAnswerSession;
|
|
12623
|
-
}
|
|
12624
|
-
async executeQuery(query, variables) {
|
|
12625
|
-
const data = await graphqlQuery({
|
|
12626
|
-
query,
|
|
12627
|
-
variables: {
|
|
12628
|
-
session: this.session,
|
|
12629
|
-
...variables,
|
|
12630
|
-
},
|
|
12631
|
-
thoughtSpotHost: this.thoughtSpotHost,
|
|
12632
|
-
isCompositeQuery: false,
|
|
12633
|
-
});
|
|
12634
|
-
this.session = deepMerge(this.session, (data === null || data === void 0 ? void 0 : data.id) || {});
|
|
12635
|
-
return data;
|
|
12636
|
-
}
|
|
12637
|
-
getSession() {
|
|
12638
|
-
return this.session;
|
|
12197
|
+
_.each(instances, function(inst) {
|
|
12198
|
+
inst._dom_loaded();
|
|
12199
|
+
});
|
|
12200
|
+
}
|
|
12201
|
+
|
|
12202
|
+
function do_scroll_check() {
|
|
12203
|
+
try {
|
|
12204
|
+
document$1.documentElement.doScroll('left');
|
|
12205
|
+
} catch(e) {
|
|
12206
|
+
setTimeout(do_scroll_check, 1);
|
|
12207
|
+
return;
|
|
12208
|
+
}
|
|
12209
|
+
|
|
12210
|
+
dom_loaded_handler();
|
|
12211
|
+
}
|
|
12212
|
+
|
|
12213
|
+
if (document$1.addEventListener) {
|
|
12214
|
+
if (document$1.readyState === 'complete') {
|
|
12215
|
+
// safari 4 can fire the DOMContentLoaded event before loading all
|
|
12216
|
+
// external JS (including this file). you will see some copypasta
|
|
12217
|
+
// on the internet that checks for 'complete' and 'loaded', but
|
|
12218
|
+
// 'loaded' is an IE thing
|
|
12219
|
+
dom_loaded_handler();
|
|
12220
|
+
} else {
|
|
12221
|
+
document$1.addEventListener('DOMContentLoaded', dom_loaded_handler, false);
|
|
12222
|
+
}
|
|
12223
|
+
} else if (document$1.attachEvent) {
|
|
12224
|
+
// IE
|
|
12225
|
+
document$1.attachEvent('onreadystatechange', dom_loaded_handler);
|
|
12226
|
+
|
|
12227
|
+
// check to make sure we arn't in a frame
|
|
12228
|
+
var toplevel = false;
|
|
12229
|
+
try {
|
|
12230
|
+
toplevel = window$1.frameElement === null;
|
|
12231
|
+
} catch(e) {
|
|
12232
|
+
// noop
|
|
12233
|
+
}
|
|
12234
|
+
|
|
12235
|
+
if (document$1.documentElement.doScroll && toplevel) {
|
|
12236
|
+
do_scroll_check();
|
|
12237
|
+
}
|
|
12238
|
+
}
|
|
12239
|
+
|
|
12240
|
+
// fallback handler, always will work
|
|
12241
|
+
_.register_event(window$1, 'load', dom_loaded_handler, true);
|
|
12242
|
+
};
|
|
12243
|
+
|
|
12244
|
+
function init_as_module() {
|
|
12245
|
+
init_type = INIT_MODULE;
|
|
12246
|
+
mixpanel_master = new MixpanelLib();
|
|
12247
|
+
|
|
12248
|
+
override_mp_init_func();
|
|
12249
|
+
mixpanel_master['init']();
|
|
12250
|
+
add_dom_loaded_handler();
|
|
12251
|
+
|
|
12252
|
+
return mixpanel_master;
|
|
12253
|
+
}
|
|
12254
|
+
|
|
12255
|
+
var mixpanel = init_as_module();
|
|
12256
|
+
|
|
12257
|
+
var mixpanel_cjs = mixpanel;
|
|
12258
|
+
|
|
12259
|
+
var mixpanel$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null), mixpanel_cjs, {
|
|
12260
|
+
'default': mixpanel_cjs
|
|
12261
|
+
}));
|
|
12262
|
+
|
|
12263
|
+
// Needed to avoid error in CJS builds on some bundlers.
|
|
12264
|
+
const mixpanelLib = mixpanel_cjs || mixpanel$1;
|
|
12265
|
+
let mixpanelInstance;
|
|
12266
|
+
const MIXPANEL_EVENT = {
|
|
12267
|
+
VISUAL_SDK_RENDER_START: 'visual-sdk-render-start',
|
|
12268
|
+
VISUAL_SDK_CALLED_INIT: 'visual-sdk-called-init',
|
|
12269
|
+
VISUAL_SDK_RENDER_COMPLETE: 'visual-sdk-render-complete',
|
|
12270
|
+
VISUAL_SDK_RENDER_FAILED: 'visual-sdk-render-failed',
|
|
12271
|
+
VISUAL_SDK_TRIGGER: 'visual-sdk-trigger',
|
|
12272
|
+
VISUAL_SDK_ON: 'visual-sdk-on',
|
|
12273
|
+
VISUAL_SDK_IFRAME_LOAD_PERFORMANCE: 'visual-sdk-iframe-load-performance',
|
|
12274
|
+
VISUAL_SDK_EMBED_CREATE: 'visual-sdk-embed-create',
|
|
12275
|
+
VERCEL_INTEGRATION_COMPLETED: 'vercel-integration-completed',
|
|
12276
|
+
};
|
|
12277
|
+
let isMixpanelInitialized = false;
|
|
12278
|
+
let eventQueue = [];
|
|
12279
|
+
/**
|
|
12280
|
+
* Pushes the event with its Property key-value map to mixpanel.
|
|
12281
|
+
*
|
|
12282
|
+
* @param eventId
|
|
12283
|
+
* @param eventProps
|
|
12284
|
+
*/
|
|
12285
|
+
function uploadMixpanelEvent(eventId, eventProps = {}) {
|
|
12286
|
+
if (!isMixpanelInitialized) {
|
|
12287
|
+
eventQueue.push({ eventId, eventProps });
|
|
12288
|
+
return;
|
|
12639
12289
|
}
|
|
12290
|
+
mixpanelInstance.track(eventId, eventProps);
|
|
12640
12291
|
}
|
|
12641
12292
|
/**
|
|
12642
12293
|
*
|
|
12643
|
-
* @param sourceDetail
|
|
12644
|
-
* @param colNames
|
|
12645
12294
|
*/
|
|
12646
|
-
function
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
}));
|
|
12295
|
+
function emptyQueue() {
|
|
12296
|
+
if (!isMixpanelInitialized) {
|
|
12297
|
+
return;
|
|
12298
|
+
}
|
|
12299
|
+
eventQueue.forEach((event) => {
|
|
12300
|
+
uploadMixpanelEvent(event.eventId, event.eventProps);
|
|
12301
|
+
});
|
|
12302
|
+
eventQueue = [];
|
|
12655
12303
|
}
|
|
12656
12304
|
/**
|
|
12657
12305
|
*
|
|
12658
|
-
* @param
|
|
12306
|
+
* @param sessionInfo
|
|
12659
12307
|
*/
|
|
12660
|
-
function
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
if (
|
|
12673
|
-
|
|
12674
|
-
epochRange: {
|
|
12675
|
-
startEpoch: colVal.value,
|
|
12676
|
-
},
|
|
12677
|
-
}];
|
|
12678
|
-
// Case for custom calendar.
|
|
12679
|
-
}
|
|
12680
|
-
else if ((_a = colVal.value) === null || _a === void 0 ? void 0 : _a.v) {
|
|
12681
|
-
dataValue = [{
|
|
12682
|
-
epochRange: {
|
|
12683
|
-
startEpoch: colVal.value.v.s,
|
|
12684
|
-
endEpoch: colVal.value.v.e,
|
|
12685
|
-
},
|
|
12686
|
-
}];
|
|
12308
|
+
function initMixpanel(sessionInfo) {
|
|
12309
|
+
var _a;
|
|
12310
|
+
if (!sessionInfo || !sessionInfo.mixpanelToken) {
|
|
12311
|
+
return;
|
|
12312
|
+
}
|
|
12313
|
+
// On a public cluster the user is anonymous, so don't set the identify to
|
|
12314
|
+
// userGUID
|
|
12315
|
+
const isPublicCluster = !!sessionInfo.isPublicUser;
|
|
12316
|
+
const token = sessionInfo.mixpanelToken;
|
|
12317
|
+
try {
|
|
12318
|
+
if (token) {
|
|
12319
|
+
mixpanelInstance = mixpanelLib.init(token, undefined, 'tsEmbed');
|
|
12320
|
+
if (!isPublicCluster) {
|
|
12321
|
+
mixpanelInstance.identify(sessionInfo.userGUID);
|
|
12687
12322
|
}
|
|
12323
|
+
mixpanelInstance.register_once({
|
|
12324
|
+
clusterId: sessionInfo.clusterId,
|
|
12325
|
+
clusterName: sessionInfo.clusterName,
|
|
12326
|
+
releaseVersion: sessionInfo.releaseVersion,
|
|
12327
|
+
hostAppUrl: ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.host) || '',
|
|
12328
|
+
});
|
|
12329
|
+
isMixpanelInitialized = true;
|
|
12330
|
+
emptyQueue();
|
|
12688
12331
|
}
|
|
12689
|
-
else {
|
|
12690
|
-
dataValue = [{ value: colVal.value }];
|
|
12691
|
-
}
|
|
12692
|
-
underlyingDataPoint.push({
|
|
12693
|
-
columnId: colVal.column.id,
|
|
12694
|
-
dataValue,
|
|
12695
|
-
});
|
|
12696
12332
|
}
|
|
12697
|
-
|
|
12698
|
-
|
|
12699
|
-
}
|
|
12700
|
-
return underlyingDataPoint;
|
|
12333
|
+
catch (e) {
|
|
12334
|
+
logger.error('Error initializing mixpanel', e);
|
|
12335
|
+
}
|
|
12701
12336
|
}
|
|
12702
12337
|
|
|
12703
12338
|
var eventemitter3 = createCommonjsModule(function (module) {
|
|
@@ -13154,114 +12789,534 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
|
|
|
13154
12789
|
return false;
|
|
13155
12790
|
}
|
|
13156
12791
|
|
|
13157
|
-
var _arrayIncludesWith = arrayIncludesWith;
|
|
13158
|
-
|
|
13159
|
-
/** Used as references for various `Number` constants. */
|
|
13160
|
-
var INFINITY = 1 / 0;
|
|
13161
|
-
|
|
13162
|
-
/**
|
|
13163
|
-
* Creates a set object of `values`.
|
|
13164
|
-
*
|
|
13165
|
-
* @private
|
|
13166
|
-
* @param {Array} values The values to add to the set.
|
|
13167
|
-
* @returns {Object} Returns the new set.
|
|
13168
|
-
*/
|
|
13169
|
-
var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) {
|
|
13170
|
-
return new _Set(values);
|
|
12792
|
+
var _arrayIncludesWith = arrayIncludesWith;
|
|
12793
|
+
|
|
12794
|
+
/** Used as references for various `Number` constants. */
|
|
12795
|
+
var INFINITY = 1 / 0;
|
|
12796
|
+
|
|
12797
|
+
/**
|
|
12798
|
+
* Creates a set object of `values`.
|
|
12799
|
+
*
|
|
12800
|
+
* @private
|
|
12801
|
+
* @param {Array} values The values to add to the set.
|
|
12802
|
+
* @returns {Object} Returns the new set.
|
|
12803
|
+
*/
|
|
12804
|
+
var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) {
|
|
12805
|
+
return new _Set(values);
|
|
12806
|
+
};
|
|
12807
|
+
|
|
12808
|
+
var _createSet = createSet;
|
|
12809
|
+
|
|
12810
|
+
/** Used as the size to enable large array optimizations. */
|
|
12811
|
+
var LARGE_ARRAY_SIZE$1 = 200;
|
|
12812
|
+
|
|
12813
|
+
/**
|
|
12814
|
+
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
|
|
12815
|
+
*
|
|
12816
|
+
* @private
|
|
12817
|
+
* @param {Array} array The array to inspect.
|
|
12818
|
+
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
12819
|
+
* @param {Function} [comparator] The comparator invoked per element.
|
|
12820
|
+
* @returns {Array} Returns the new duplicate free array.
|
|
12821
|
+
*/
|
|
12822
|
+
function baseUniq(array, iteratee, comparator) {
|
|
12823
|
+
var index = -1,
|
|
12824
|
+
includes = _arrayIncludes,
|
|
12825
|
+
length = array.length,
|
|
12826
|
+
isCommon = true,
|
|
12827
|
+
result = [],
|
|
12828
|
+
seen = result;
|
|
12829
|
+
|
|
12830
|
+
if (comparator) {
|
|
12831
|
+
isCommon = false;
|
|
12832
|
+
includes = _arrayIncludesWith;
|
|
12833
|
+
}
|
|
12834
|
+
else if (length >= LARGE_ARRAY_SIZE$1) {
|
|
12835
|
+
var set = iteratee ? null : _createSet(array);
|
|
12836
|
+
if (set) {
|
|
12837
|
+
return _setToArray(set);
|
|
12838
|
+
}
|
|
12839
|
+
isCommon = false;
|
|
12840
|
+
includes = _cacheHas;
|
|
12841
|
+
seen = new _SetCache;
|
|
12842
|
+
}
|
|
12843
|
+
else {
|
|
12844
|
+
seen = iteratee ? [] : result;
|
|
12845
|
+
}
|
|
12846
|
+
outer:
|
|
12847
|
+
while (++index < length) {
|
|
12848
|
+
var value = array[index],
|
|
12849
|
+
computed = iteratee ? iteratee(value) : value;
|
|
12850
|
+
|
|
12851
|
+
value = (comparator || value !== 0) ? value : 0;
|
|
12852
|
+
if (isCommon && computed === computed) {
|
|
12853
|
+
var seenIndex = seen.length;
|
|
12854
|
+
while (seenIndex--) {
|
|
12855
|
+
if (seen[seenIndex] === computed) {
|
|
12856
|
+
continue outer;
|
|
12857
|
+
}
|
|
12858
|
+
}
|
|
12859
|
+
if (iteratee) {
|
|
12860
|
+
seen.push(computed);
|
|
12861
|
+
}
|
|
12862
|
+
result.push(value);
|
|
12863
|
+
}
|
|
12864
|
+
else if (!includes(seen, computed, comparator)) {
|
|
12865
|
+
if (seen !== result) {
|
|
12866
|
+
seen.push(computed);
|
|
12867
|
+
}
|
|
12868
|
+
result.push(value);
|
|
12869
|
+
}
|
|
12870
|
+
}
|
|
12871
|
+
return result;
|
|
12872
|
+
}
|
|
12873
|
+
|
|
12874
|
+
var _baseUniq = baseUniq;
|
|
12875
|
+
|
|
12876
|
+
/**
|
|
12877
|
+
* Creates a duplicate-free version of an array, using
|
|
12878
|
+
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
12879
|
+
* for equality comparisons, in which only the first occurrence of each element
|
|
12880
|
+
* is kept. The order of result values is determined by the order they occur
|
|
12881
|
+
* in the array.
|
|
12882
|
+
*
|
|
12883
|
+
* @static
|
|
12884
|
+
* @memberOf _
|
|
12885
|
+
* @since 0.1.0
|
|
12886
|
+
* @category Array
|
|
12887
|
+
* @param {Array} array The array to inspect.
|
|
12888
|
+
* @returns {Array} Returns the new duplicate free array.
|
|
12889
|
+
* @example
|
|
12890
|
+
*
|
|
12891
|
+
* _.uniq([2, 1, 2]);
|
|
12892
|
+
* // => [2, 1]
|
|
12893
|
+
*/
|
|
12894
|
+
function uniq(array) {
|
|
12895
|
+
return (array && array.length) ? _baseUniq(array) : [];
|
|
12896
|
+
}
|
|
12897
|
+
|
|
12898
|
+
var uniq_1 = uniq;
|
|
12899
|
+
|
|
12900
|
+
/**
|
|
12901
|
+
*
|
|
12902
|
+
* @param url
|
|
12903
|
+
* @param options
|
|
12904
|
+
*/
|
|
12905
|
+
function tokenisedFailureLoggedFetch(url, options = {}) {
|
|
12906
|
+
return tokenizedFetch(url, options).then(async (r) => {
|
|
12907
|
+
var _a;
|
|
12908
|
+
if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
|
|
12909
|
+
logger.error('Failure', await ((_a = r.text) === null || _a === void 0 ? void 0 : _a.call(r)));
|
|
12910
|
+
}
|
|
12911
|
+
return r;
|
|
12912
|
+
});
|
|
12913
|
+
}
|
|
12914
|
+
/**
|
|
12915
|
+
*
|
|
12916
|
+
* @param authVerificationUrl
|
|
12917
|
+
*/
|
|
12918
|
+
function fetchSessionInfoService(authVerificationUrl) {
|
|
12919
|
+
return tokenisedFailureLoggedFetch(authVerificationUrl, {
|
|
12920
|
+
credentials: 'include',
|
|
12921
|
+
});
|
|
12922
|
+
}
|
|
12923
|
+
/**
|
|
12924
|
+
*
|
|
12925
|
+
* @param thoughtSpotHost
|
|
12926
|
+
*/
|
|
12927
|
+
async function fetchLogoutService(thoughtSpotHost) {
|
|
12928
|
+
return tokenisedFailureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
|
|
12929
|
+
credentials: 'include',
|
|
12930
|
+
method: 'POST',
|
|
12931
|
+
headers: {
|
|
12932
|
+
'x-requested-by': 'ThoughtSpot',
|
|
12933
|
+
},
|
|
12934
|
+
});
|
|
12935
|
+
}
|
|
12936
|
+
|
|
12937
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
12938
|
+
let loggedInStatus = false;
|
|
12939
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
12940
|
+
let samlAuthWindow = null;
|
|
12941
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
12942
|
+
let samlCompletionPromise = null;
|
|
12943
|
+
let sessionInfo = null;
|
|
12944
|
+
let sessionInfoResolver = null;
|
|
12945
|
+
const sessionInfoPromise = new Promise((resolve) => {
|
|
12946
|
+
sessionInfoResolver = resolve;
|
|
12947
|
+
});
|
|
12948
|
+
let releaseVersion = '';
|
|
12949
|
+
const SSO_REDIRECTION_MARKER_GUID = '5e16222e-ef02-43e9-9fbd-24226bf3ce5b';
|
|
12950
|
+
(function (AuthFailureType) {
|
|
12951
|
+
AuthFailureType["SDK"] = "SDK";
|
|
12952
|
+
AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
|
|
12953
|
+
AuthFailureType["EXPIRY"] = "EXPIRY";
|
|
12954
|
+
AuthFailureType["OTHER"] = "OTHER";
|
|
12955
|
+
})(exports.AuthFailureType || (exports.AuthFailureType = {}));
|
|
12956
|
+
(function (AuthStatus) {
|
|
12957
|
+
/**
|
|
12958
|
+
* Emits when the SDK fails to authenticate
|
|
12959
|
+
*/
|
|
12960
|
+
AuthStatus["FAILURE"] = "FAILURE";
|
|
12961
|
+
/**
|
|
12962
|
+
* Emits when the SDK authenticates successfully
|
|
12963
|
+
*/
|
|
12964
|
+
AuthStatus["SDK_SUCCESS"] = "SDK_SUCCESS";
|
|
12965
|
+
/**
|
|
12966
|
+
* Emits when the app sends an authentication success message
|
|
12967
|
+
*/
|
|
12968
|
+
AuthStatus["SUCCESS"] = "SUCCESS";
|
|
12969
|
+
/**
|
|
12970
|
+
* Emits when a user logs out
|
|
12971
|
+
*/
|
|
12972
|
+
AuthStatus["LOGOUT"] = "LOGOUT";
|
|
12973
|
+
/**
|
|
12974
|
+
* Emitted when inPopup is true in the SAMLRedirect flow and the
|
|
12975
|
+
* popup is waiting to be triggered either programmatically
|
|
12976
|
+
* or by the trigger button.
|
|
12977
|
+
*
|
|
12978
|
+
* @version SDK: 1.19.0
|
|
12979
|
+
*/
|
|
12980
|
+
AuthStatus["WAITING_FOR_POPUP"] = "WAITING_FOR_POPUP";
|
|
12981
|
+
})(exports.AuthStatus || (exports.AuthStatus = {}));
|
|
12982
|
+
(function (AuthEvent) {
|
|
12983
|
+
/**
|
|
12984
|
+
* Manually trigger the SSO popup. This is useful when
|
|
12985
|
+
* authStatus is SAMLRedirect/OIDCRedirect and inPopup is set to true
|
|
12986
|
+
*/
|
|
12987
|
+
AuthEvent["TRIGGER_SSO_POPUP"] = "TRIGGER_SSO_POPUP";
|
|
12988
|
+
})(exports.AuthEvent || (exports.AuthEvent = {}));
|
|
12989
|
+
let authEE;
|
|
12990
|
+
/**
|
|
12991
|
+
*
|
|
12992
|
+
* @param eventEmitter
|
|
12993
|
+
*/
|
|
12994
|
+
function setAuthEE(eventEmitter) {
|
|
12995
|
+
authEE = eventEmitter;
|
|
12996
|
+
}
|
|
12997
|
+
/**
|
|
12998
|
+
*
|
|
12999
|
+
*/
|
|
13000
|
+
function notifyAuthSDKSuccess() {
|
|
13001
|
+
if (!authEE) {
|
|
13002
|
+
logger.error('SDK not initialized');
|
|
13003
|
+
return;
|
|
13004
|
+
}
|
|
13005
|
+
authEE.emit(exports.AuthStatus.SDK_SUCCESS);
|
|
13006
|
+
}
|
|
13007
|
+
/**
|
|
13008
|
+
*
|
|
13009
|
+
*/
|
|
13010
|
+
function notifyAuthSuccess() {
|
|
13011
|
+
if (!authEE) {
|
|
13012
|
+
logger.error('SDK not initialized');
|
|
13013
|
+
return;
|
|
13014
|
+
}
|
|
13015
|
+
authEE.emit(exports.AuthStatus.SUCCESS, sessionInfo);
|
|
13016
|
+
}
|
|
13017
|
+
/**
|
|
13018
|
+
*
|
|
13019
|
+
* @param failureType
|
|
13020
|
+
*/
|
|
13021
|
+
function notifyAuthFailure(failureType) {
|
|
13022
|
+
if (!authEE) {
|
|
13023
|
+
logger.error('SDK not initialized');
|
|
13024
|
+
return;
|
|
13025
|
+
}
|
|
13026
|
+
authEE.emit(exports.AuthStatus.FAILURE, failureType);
|
|
13027
|
+
}
|
|
13028
|
+
/**
|
|
13029
|
+
*
|
|
13030
|
+
*/
|
|
13031
|
+
function notifyLogout() {
|
|
13032
|
+
if (!authEE) {
|
|
13033
|
+
logger.error('SDK not initialized');
|
|
13034
|
+
return;
|
|
13035
|
+
}
|
|
13036
|
+
authEE.emit(exports.AuthStatus.LOGOUT);
|
|
13037
|
+
}
|
|
13038
|
+
const initSession = (sessionDetails) => {
|
|
13039
|
+
if (sessionInfo == null) {
|
|
13040
|
+
sessionInfo = sessionDetails;
|
|
13041
|
+
initMixpanel(sessionInfo);
|
|
13042
|
+
sessionInfoResolver(sessionInfo);
|
|
13043
|
+
}
|
|
13044
|
+
};
|
|
13045
|
+
const getSessionDetails = (sessionInfoResp) => {
|
|
13046
|
+
const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
|
|
13047
|
+
const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
|
|
13048
|
+
const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
|
|
13049
|
+
? prodMixpanelToken
|
|
13050
|
+
: devMixpanelToken;
|
|
13051
|
+
return {
|
|
13052
|
+
userGUID: sessionInfoResp.userGUID,
|
|
13053
|
+
mixpanelToken,
|
|
13054
|
+
isPublicUser: sessionInfoResp.configInfo.isPublicUser,
|
|
13055
|
+
releaseVersion: sessionInfoResp.releaseVersion,
|
|
13056
|
+
clusterId: sessionInfoResp.configInfo.selfClusterId,
|
|
13057
|
+
clusterName: sessionInfoResp.configInfo.selfClusterName,
|
|
13058
|
+
...sessionInfoResp,
|
|
13059
|
+
};
|
|
13060
|
+
};
|
|
13061
|
+
/**
|
|
13062
|
+
* Check if we are logged into the ThoughtSpot cluster
|
|
13063
|
+
*
|
|
13064
|
+
* @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
|
|
13065
|
+
*/
|
|
13066
|
+
async function isLoggedIn(thoughtSpotHost) {
|
|
13067
|
+
const authVerificationUrl = `${thoughtSpotHost}${EndPoints.AUTH_VERIFICATION}`;
|
|
13068
|
+
let response = null;
|
|
13069
|
+
try {
|
|
13070
|
+
response = await fetchSessionInfoService(authVerificationUrl);
|
|
13071
|
+
const sessionInfoResp = await response.json();
|
|
13072
|
+
const sessionDetails = getSessionDetails(sessionInfoResp);
|
|
13073
|
+
// Store user session details from session info
|
|
13074
|
+
initSession(sessionDetails);
|
|
13075
|
+
releaseVersion = sessionInfoResp.releaseVersion;
|
|
13076
|
+
}
|
|
13077
|
+
catch (e) {
|
|
13078
|
+
return false;
|
|
13079
|
+
}
|
|
13080
|
+
return response.status === 200;
|
|
13081
|
+
}
|
|
13082
|
+
/**
|
|
13083
|
+
* Return releaseVersion if available
|
|
13084
|
+
*/
|
|
13085
|
+
function getReleaseVersion() {
|
|
13086
|
+
return releaseVersion;
|
|
13087
|
+
}
|
|
13088
|
+
/**
|
|
13089
|
+
* Return a promise that resolves with the session information when
|
|
13090
|
+
* authentication is successful. And info is available.
|
|
13091
|
+
*
|
|
13092
|
+
* @group Global methods
|
|
13093
|
+
*/
|
|
13094
|
+
function getSessionInfo() {
|
|
13095
|
+
return sessionInfoPromise;
|
|
13096
|
+
}
|
|
13097
|
+
/**
|
|
13098
|
+
* Check if we are stuck at the SSO redirect URL
|
|
13099
|
+
*/
|
|
13100
|
+
function isAtSSORedirectUrl() {
|
|
13101
|
+
return window.location.href.indexOf(SSO_REDIRECTION_MARKER_GUID) >= 0;
|
|
13102
|
+
}
|
|
13103
|
+
/**
|
|
13104
|
+
* Remove the SSO redirect URL marker
|
|
13105
|
+
*/
|
|
13106
|
+
function removeSSORedirectUrlMarker() {
|
|
13107
|
+
// Note (sunny): This will leave a # around even if it was not in the URL
|
|
13108
|
+
// to begin with. Trying to remove the hash by changing window.location will
|
|
13109
|
+
// reload the page which we don't want. We'll live with adding an
|
|
13110
|
+
// unnecessary hash to the parent page URL until we find any use case where
|
|
13111
|
+
// that creates an issue.
|
|
13112
|
+
window.location.hash = window.location.hash.replace(SSO_REDIRECTION_MARKER_GUID, '');
|
|
13113
|
+
}
|
|
13114
|
+
/**
|
|
13115
|
+
* Perform token based authentication
|
|
13116
|
+
*
|
|
13117
|
+
* @param embedConfig The embed configuration
|
|
13118
|
+
*/
|
|
13119
|
+
const doTokenAuth = async (embedConfig) => {
|
|
13120
|
+
const { thoughtSpotHost, username, authEndpoint, getAuthToken, } = embedConfig;
|
|
13121
|
+
if (!authEndpoint && !getAuthToken) {
|
|
13122
|
+
throw new Error('Either auth endpoint or getAuthToken function must be provided');
|
|
13123
|
+
}
|
|
13124
|
+
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
13125
|
+
if (!loggedInStatus) {
|
|
13126
|
+
const authToken = await getAuthenticationToken(embedConfig);
|
|
13127
|
+
let resp;
|
|
13128
|
+
try {
|
|
13129
|
+
resp = await fetchAuthPostService(thoughtSpotHost, username, authToken);
|
|
13130
|
+
}
|
|
13131
|
+
catch (e) {
|
|
13132
|
+
resp = await fetchAuthService(thoughtSpotHost, username, authToken);
|
|
13133
|
+
}
|
|
13134
|
+
// token login issues a 302 when successful
|
|
13135
|
+
loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
|
|
13136
|
+
if (loggedInStatus && embedConfig.detectCookieAccessSlow) {
|
|
13137
|
+
// When 3rd party cookie access is blocked, this will fail because
|
|
13138
|
+
// cookies will not be sent with the call.
|
|
13139
|
+
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
13140
|
+
}
|
|
13141
|
+
}
|
|
13142
|
+
return loggedInStatus;
|
|
13143
|
+
};
|
|
13144
|
+
/**
|
|
13145
|
+
* Validate embedConfig parameters required for cookielessTokenAuth
|
|
13146
|
+
*
|
|
13147
|
+
* @param embedConfig The embed configuration
|
|
13148
|
+
*/
|
|
13149
|
+
const doCookielessTokenAuth = async (embedConfig) => {
|
|
13150
|
+
const { authEndpoint, getAuthToken } = embedConfig;
|
|
13151
|
+
if (!authEndpoint && !getAuthToken) {
|
|
13152
|
+
throw new Error('Either auth endpoint or getAuthToken function must be provided');
|
|
13153
|
+
}
|
|
13154
|
+
let authSuccess = false;
|
|
13155
|
+
try {
|
|
13156
|
+
const authToken = await getAuthenticationToken(embedConfig);
|
|
13157
|
+
if (authToken) {
|
|
13158
|
+
authSuccess = true;
|
|
13159
|
+
}
|
|
13160
|
+
}
|
|
13161
|
+
catch {
|
|
13162
|
+
authSuccess = false;
|
|
13163
|
+
}
|
|
13164
|
+
return authSuccess;
|
|
13165
|
+
};
|
|
13166
|
+
/**
|
|
13167
|
+
* Perform basic authentication to the ThoughtSpot cluster using the cluster
|
|
13168
|
+
* credentials.
|
|
13169
|
+
*
|
|
13170
|
+
* Warning: This feature is primarily intended for developer testing. It is
|
|
13171
|
+
* strongly advised not to use this authentication method in production.
|
|
13172
|
+
*
|
|
13173
|
+
* @param embedConfig The embed configuration
|
|
13174
|
+
*/
|
|
13175
|
+
const doBasicAuth = async (embedConfig) => {
|
|
13176
|
+
const { thoughtSpotHost, username, password } = embedConfig;
|
|
13177
|
+
const loggedIn = await isLoggedIn(thoughtSpotHost);
|
|
13178
|
+
if (!loggedIn) {
|
|
13179
|
+
const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
|
|
13180
|
+
loggedInStatus = response.ok;
|
|
13181
|
+
if (embedConfig.detectCookieAccessSlow) {
|
|
13182
|
+
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
13183
|
+
}
|
|
13184
|
+
}
|
|
13185
|
+
else {
|
|
13186
|
+
loggedInStatus = true;
|
|
13187
|
+
}
|
|
13188
|
+
return loggedInStatus;
|
|
13189
|
+
};
|
|
13190
|
+
/**
|
|
13191
|
+
*
|
|
13192
|
+
* @param ssoURL
|
|
13193
|
+
* @param triggerContainer
|
|
13194
|
+
* @param triggerText
|
|
13195
|
+
*/
|
|
13196
|
+
async function samlPopupFlow(ssoURL, triggerContainer, triggerText) {
|
|
13197
|
+
const openPopup = () => {
|
|
13198
|
+
if (samlAuthWindow === null || samlAuthWindow.closed) {
|
|
13199
|
+
samlAuthWindow = window.open(ssoURL, '_blank', 'location=no,height=570,width=520,scrollbars=yes,status=yes');
|
|
13200
|
+
}
|
|
13201
|
+
else {
|
|
13202
|
+
samlAuthWindow.focus();
|
|
13203
|
+
}
|
|
13204
|
+
};
|
|
13205
|
+
authEE === null || authEE === void 0 ? void 0 : authEE.emit(exports.AuthStatus.WAITING_FOR_POPUP);
|
|
13206
|
+
const containerEl = getDOMNode(triggerContainer);
|
|
13207
|
+
if (containerEl) {
|
|
13208
|
+
containerEl.innerHTML = '<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
|
|
13209
|
+
const authElem = document.getElementById('ts-auth-btn');
|
|
13210
|
+
authElem.textContent = triggerText;
|
|
13211
|
+
authElem.addEventListener('click', openPopup, { once: true });
|
|
13212
|
+
}
|
|
13213
|
+
samlCompletionPromise = samlCompletionPromise
|
|
13214
|
+
|| new Promise((resolve, reject) => {
|
|
13215
|
+
window.addEventListener('message', (e) => {
|
|
13216
|
+
if (e.data.type === exports.EmbedEvent.SAMLComplete) {
|
|
13217
|
+
e.source.close();
|
|
13218
|
+
resolve();
|
|
13219
|
+
}
|
|
13220
|
+
});
|
|
13221
|
+
});
|
|
13222
|
+
authEE === null || authEE === void 0 ? void 0 : authEE.once(exports.AuthEvent.TRIGGER_SSO_POPUP, openPopup);
|
|
13223
|
+
return samlCompletionPromise;
|
|
13224
|
+
}
|
|
13225
|
+
/**
|
|
13226
|
+
* Perform SAML authentication
|
|
13227
|
+
*
|
|
13228
|
+
* @param embedConfig The embed configuration
|
|
13229
|
+
* @param ssoEndPoint
|
|
13230
|
+
*/
|
|
13231
|
+
const doSSOAuth = async (embedConfig, ssoEndPoint) => {
|
|
13232
|
+
const { thoughtSpotHost } = embedConfig;
|
|
13233
|
+
const loggedIn = await isLoggedIn(thoughtSpotHost);
|
|
13234
|
+
if (loggedIn) {
|
|
13235
|
+
if (isAtSSORedirectUrl()) {
|
|
13236
|
+
removeSSORedirectUrlMarker();
|
|
13237
|
+
}
|
|
13238
|
+
loggedInStatus = true;
|
|
13239
|
+
return;
|
|
13240
|
+
}
|
|
13241
|
+
// we have already tried authentication and it did not succeed, restore
|
|
13242
|
+
// the current URL to the original one and invoke the callback.
|
|
13243
|
+
if (isAtSSORedirectUrl()) {
|
|
13244
|
+
removeSSORedirectUrlMarker();
|
|
13245
|
+
loggedInStatus = false;
|
|
13246
|
+
return;
|
|
13247
|
+
}
|
|
13248
|
+
const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
|
|
13249
|
+
if (embedConfig.inPopup) {
|
|
13250
|
+
await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
|
|
13251
|
+
loggedInStatus = await isLoggedIn(thoughtSpotHost);
|
|
13252
|
+
return;
|
|
13253
|
+
}
|
|
13254
|
+
window.location.href = ssoURL;
|
|
13255
|
+
};
|
|
13256
|
+
const doSamlAuth = async (embedConfig) => {
|
|
13257
|
+
const { thoughtSpotHost } = embedConfig;
|
|
13258
|
+
// redirect for SSO, when the SSO authentication is done, this page will be
|
|
13259
|
+
// loaded again and the same JS will execute again.
|
|
13260
|
+
const ssoRedirectUrl = embedConfig.inPopup
|
|
13261
|
+
? `${thoughtSpotHost}/v2/#/embed/saml-complete`
|
|
13262
|
+
: getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
|
|
13263
|
+
// bring back the page to the same URL
|
|
13264
|
+
const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
|
|
13265
|
+
await doSSOAuth(embedConfig, ssoEndPoint);
|
|
13266
|
+
return loggedInStatus;
|
|
13267
|
+
};
|
|
13268
|
+
const doOIDCAuth = async (embedConfig) => {
|
|
13269
|
+
const { thoughtSpotHost } = embedConfig;
|
|
13270
|
+
// redirect for SSO, when the SSO authentication is done, this page will be
|
|
13271
|
+
// loaded again and the same JS will execute again.
|
|
13272
|
+
const ssoRedirectUrl = embedConfig.noRedirect || embedConfig.inPopup
|
|
13273
|
+
? `${thoughtSpotHost}/v2/#/embed/saml-complete`
|
|
13274
|
+
: getRedirectUrl(window.location.href, SSO_REDIRECTION_MARKER_GUID, embedConfig.redirectPath);
|
|
13275
|
+
// bring back the page to the same URL
|
|
13276
|
+
const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
|
|
13277
|
+
await doSSOAuth(embedConfig, ssoEndPoint);
|
|
13278
|
+
return loggedInStatus;
|
|
13279
|
+
};
|
|
13280
|
+
const logout = async (embedConfig) => {
|
|
13281
|
+
const { thoughtSpotHost } = embedConfig;
|
|
13282
|
+
await fetchLogoutService(thoughtSpotHost);
|
|
13283
|
+
resetCachedAuthToken();
|
|
13284
|
+
const thoughtspotIframes = document.querySelectorAll('[data-ts-iframe=\'true\']');
|
|
13285
|
+
if (thoughtspotIframes === null || thoughtspotIframes === void 0 ? void 0 : thoughtspotIframes.length) {
|
|
13286
|
+
thoughtspotIframes.forEach((el) => {
|
|
13287
|
+
el.parentElement.innerHTML = embedConfig.loginFailedMessage;
|
|
13288
|
+
});
|
|
13289
|
+
}
|
|
13290
|
+
loggedInStatus = false;
|
|
13291
|
+
return loggedInStatus;
|
|
13292
|
+
};
|
|
13293
|
+
/**
|
|
13294
|
+
* Perform authentication on the ThoughtSpot cluster
|
|
13295
|
+
*
|
|
13296
|
+
* @param embedConfig The embed configuration
|
|
13297
|
+
*/
|
|
13298
|
+
const authenticate = async (embedConfig) => {
|
|
13299
|
+
const { authType } = embedConfig;
|
|
13300
|
+
switch (authType) {
|
|
13301
|
+
case exports.AuthType.SSO:
|
|
13302
|
+
case exports.AuthType.SAMLRedirect:
|
|
13303
|
+
case exports.AuthType.SAML:
|
|
13304
|
+
return doSamlAuth(embedConfig);
|
|
13305
|
+
case exports.AuthType.OIDC:
|
|
13306
|
+
case exports.AuthType.OIDCRedirect:
|
|
13307
|
+
return doOIDCAuth(embedConfig);
|
|
13308
|
+
case exports.AuthType.AuthServer:
|
|
13309
|
+
case exports.AuthType.TrustedAuthToken:
|
|
13310
|
+
return doTokenAuth(embedConfig);
|
|
13311
|
+
case exports.AuthType.TrustedAuthTokenCookieless:
|
|
13312
|
+
return doCookielessTokenAuth(embedConfig);
|
|
13313
|
+
case exports.AuthType.Basic:
|
|
13314
|
+
return doBasicAuth(embedConfig);
|
|
13315
|
+
default:
|
|
13316
|
+
return Promise.resolve(true);
|
|
13317
|
+
}
|
|
13171
13318
|
};
|
|
13172
13319
|
|
|
13173
|
-
var _createSet = createSet;
|
|
13174
|
-
|
|
13175
|
-
/** Used as the size to enable large array optimizations. */
|
|
13176
|
-
var LARGE_ARRAY_SIZE$1 = 200;
|
|
13177
|
-
|
|
13178
|
-
/**
|
|
13179
|
-
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
|
|
13180
|
-
*
|
|
13181
|
-
* @private
|
|
13182
|
-
* @param {Array} array The array to inspect.
|
|
13183
|
-
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
13184
|
-
* @param {Function} [comparator] The comparator invoked per element.
|
|
13185
|
-
* @returns {Array} Returns the new duplicate free array.
|
|
13186
|
-
*/
|
|
13187
|
-
function baseUniq(array, iteratee, comparator) {
|
|
13188
|
-
var index = -1,
|
|
13189
|
-
includes = _arrayIncludes,
|
|
13190
|
-
length = array.length,
|
|
13191
|
-
isCommon = true,
|
|
13192
|
-
result = [],
|
|
13193
|
-
seen = result;
|
|
13194
|
-
|
|
13195
|
-
if (comparator) {
|
|
13196
|
-
isCommon = false;
|
|
13197
|
-
includes = _arrayIncludesWith;
|
|
13198
|
-
}
|
|
13199
|
-
else if (length >= LARGE_ARRAY_SIZE$1) {
|
|
13200
|
-
var set = iteratee ? null : _createSet(array);
|
|
13201
|
-
if (set) {
|
|
13202
|
-
return _setToArray(set);
|
|
13203
|
-
}
|
|
13204
|
-
isCommon = false;
|
|
13205
|
-
includes = _cacheHas;
|
|
13206
|
-
seen = new _SetCache;
|
|
13207
|
-
}
|
|
13208
|
-
else {
|
|
13209
|
-
seen = iteratee ? [] : result;
|
|
13210
|
-
}
|
|
13211
|
-
outer:
|
|
13212
|
-
while (++index < length) {
|
|
13213
|
-
var value = array[index],
|
|
13214
|
-
computed = iteratee ? iteratee(value) : value;
|
|
13215
|
-
|
|
13216
|
-
value = (comparator || value !== 0) ? value : 0;
|
|
13217
|
-
if (isCommon && computed === computed) {
|
|
13218
|
-
var seenIndex = seen.length;
|
|
13219
|
-
while (seenIndex--) {
|
|
13220
|
-
if (seen[seenIndex] === computed) {
|
|
13221
|
-
continue outer;
|
|
13222
|
-
}
|
|
13223
|
-
}
|
|
13224
|
-
if (iteratee) {
|
|
13225
|
-
seen.push(computed);
|
|
13226
|
-
}
|
|
13227
|
-
result.push(value);
|
|
13228
|
-
}
|
|
13229
|
-
else if (!includes(seen, computed, comparator)) {
|
|
13230
|
-
if (seen !== result) {
|
|
13231
|
-
seen.push(computed);
|
|
13232
|
-
}
|
|
13233
|
-
result.push(value);
|
|
13234
|
-
}
|
|
13235
|
-
}
|
|
13236
|
-
return result;
|
|
13237
|
-
}
|
|
13238
|
-
|
|
13239
|
-
var _baseUniq = baseUniq;
|
|
13240
|
-
|
|
13241
|
-
/**
|
|
13242
|
-
* Creates a duplicate-free version of an array, using
|
|
13243
|
-
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
13244
|
-
* for equality comparisons, in which only the first occurrence of each element
|
|
13245
|
-
* is kept. The order of result values is determined by the order they occur
|
|
13246
|
-
* in the array.
|
|
13247
|
-
*
|
|
13248
|
-
* @static
|
|
13249
|
-
* @memberOf _
|
|
13250
|
-
* @since 0.1.0
|
|
13251
|
-
* @category Array
|
|
13252
|
-
* @param {Array} array The array to inspect.
|
|
13253
|
-
* @returns {Array} Returns the new duplicate free array.
|
|
13254
|
-
* @example
|
|
13255
|
-
*
|
|
13256
|
-
* _.uniq([2, 1, 2]);
|
|
13257
|
-
* // => [2, 1]
|
|
13258
|
-
*/
|
|
13259
|
-
function uniq(array) {
|
|
13260
|
-
return (array && array.length) ? _baseUniq(array) : [];
|
|
13261
|
-
}
|
|
13262
|
-
|
|
13263
|
-
var uniq_1 = uniq;
|
|
13264
|
-
|
|
13265
13320
|
/* eslint-disable camelcase */
|
|
13266
13321
|
const CONFIG_DEFAULTS = {
|
|
13267
13322
|
loginFailedMessage: 'Not logged in',
|
|
@@ -13722,6 +13777,8 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
|
|
|
13722
13777
|
});
|
|
13723
13778
|
}
|
|
13724
13779
|
|
|
13780
|
+
var name="@thoughtspot/visual-embed-sdk";var version="1.28.0-alpha.1";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$1={".":{"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$1,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};
|
|
13781
|
+
|
|
13725
13782
|
/**
|
|
13726
13783
|
* Copyright (c) 2022
|
|
13727
13784
|
*
|
|
@@ -15221,7 +15278,7 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
|
|
|
15221
15278
|
}
|
|
15222
15279
|
getEmbedParams() {
|
|
15223
15280
|
var _a;
|
|
15224
|
-
const { hideResults,
|
|
15281
|
+
const { hideResults, enableSearchAssist, forceTable, searchOptions, runtimeFilters, dataSource, dataSources, excludeRuntimeFiltersfromURL, hideSearchBar, dataPanelV2 = false, useLastSelectedSources = false, runtimeParameters, } = this.viewConfig;
|
|
15225
15282
|
const queryParams = this.getBaseQueryParams();
|
|
15226
15283
|
queryParams[Param.HideActions] = [
|
|
15227
15284
|
...((_a = queryParams[Param.HideActions]) !== null && _a !== void 0 ? _a : []),
|
|
@@ -15463,6 +15520,7 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
|
|
|
15463
15520
|
exports.AnswerService = AnswerService;
|
|
15464
15521
|
exports.AppEmbed = AppEmbed;
|
|
15465
15522
|
exports.LiveboardEmbed = LiveboardEmbed;
|
|
15523
|
+
exports.MIXPANEL_EVENT = MIXPANEL_EVENT;
|
|
15466
15524
|
exports.PinboardEmbed = PinboardEmbed;
|
|
15467
15525
|
exports.SageEmbed = SageEmbed;
|
|
15468
15526
|
exports.SearchBarEmbed = SearchBarEmbed;
|
|
@@ -15474,6 +15532,7 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
|
|
|
15474
15532
|
exports.init = init;
|
|
15475
15533
|
exports.logout = logout$1;
|
|
15476
15534
|
exports.prefetch = prefetch;
|
|
15535
|
+
exports.uploadMixpanelEvent = uploadMixpanelEvent;
|
|
15477
15536
|
|
|
15478
15537
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
15479
15538
|
|