@thoughtspot/visual-embed-sdk 1.10.0 → 1.10.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.
Files changed (68) hide show
  1. package/dist/src/auth.d.ts +18 -5
  2. package/dist/src/embed/base.d.ts +21 -5
  3. package/dist/src/embed/pinboard.d.ts +91 -0
  4. package/dist/src/index.d.ts +3 -2
  5. package/dist/src/types.d.ts +15 -0
  6. package/dist/src/utils/authService.d.ts +1 -0
  7. package/dist/src/utils/plugin.d.ts +0 -0
  8. package/dist/src/utils/processData.d.ts +1 -1
  9. package/dist/src/v1/api.d.ts +19 -0
  10. package/dist/tsembed.es.js +521 -32
  11. package/dist/tsembed.js +519 -31
  12. package/lib/package.json +2 -1
  13. package/lib/src/auth.d.ts +18 -5
  14. package/lib/src/auth.js +48 -9
  15. package/lib/src/auth.js.map +1 -1
  16. package/lib/src/auth.spec.js +69 -11
  17. package/lib/src/auth.spec.js.map +1 -1
  18. package/lib/src/embed/base.d.ts +21 -5
  19. package/lib/src/embed/base.js +64 -10
  20. package/lib/src/embed/base.js.map +1 -1
  21. package/lib/src/embed/base.spec.js +49 -3
  22. package/lib/src/embed/base.spec.js.map +1 -1
  23. package/lib/src/embed/embed.spec.js +1 -1
  24. package/lib/src/embed/embed.spec.js.map +1 -1
  25. package/lib/src/embed/pinboard.d.ts +91 -0
  26. package/lib/src/embed/pinboard.js +110 -0
  27. package/lib/src/embed/pinboard.js.map +1 -0
  28. package/lib/src/embed/ts-embed.js +9 -10
  29. package/lib/src/embed/ts-embed.js.map +1 -1
  30. package/lib/src/embed/ts-embed.spec.js +16 -6
  31. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  32. package/lib/src/index.d.ts +3 -2
  33. package/lib/src/index.js +3 -2
  34. package/lib/src/index.js.map +1 -1
  35. package/lib/src/test/test-utils.js +1 -1
  36. package/lib/src/test/test-utils.js.map +1 -1
  37. package/lib/src/types.d.ts +15 -0
  38. package/lib/src/types.js +10 -0
  39. package/lib/src/types.js.map +1 -1
  40. package/lib/src/utils/authService.d.ts +1 -0
  41. package/lib/src/utils/authService.js +21 -3
  42. package/lib/src/utils/authService.js.map +1 -1
  43. package/lib/src/utils/authService.spec.js +21 -5
  44. package/lib/src/utils/authService.spec.js.map +1 -1
  45. package/lib/src/utils/plugin.d.ts +0 -0
  46. package/lib/src/utils/plugin.js +1 -0
  47. package/lib/src/utils/plugin.js.map +1 -0
  48. package/lib/src/utils/processData.d.ts +1 -1
  49. package/lib/src/utils/processData.js +37 -3
  50. package/lib/src/utils/processData.js.map +1 -1
  51. package/lib/src/utils/processData.spec.js +106 -4
  52. package/lib/src/utils/processData.spec.js.map +1 -1
  53. package/lib/src/visual-embed-sdk.d.ts +100 -7
  54. package/package.json +2 -1
  55. package/src/auth.spec.ts +90 -11
  56. package/src/auth.ts +63 -13
  57. package/src/embed/base.spec.ts +56 -4
  58. package/src/embed/base.ts +83 -16
  59. package/src/embed/embed.spec.ts +1 -1
  60. package/src/embed/ts-embed.spec.ts +19 -9
  61. package/src/embed/ts-embed.ts +15 -12
  62. package/src/index.ts +5 -1
  63. package/src/test/test-utils.ts +1 -1
  64. package/src/types.ts +16 -0
  65. package/src/utils/authService.spec.ts +31 -5
  66. package/src/utils/authService.ts +27 -3
  67. package/src/utils/processData.spec.ts +139 -4
  68. package/src/utils/processData.ts +54 -4
@@ -306,6 +306,16 @@ var EmbedEvent;
306
306
  * The ThoughtSpot auth session has expired.
307
307
  */
308
308
  EmbedEvent["AuthExpire"] = "ThoughtspotAuthExpired";
309
+ /**
310
+ * ThoughtSpot failed to validate the auth session.
311
+ * @hidden
312
+ */
313
+ EmbedEvent["AuthFailure"] = "ThoughtspotAuthFailure";
314
+ /**
315
+ * ThoughtSpot failed to validate the auth session.
316
+ * @hidden
317
+ */
318
+ EmbedEvent["AuthLogout"] = "ThoughtspotAuthLogout";
309
319
  /**
310
320
  * The height of the embedded Liveboard or visualization has been computed.
311
321
  * @return data - The height of the embedded Liveboard or visualization
@@ -8686,9 +8696,361 @@ function initMixpanel(sessionInfo) {
8686
8696
  }
8687
8697
  }
8688
8698
 
8699
+ function createCommonjsModule(fn) {
8700
+ var module = { exports: {} };
8701
+ return fn(module, module.exports), module.exports;
8702
+ }
8703
+
8704
+ var eventemitter3 = createCommonjsModule(function (module) {
8705
+
8706
+ var has = Object.prototype.hasOwnProperty
8707
+ , prefix = '~';
8708
+
8709
+ /**
8710
+ * Constructor to create a storage for our `EE` objects.
8711
+ * An `Events` instance is a plain object whose properties are event names.
8712
+ *
8713
+ * @constructor
8714
+ * @private
8715
+ */
8716
+ function Events() {}
8717
+
8718
+ //
8719
+ // We try to not inherit from `Object.prototype`. In some engines creating an
8720
+ // instance in this way is faster than calling `Object.create(null)` directly.
8721
+ // If `Object.create(null)` is not supported we prefix the event names with a
8722
+ // character to make sure that the built-in object properties are not
8723
+ // overridden or used as an attack vector.
8724
+ //
8725
+ if (Object.create) {
8726
+ Events.prototype = Object.create(null);
8727
+
8728
+ //
8729
+ // This hack is needed because the `__proto__` property is still inherited in
8730
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
8731
+ //
8732
+ if (!new Events().__proto__) prefix = false;
8733
+ }
8734
+
8735
+ /**
8736
+ * Representation of a single event listener.
8737
+ *
8738
+ * @param {Function} fn The listener function.
8739
+ * @param {*} context The context to invoke the listener with.
8740
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
8741
+ * @constructor
8742
+ * @private
8743
+ */
8744
+ function EE(fn, context, once) {
8745
+ this.fn = fn;
8746
+ this.context = context;
8747
+ this.once = once || false;
8748
+ }
8749
+
8750
+ /**
8751
+ * Add a listener for a given event.
8752
+ *
8753
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
8754
+ * @param {(String|Symbol)} event The event name.
8755
+ * @param {Function} fn The listener function.
8756
+ * @param {*} context The context to invoke the listener with.
8757
+ * @param {Boolean} once Specify if the listener is a one-time listener.
8758
+ * @returns {EventEmitter}
8759
+ * @private
8760
+ */
8761
+ function addListener(emitter, event, fn, context, once) {
8762
+ if (typeof fn !== 'function') {
8763
+ throw new TypeError('The listener must be a function');
8764
+ }
8765
+
8766
+ var listener = new EE(fn, context || emitter, once)
8767
+ , evt = prefix ? prefix + event : event;
8768
+
8769
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
8770
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
8771
+ else emitter._events[evt] = [emitter._events[evt], listener];
8772
+
8773
+ return emitter;
8774
+ }
8775
+
8776
+ /**
8777
+ * Clear event by name.
8778
+ *
8779
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
8780
+ * @param {(String|Symbol)} evt The Event name.
8781
+ * @private
8782
+ */
8783
+ function clearEvent(emitter, evt) {
8784
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
8785
+ else delete emitter._events[evt];
8786
+ }
8787
+
8788
+ /**
8789
+ * Minimal `EventEmitter` interface that is molded against the Node.js
8790
+ * `EventEmitter` interface.
8791
+ *
8792
+ * @constructor
8793
+ * @public
8794
+ */
8795
+ function EventEmitter() {
8796
+ this._events = new Events();
8797
+ this._eventsCount = 0;
8798
+ }
8799
+
8800
+ /**
8801
+ * Return an array listing the events for which the emitter has registered
8802
+ * listeners.
8803
+ *
8804
+ * @returns {Array}
8805
+ * @public
8806
+ */
8807
+ EventEmitter.prototype.eventNames = function eventNames() {
8808
+ var names = []
8809
+ , events
8810
+ , name;
8811
+
8812
+ if (this._eventsCount === 0) return names;
8813
+
8814
+ for (name in (events = this._events)) {
8815
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
8816
+ }
8817
+
8818
+ if (Object.getOwnPropertySymbols) {
8819
+ return names.concat(Object.getOwnPropertySymbols(events));
8820
+ }
8821
+
8822
+ return names;
8823
+ };
8824
+
8825
+ /**
8826
+ * Return the listeners registered for a given event.
8827
+ *
8828
+ * @param {(String|Symbol)} event The event name.
8829
+ * @returns {Array} The registered listeners.
8830
+ * @public
8831
+ */
8832
+ EventEmitter.prototype.listeners = function listeners(event) {
8833
+ var evt = prefix ? prefix + event : event
8834
+ , handlers = this._events[evt];
8835
+
8836
+ if (!handlers) return [];
8837
+ if (handlers.fn) return [handlers.fn];
8838
+
8839
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
8840
+ ee[i] = handlers[i].fn;
8841
+ }
8842
+
8843
+ return ee;
8844
+ };
8845
+
8846
+ /**
8847
+ * Return the number of listeners listening to a given event.
8848
+ *
8849
+ * @param {(String|Symbol)} event The event name.
8850
+ * @returns {Number} The number of listeners.
8851
+ * @public
8852
+ */
8853
+ EventEmitter.prototype.listenerCount = function listenerCount(event) {
8854
+ var evt = prefix ? prefix + event : event
8855
+ , listeners = this._events[evt];
8856
+
8857
+ if (!listeners) return 0;
8858
+ if (listeners.fn) return 1;
8859
+ return listeners.length;
8860
+ };
8861
+
8862
+ /**
8863
+ * Calls each of the listeners registered for a given event.
8864
+ *
8865
+ * @param {(String|Symbol)} event The event name.
8866
+ * @returns {Boolean} `true` if the event had listeners, else `false`.
8867
+ * @public
8868
+ */
8869
+ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
8870
+ var evt = prefix ? prefix + event : event;
8871
+
8872
+ if (!this._events[evt]) return false;
8873
+
8874
+ var listeners = this._events[evt]
8875
+ , len = arguments.length
8876
+ , args
8877
+ , i;
8878
+
8879
+ if (listeners.fn) {
8880
+ if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
8881
+
8882
+ switch (len) {
8883
+ case 1: return listeners.fn.call(listeners.context), true;
8884
+ case 2: return listeners.fn.call(listeners.context, a1), true;
8885
+ case 3: return listeners.fn.call(listeners.context, a1, a2), true;
8886
+ case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
8887
+ case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
8888
+ case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
8889
+ }
8890
+
8891
+ for (i = 1, args = new Array(len -1); i < len; i++) {
8892
+ args[i - 1] = arguments[i];
8893
+ }
8894
+
8895
+ listeners.fn.apply(listeners.context, args);
8896
+ } else {
8897
+ var length = listeners.length
8898
+ , j;
8899
+
8900
+ for (i = 0; i < length; i++) {
8901
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
8902
+
8903
+ switch (len) {
8904
+ case 1: listeners[i].fn.call(listeners[i].context); break;
8905
+ case 2: listeners[i].fn.call(listeners[i].context, a1); break;
8906
+ case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
8907
+ case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
8908
+ default:
8909
+ if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
8910
+ args[j - 1] = arguments[j];
8911
+ }
8912
+
8913
+ listeners[i].fn.apply(listeners[i].context, args);
8914
+ }
8915
+ }
8916
+ }
8917
+
8918
+ return true;
8919
+ };
8920
+
8921
+ /**
8922
+ * Add a listener for a given event.
8923
+ *
8924
+ * @param {(String|Symbol)} event The event name.
8925
+ * @param {Function} fn The listener function.
8926
+ * @param {*} [context=this] The context to invoke the listener with.
8927
+ * @returns {EventEmitter} `this`.
8928
+ * @public
8929
+ */
8930
+ EventEmitter.prototype.on = function on(event, fn, context) {
8931
+ return addListener(this, event, fn, context, false);
8932
+ };
8933
+
8934
+ /**
8935
+ * Add a one-time listener for a given event.
8936
+ *
8937
+ * @param {(String|Symbol)} event The event name.
8938
+ * @param {Function} fn The listener function.
8939
+ * @param {*} [context=this] The context to invoke the listener with.
8940
+ * @returns {EventEmitter} `this`.
8941
+ * @public
8942
+ */
8943
+ EventEmitter.prototype.once = function once(event, fn, context) {
8944
+ return addListener(this, event, fn, context, true);
8945
+ };
8946
+
8947
+ /**
8948
+ * Remove the listeners of a given event.
8949
+ *
8950
+ * @param {(String|Symbol)} event The event name.
8951
+ * @param {Function} fn Only remove the listeners that match this function.
8952
+ * @param {*} context Only remove the listeners that have this context.
8953
+ * @param {Boolean} once Only remove one-time listeners.
8954
+ * @returns {EventEmitter} `this`.
8955
+ * @public
8956
+ */
8957
+ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
8958
+ var evt = prefix ? prefix + event : event;
8959
+
8960
+ if (!this._events[evt]) return this;
8961
+ if (!fn) {
8962
+ clearEvent(this, evt);
8963
+ return this;
8964
+ }
8965
+
8966
+ var listeners = this._events[evt];
8967
+
8968
+ if (listeners.fn) {
8969
+ if (
8970
+ listeners.fn === fn &&
8971
+ (!once || listeners.once) &&
8972
+ (!context || listeners.context === context)
8973
+ ) {
8974
+ clearEvent(this, evt);
8975
+ }
8976
+ } else {
8977
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
8978
+ if (
8979
+ listeners[i].fn !== fn ||
8980
+ (once && !listeners[i].once) ||
8981
+ (context && listeners[i].context !== context)
8982
+ ) {
8983
+ events.push(listeners[i]);
8984
+ }
8985
+ }
8986
+
8987
+ //
8988
+ // Reset the array, or remove it completely if we have no more listeners.
8989
+ //
8990
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
8991
+ else clearEvent(this, evt);
8992
+ }
8993
+
8994
+ return this;
8995
+ };
8996
+
8997
+ /**
8998
+ * Remove all listeners, or those of the specified event.
8999
+ *
9000
+ * @param {(String|Symbol)} [event] The event name.
9001
+ * @returns {EventEmitter} `this`.
9002
+ * @public
9003
+ */
9004
+ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
9005
+ var evt;
9006
+
9007
+ if (event) {
9008
+ evt = prefix ? prefix + event : event;
9009
+ if (this._events[evt]) clearEvent(this, evt);
9010
+ } else {
9011
+ this._events = new Events();
9012
+ this._eventsCount = 0;
9013
+ }
9014
+
9015
+ return this;
9016
+ };
9017
+
9018
+ //
9019
+ // Alias methods names because people roll like that.
9020
+ //
9021
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
9022
+ EventEmitter.prototype.addListener = EventEmitter.prototype.on;
9023
+
9024
+ //
9025
+ // Expose the prefix.
9026
+ //
9027
+ EventEmitter.prefixed = prefix;
9028
+
9029
+ //
9030
+ // Allow `EventEmitter` to be imported as module namespace.
9031
+ //
9032
+ EventEmitter.EventEmitter = EventEmitter;
9033
+
9034
+ //
9035
+ // Expose the module.
9036
+ //
9037
+ {
9038
+ module.exports = EventEmitter;
9039
+ }
9040
+ });
9041
+
8689
9042
  // eslint-disable-next-line import/no-cycle
9043
+ function failureLoggedFetch(url, options = {}) {
9044
+ return fetch(url, options).then(async (r) => {
9045
+ var _a;
9046
+ if (!r.ok && r.type !== 'opaqueredirect' && r.type !== 'opaque') {
9047
+ console.error('Failure', await ((_a = r.text) === null || _a === void 0 ? void 0 : _a.call(r)));
9048
+ }
9049
+ return r;
9050
+ });
9051
+ }
8690
9052
  function fetchSessionInfoService(authVerificationUrl) {
8691
- return fetch(authVerificationUrl, {
9053
+ return failureLoggedFetch(authVerificationUrl, {
8692
9054
  credentials: 'include',
8693
9055
  });
8694
9056
  }
@@ -8696,12 +9058,14 @@ async function fetchAuthTokenService(authEndpoint) {
8696
9058
  return fetch(authEndpoint);
8697
9059
  }
8698
9060
  async function fetchAuthService(thoughtSpotHost, username, authToken) {
8699
- return fetch(`${thoughtSpotHost}${EndPoints.TOKEN_LOGIN}?username=${username}&auth_token=${authToken}`, {
9061
+ return failureLoggedFetch(`${thoughtSpotHost}${EndPoints.TOKEN_LOGIN}?username=${username}&auth_token=${authToken}`, {
8700
9062
  credentials: 'include',
9063
+ // We do not want to follow the redirect, as it starts giving a CORS error
9064
+ redirect: 'manual',
8701
9065
  });
8702
9066
  }
8703
9067
  async function fetchBasicAuthService(thoughtSpotHost, username, password) {
8704
- return fetch(`${thoughtSpotHost}${EndPoints.BASIC_LOGIN}`, {
9068
+ return failureLoggedFetch(`${thoughtSpotHost}${EndPoints.BASIC_LOGIN}`, {
8705
9069
  method: 'POST',
8706
9070
  headers: {
8707
9071
  'content-type': 'application/x-www-form-urlencoded',
@@ -8710,6 +9074,13 @@ async function fetchBasicAuthService(thoughtSpotHost, username, password) {
8710
9074
  body: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`,
8711
9075
  credentials: 'include',
8712
9076
  });
9077
+ }
9078
+ async function fetchLogoutService(thoughtSpotHost) {
9079
+ return failureLoggedFetch(`${thoughtSpotHost}${EndPoints.LOGOUT}`, {
9080
+ credentials: 'include',
9081
+ mode: 'no-cors',
9082
+ method: 'POST',
9083
+ });
8713
9084
  }
8714
9085
 
8715
9086
  // eslint-disable-next-line import/no-mutable-exports
@@ -8727,7 +9098,21 @@ const EndPoints = {
8727
9098
  OIDC_LOGIN_TEMPLATE: (targetUrl) => `/callosum/v1/oidc/login?targetURLPath=${targetUrl}`,
8728
9099
  TOKEN_LOGIN: '/callosum/v1/session/login/token',
8729
9100
  BASIC_LOGIN: '/callosum/v1/session/login',
9101
+ LOGOUT: '/callosum/v1/session/logout',
8730
9102
  };
9103
+ var AuthFailureType;
9104
+ (function (AuthFailureType) {
9105
+ AuthFailureType["SDK"] = "SDK";
9106
+ AuthFailureType["NO_COOKIE_ACCESS"] = "NO_COOKIE_ACCESS";
9107
+ AuthFailureType["EXPIRY"] = "EXPIRY";
9108
+ AuthFailureType["OTHER"] = "OTHER";
9109
+ })(AuthFailureType || (AuthFailureType = {}));
9110
+ var AuthStatus;
9111
+ (function (AuthStatus) {
9112
+ AuthStatus["FAILURE"] = "FAILURE";
9113
+ AuthStatus["SUCCESS"] = "SUCCESS";
9114
+ AuthStatus["LOGOUT"] = "LOGOUT";
9115
+ })(AuthStatus || (AuthStatus = {}));
8731
9116
  /**
8732
9117
  * Check if we are logged into the ThoughtSpot cluster
8733
9118
  * @param thoughtSpotHost The ThoughtSpot cluster hostname or IP
@@ -8747,6 +9132,17 @@ function initSession(sessionDetails) {
8747
9132
  sessionInfo = sessionDetails;
8748
9133
  initMixpanel(sessionInfo);
8749
9134
  }
9135
+ const DUPLICATE_TOKEN_ERR = 'Duplicate token, please issue a new token every time getAuthToken callback is called.' +
9136
+ 'See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.';
9137
+ let prevAuthToken = null;
9138
+ function alertForDuplicateToken(authtoken) {
9139
+ if (prevAuthToken === authtoken) {
9140
+ // eslint-disable-next-line no-alert
9141
+ alert(DUPLICATE_TOKEN_ERR);
9142
+ throw new Error(DUPLICATE_TOKEN_ERR);
9143
+ }
9144
+ prevAuthToken = authtoken;
9145
+ }
8750
9146
  /**
8751
9147
  * Check if we are stuck at the SSO redirect URL
8752
9148
  */
@@ -8772,20 +9168,22 @@ const doTokenAuth = async (embedConfig) => {
8772
9168
  if (!authEndpoint && !getAuthToken) {
8773
9169
  throw new Error('Either auth endpoint or getAuthToken function must be provided');
8774
9170
  }
8775
- const loggedIn = await isLoggedIn(thoughtSpotHost);
8776
- if (!loggedIn) {
9171
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
9172
+ if (!loggedInStatus) {
8777
9173
  let authToken = null;
8778
9174
  if (getAuthToken) {
8779
9175
  authToken = await getAuthToken();
9176
+ alertForDuplicateToken(authToken);
8780
9177
  }
8781
9178
  else {
8782
9179
  const response = await fetchAuthTokenService(authEndpoint);
8783
9180
  authToken = await response.text();
8784
9181
  }
8785
- await fetchAuthService(thoughtSpotHost, username, authToken);
8786
- loggedInStatus = false;
9182
+ const resp = await fetchAuthService(thoughtSpotHost, username, authToken);
9183
+ // token login issues a 302 when successful
9184
+ loggedInStatus = resp.ok || resp.type === 'opaqueredirect';
8787
9185
  }
8788
- loggedInStatus = true;
9186
+ return loggedInStatus;
8789
9187
  };
8790
9188
  /**
8791
9189
  * Perform basic authentication to the ThoughtSpot cluster using the cluster
@@ -8800,9 +9198,12 @@ const doBasicAuth = async (embedConfig) => {
8800
9198
  const loggedIn = await isLoggedIn(thoughtSpotHost);
8801
9199
  if (!loggedIn) {
8802
9200
  const response = await fetchBasicAuthService(thoughtSpotHost, username, password);
8803
- loggedInStatus = response.status === 200;
9201
+ loggedInStatus = response.ok;
8804
9202
  }
8805
- loggedInStatus = true;
9203
+ else {
9204
+ loggedInStatus = true;
9205
+ }
9206
+ return loggedInStatus;
8806
9207
  };
8807
9208
  async function samlPopupFlow(ssoURL) {
8808
9209
  document.body.insertAdjacentHTML('beforeend', '<div id="ts-saml-auth"></div>');
@@ -8852,6 +9253,7 @@ const doSSOAuth = async (embedConfig, ssoEndPoint) => {
8852
9253
  const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
8853
9254
  if (embedConfig.noRedirect) {
8854
9255
  await samlPopupFlow(ssoURL);
9256
+ loggedInStatus = true;
8855
9257
  return;
8856
9258
  }
8857
9259
  window.location.href = ssoURL;
@@ -8866,6 +9268,7 @@ const doSamlAuth = async (embedConfig) => {
8866
9268
  // bring back the page to the same URL
8867
9269
  const ssoEndPoint = `${EndPoints.SAML_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
8868
9270
  await doSSOAuth(embedConfig, ssoEndPoint);
9271
+ return loggedInStatus;
8869
9272
  };
8870
9273
  const doOIDCAuth = async (embedConfig) => {
8871
9274
  const { thoughtSpotHost } = embedConfig;
@@ -8877,6 +9280,13 @@ const doOIDCAuth = async (embedConfig) => {
8877
9280
  // bring back the page to the same URL
8878
9281
  const ssoEndPoint = `${EndPoints.OIDC_LOGIN_TEMPLATE(encodeURIComponent(ssoRedirectUrl))}`;
8879
9282
  await doSSOAuth(embedConfig, ssoEndPoint);
9283
+ return loggedInStatus;
9284
+ };
9285
+ const logout = async (embedConfig) => {
9286
+ const { thoughtSpotHost } = embedConfig;
9287
+ const response = await fetchLogoutService(thoughtSpotHost);
9288
+ loggedInStatus = false;
9289
+ return loggedInStatus;
8880
9290
  };
8881
9291
  /**
8882
9292
  * Perform authentication on the ThoughtSpot cluster
@@ -8894,26 +9304,55 @@ const authenticate = async (embedConfig) => {
8894
9304
  case AuthType.Basic:
8895
9305
  return doBasicAuth(embedConfig);
8896
9306
  default:
8897
- return Promise.resolve();
9307
+ return Promise.resolve(true);
8898
9308
  }
8899
9309
  };
8900
9310
 
8901
9311
  /* eslint-disable import/no-mutable-exports */
8902
9312
  let config = {};
9313
+ const CONFIG_DEFAULTS = {
9314
+ loginFailedMessage: 'Not logged in',
9315
+ authType: AuthType.None,
9316
+ };
8903
9317
  let authPromise;
9318
+ const getEmbedConfig = () => config;
9319
+ const getAuthPromise = () => authPromise;
9320
+ let authEE;
9321
+ function notifyAuthSuccess() {
9322
+ if (!authEE) {
9323
+ console.error('SDK not initialized');
9324
+ return;
9325
+ }
9326
+ authEE.emit(AuthStatus.SUCCESS);
9327
+ }
9328
+ function notifyAuthFailure(failureType) {
9329
+ if (!authEE) {
9330
+ console.error('SDK not initialized');
9331
+ return;
9332
+ }
9333
+ authEE.emit(AuthStatus.FAILURE, failureType);
9334
+ }
9335
+ function notifyLogout() {
9336
+ if (!authEE) {
9337
+ console.error('SDK not initialized');
9338
+ return;
9339
+ }
9340
+ authEE.emit(AuthStatus.LOGOUT);
9341
+ }
8904
9342
  /**
8905
9343
  * Perform authentication on the ThoughtSpot app as applicable.
8906
9344
  */
8907
9345
  const handleAuth = () => {
8908
- const authConfig = {
8909
- ...config,
8910
- thoughtSpotHost: getThoughtSpotHost(config),
8911
- };
8912
- authPromise = authenticate(authConfig);
9346
+ authPromise = authenticate(config);
9347
+ authPromise.then((isLoggedIn) => {
9348
+ if (!isLoggedIn) {
9349
+ notifyAuthFailure(AuthFailureType.SDK);
9350
+ }
9351
+ }, () => {
9352
+ notifyAuthFailure(AuthFailureType.SDK);
9353
+ });
8913
9354
  return authPromise;
8914
9355
  };
8915
- const getEmbedConfig = () => config;
8916
- const getAuthPromise = () => authPromise;
8917
9356
  /**
8918
9357
  * Prefetches static resources from the specified URL. Web browsers can then cache the prefetched resources and serve them from the user's local disk to provide faster access to your app.
8919
9358
  * @param url The URL provided for prefetch
@@ -8942,7 +9381,12 @@ const prefetch = (url) => {
8942
9381
  * @returns authPromise Promise which resolves when authentication is complete.
8943
9382
  */
8944
9383
  const init = (embedConfig) => {
8945
- config = embedConfig;
9384
+ config = {
9385
+ ...CONFIG_DEFAULTS,
9386
+ ...embedConfig,
9387
+ thoughtSpotHost: getThoughtSpotHost(embedConfig),
9388
+ };
9389
+ authEE = new eventemitter3();
8946
9390
  handleAuth();
8947
9391
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_CALLED_INIT, {
8948
9392
  authType: config.authType,
@@ -8951,7 +9395,19 @@ const init = (embedConfig) => {
8951
9395
  if (config.callPrefetch) {
8952
9396
  prefetch(config.thoughtSpotHost);
8953
9397
  }
8954
- return authPromise;
9398
+ return authEE;
9399
+ };
9400
+ function disableAutoLogin() {
9401
+ config.autoLogin = false;
9402
+ }
9403
+ const logout$1 = (doNotDisableAutoLogin = false) => {
9404
+ if (!doNotDisableAutoLogin) {
9405
+ disableAutoLogin();
9406
+ }
9407
+ return logout(config).then((isLoggedIn) => {
9408
+ notifyLogout();
9409
+ return isLoggedIn;
9410
+ });
8955
9411
  };
8956
9412
  let renderQueue = Promise.resolve();
8957
9413
  /**
@@ -9037,6 +9493,7 @@ function processAuthInit(e) {
9037
9493
  var _a, _b;
9038
9494
  // Store user session details sent by app.
9039
9495
  initSession(e.data);
9496
+ notifyAuthSuccess();
9040
9497
  // Expose only allowed details (eg: userGUID) back to SDK users.
9041
9498
  return {
9042
9499
  ...e,
@@ -9050,9 +9507,36 @@ function processAuthExpire(e) {
9050
9507
  if (autoLogin) {
9051
9508
  handleAuth();
9052
9509
  }
9510
+ notifyAuthFailure(AuthFailureType.EXPIRY);
9511
+ return e;
9512
+ }
9513
+ function processNoCookieAccess(e, containerEl) {
9514
+ const { loginFailedMessage, suppressNoCookieAccessAlert, } = getEmbedConfig();
9515
+ if (!suppressNoCookieAccessAlert) {
9516
+ // eslint-disable-next-line no-alert
9517
+ alert('Third party cookie access is blocked on this browser, please allow third party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.');
9518
+ }
9519
+ // eslint-disable-next-line no-param-reassign
9520
+ containerEl.innerHTML = loginFailedMessage;
9521
+ notifyAuthFailure(AuthFailureType.NO_COOKIE_ACCESS);
9522
+ return e;
9523
+ }
9524
+ function processAuthFailure(e, containerEl) {
9525
+ const { loginFailedMessage } = getEmbedConfig();
9526
+ // eslint-disable-next-line no-param-reassign
9527
+ containerEl.innerHTML = loginFailedMessage;
9528
+ notifyAuthFailure(AuthFailureType.OTHER);
9053
9529
  return e;
9054
9530
  }
9055
- function getProcessData(type, e, thoughtSpotHost) {
9531
+ function processAuthLogout(e, containerEl) {
9532
+ const { loginFailedMessage } = getEmbedConfig();
9533
+ // eslint-disable-next-line no-param-reassign
9534
+ containerEl.innerHTML = loginFailedMessage;
9535
+ disableAutoLogin();
9536
+ notifyLogout();
9537
+ return e;
9538
+ }
9539
+ function processEventData(type, e, thoughtSpotHost, containerEl) {
9056
9540
  switch (type) {
9057
9541
  case EmbedEvent.CustomAction:
9058
9542
  return processCustomAction(e, thoughtSpotHost);
@@ -9060,6 +9544,12 @@ function getProcessData(type, e, thoughtSpotHost) {
9060
9544
  return processAuthInit(e);
9061
9545
  case EmbedEvent.AuthExpire:
9062
9546
  return processAuthExpire(e);
9547
+ case EmbedEvent.NoCookieAccess:
9548
+ return processNoCookieAccess(e, containerEl);
9549
+ case EmbedEvent.AuthFailure:
9550
+ return processAuthFailure(e, containerEl);
9551
+ case EmbedEvent.AuthLogout:
9552
+ return processAuthLogout(e, containerEl);
9063
9553
  }
9064
9554
  return e;
9065
9555
  }
@@ -9088,7 +9578,7 @@ function processTrigger(iFrame, messageType, thoughtSpotHost, data) {
9088
9578
  }
9089
9579
  }
9090
9580
 
9091
- var name="@thoughtspot/visual-embed-sdk";var version="1.10.0";var description="ThoughtSpot Embed SDK";var module="lib/src/index.js";var main="dist/tsembed.js";var types="lib/src/index.d.ts";var files=["dist/**","lib/**","src/**"];var exports={".":"./lib/src/index.js","./react":"./lib/src/react/index.js"};var scripts={lint:"eslint 'src/**'","lint:fix":"eslint 'src/**/*.*' --fix",tsc:"tsc -p . --incremental false",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":"dts-bundle --name @thoughtspot/visual-embed-sdk --out visual-embed-sdk.d.ts --main lib/src/index.d.ts",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","test-docs":"jest -c jest.config.docs.js",test:"npm run test-sdk && npm run test-docs && npx istanbul-merge --out ./coverage/coverage.json ./coverage/docs/coverage-final.json ./coverage/sdk/coverage-final.json && npx istanbul report --include ./coverage/coverage.json --dir ./coverage lcov",posttest:"cat ./coverage/sdk/lcov.info | coveralls",prepublishOnly:"npm run test; npm run tsc; npm run bundle-dts; npm run build","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","mixpanel-browser":"^2.41.0"};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","@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","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.1.0","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":"4.1.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-puppeteer":"^4.4.0",jsdom:"^17.0.0","node-sass":"^4.0.0",prettier:"2.1.2",puppeteer:"^7.0.1",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-neo-theme":"^1.1.0","typedoc-plugin-toc-group":"0.0.5",typescript:"^4.1.0","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,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};
9581
+ var name="@thoughtspot/visual-embed-sdk";var version="1.10.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/**"];var exports={".":"./lib/src/index.js","./react":"./lib/src/react/index.js"};var scripts={lint:"eslint 'src/**'","lint:fix":"eslint 'src/**/*.*' --fix",tsc:"tsc -p . --incremental false",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":"dts-bundle --name @thoughtspot/visual-embed-sdk --out visual-embed-sdk.d.ts --main lib/src/index.d.ts",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","test-docs":"jest -c jest.config.docs.js",test:"npm run test-sdk && npm run test-docs && npx istanbul-merge --out ./coverage/coverage.json ./coverage/docs/coverage-final.json ./coverage/sdk/coverage-final.json && npx istanbul report --include ./coverage/coverage.json --dir ./coverage lcov",posttest:"cat ./coverage/sdk/lcov.info | coveralls",prepublishOnly:"npm run test; npm run tsc; npm run bundle-dts; npm run build","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",eventemitter3:"^4.0.7","mixpanel-browser":"^2.41.0"};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","@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","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.1.0","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":"4.1.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-puppeteer":"^4.4.0",jsdom:"^17.0.0","node-sass":"^4.0.0",prettier:"2.1.2",puppeteer:"^7.0.1",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-neo-theme":"^1.1.0","typedoc-plugin-toc-group":"0.0.5",typescript:"^4.1.0","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,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};
9092
9582
 
9093
9583
  /**
9094
9584
  * Copyright (c) 2022
@@ -9135,12 +9625,6 @@ class TsEmbed {
9135
9625
  this.isError = false;
9136
9626
  this.viewConfig = viewConfig;
9137
9627
  this.shouldEncodeUrlQueryParams = this.embedConfig.shouldEncodeUrlQueryParams;
9138
- if (!this.embedConfig.suppressNoCookieAccessAlert) {
9139
- this.on(EmbedEvent.NoCookieAccess, () => {
9140
- // eslint-disable-next-line no-alert
9141
- alert('Third party cookie access is blocked on this browser, please allow third party cookies for ThoughtSpot to work properly');
9142
- });
9143
- }
9144
9628
  }
9145
9629
  /**
9146
9630
  * Gets a reference to the root DOM node where
@@ -9217,7 +9701,7 @@ class TsEmbed {
9217
9701
  const eventPort = this.getEventPort(event);
9218
9702
  const eventData = this.formatEventData(event, eventType);
9219
9703
  if (event.source === this.iFrame.contentWindow) {
9220
- this.executeCallbacks(eventType, getProcessData(eventType, eventData, this.thoughtSpotHost), eventPort);
9704
+ this.executeCallbacks(eventType, processEventData(eventType, eventData, this.thoughtSpotHost, this.el), eventPort);
9221
9705
  }
9222
9706
  });
9223
9707
  }
@@ -9336,7 +9820,11 @@ class TsEmbed {
9336
9820
  type: EmbedEvent.Init,
9337
9821
  });
9338
9822
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_START);
9339
- (_a = getAuthPromise()) === null || _a === void 0 ? void 0 : _a.then(() => {
9823
+ (_a = getAuthPromise()) === null || _a === void 0 ? void 0 : _a.then((isLoggedIn) => {
9824
+ if (!isLoggedIn) {
9825
+ this.el.innerHTML = this.embedConfig.loginFailedMessage;
9826
+ return;
9827
+ }
9340
9828
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_COMPLETE);
9341
9829
  this.iFrame =
9342
9830
  this.iFrame || document.createElement('iframe');
@@ -9352,7 +9840,7 @@ class TsEmbed {
9352
9840
  this.iFrame.mozallowfullscreen = true;
9353
9841
  const { height: frameHeight, width: frameWidth, ...restParams } = frameOptions;
9354
9842
  const width = getCssDimension(frameWidth || DEFAULT_EMBED_WIDTH);
9355
- const height = getCssDimension(frameWidth || DEFAULT_EMBED_HEIGHT);
9843
+ const height = getCssDimension(frameHeight || DEFAULT_EMBED_HEIGHT);
9356
9844
  setAttributes(this.iFrame, restParams);
9357
9845
  this.iFrame.style.width = `${width}`;
9358
9846
  this.iFrame.style.height = `${height}`;
@@ -9386,6 +9874,7 @@ class TsEmbed {
9386
9874
  }).catch((error) => {
9387
9875
  nextInQueue();
9388
9876
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_FAILED);
9877
+ this.el.innerHTML = this.embedConfig.loginFailedMessage;
9389
9878
  this.handleError(error);
9390
9879
  });
9391
9880
  });
@@ -9957,4 +10446,4 @@ class SearchEmbed extends TsEmbed {
9957
10446
  }
9958
10447
  }
9959
10448
 
9960
- export { Action, AppEmbed, AuthType, DataSourceVisualMode, EmbedEvent, HostEvent, LiveboardEmbed, Page, PinboardEmbed, RuntimeFilterOp, SearchEmbed, init, prefetch };
10449
+ export { Action, AppEmbed, AuthFailureType, AuthStatus, AuthType, DataSourceVisualMode, EmbedEvent, HostEvent, LiveboardEmbed, Page, PinboardEmbed, RuntimeFilterOp, SearchEmbed, init, logout$1 as logout, prefetch };