@thoughtspot/visual-embed-sdk 1.51.1 → 1.52.0

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 (130) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/api-intercept.d.ts.map +1 -1
  3. package/cjs/src/api-intercept.js +1 -0
  4. package/cjs/src/api-intercept.js.map +1 -1
  5. package/cjs/src/css-variables.d.ts +1 -1
  6. package/cjs/src/embed/conversation.d.ts +5 -5
  7. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  8. package/cjs/src/embed/liveboard.js +2 -1
  9. package/cjs/src/embed/liveboard.js.map +1 -1
  10. package/cjs/src/embed/liveboard.spec.js +4 -4
  11. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  12. package/cjs/src/embed/search.spec.js +28 -0
  13. package/cjs/src/embed/search.spec.js.map +1 -1
  14. package/cjs/src/embed/ts-embed.d.ts +86 -5
  15. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  16. package/cjs/src/embed/ts-embed.js +30 -19
  17. package/cjs/src/embed/ts-embed.js.map +1 -1
  18. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  19. package/cjs/src/embed/ts-embed.spec.js +55 -16
  20. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  21. package/cjs/src/index.d.ts +2 -2
  22. package/cjs/src/index.d.ts.map +1 -1
  23. package/cjs/src/index.js +2 -1
  24. package/cjs/src/index.js.map +1 -1
  25. package/cjs/src/react/all-types-export.d.ts +1 -1
  26. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  27. package/cjs/src/react/all-types-export.js +2 -1
  28. package/cjs/src/react/all-types-export.js.map +1 -1
  29. package/cjs/src/react/index.d.ts +8 -8
  30. package/cjs/src/react/index.d.ts.map +1 -1
  31. package/cjs/src/react/index.js +1 -1
  32. package/cjs/src/react/index.js.map +1 -1
  33. package/cjs/src/react/index.spec.js +7 -7
  34. package/cjs/src/react/index.spec.js.map +1 -1
  35. package/cjs/src/types.d.ts +124 -36
  36. package/cjs/src/types.d.ts.map +1 -1
  37. package/cjs/src/types.js +80 -12
  38. package/cjs/src/types.js.map +1 -1
  39. package/cjs/src/utils.d.ts +5 -0
  40. package/cjs/src/utils.d.ts.map +1 -1
  41. package/cjs/src/utils.js +19 -1
  42. package/cjs/src/utils.js.map +1 -1
  43. package/cjs/src/utils.spec.js +33 -0
  44. package/cjs/src/utils.spec.js.map +1 -1
  45. package/dist/{index-DxLfQxoT.js → index-BMppCU63.js} +1 -1
  46. package/dist/src/api-intercept.d.ts.map +1 -1
  47. package/dist/src/css-variables.d.ts +1 -1
  48. package/dist/src/embed/conversation.d.ts +5 -5
  49. package/dist/src/embed/liveboard.d.ts.map +1 -1
  50. package/dist/src/embed/ts-embed.d.ts +86 -5
  51. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  52. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  53. package/dist/src/index.d.ts +2 -2
  54. package/dist/src/index.d.ts.map +1 -1
  55. package/dist/src/react/all-types-export.d.ts +1 -1
  56. package/dist/src/react/all-types-export.d.ts.map +1 -1
  57. package/dist/src/react/index.d.ts +8 -8
  58. package/dist/src/react/index.d.ts.map +1 -1
  59. package/dist/src/types.d.ts +124 -36
  60. package/dist/src/types.d.ts.map +1 -1
  61. package/dist/src/utils.d.ts +5 -0
  62. package/dist/src/utils.d.ts.map +1 -1
  63. package/dist/tsembed-react.es.js +133 -35
  64. package/dist/tsembed-react.js +132 -34
  65. package/dist/tsembed.es.js +133 -35
  66. package/dist/tsembed.js +131 -33
  67. package/dist/visual-embed-sdk-react-full.d.ts +223 -54
  68. package/dist/visual-embed-sdk-react.d.ts +199 -53
  69. package/dist/visual-embed-sdk.d.ts +215 -46
  70. package/lib/package.json +1 -1
  71. package/lib/src/api-intercept.d.ts.map +1 -1
  72. package/lib/src/api-intercept.js +2 -1
  73. package/lib/src/api-intercept.js.map +1 -1
  74. package/lib/src/css-variables.d.ts +1 -1
  75. package/lib/src/embed/conversation.d.ts +5 -5
  76. package/lib/src/embed/liveboard.d.ts.map +1 -1
  77. package/lib/src/embed/liveboard.js +3 -2
  78. package/lib/src/embed/liveboard.js.map +1 -1
  79. package/lib/src/embed/liveboard.spec.js +4 -4
  80. package/lib/src/embed/liveboard.spec.js.map +1 -1
  81. package/lib/src/embed/search.spec.js +28 -0
  82. package/lib/src/embed/search.spec.js.map +1 -1
  83. package/lib/src/embed/ts-embed.d.ts +86 -5
  84. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  85. package/lib/src/embed/ts-embed.js +32 -21
  86. package/lib/src/embed/ts-embed.js.map +1 -1
  87. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  88. package/lib/src/embed/ts-embed.spec.js +56 -17
  89. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  90. package/lib/src/index.d.ts +2 -2
  91. package/lib/src/index.d.ts.map +1 -1
  92. package/lib/src/index.js +2 -2
  93. package/lib/src/index.js.map +1 -1
  94. package/lib/src/react/all-types-export.d.ts +1 -1
  95. package/lib/src/react/all-types-export.d.ts.map +1 -1
  96. package/lib/src/react/all-types-export.js +1 -1
  97. package/lib/src/react/all-types-export.js.map +1 -1
  98. package/lib/src/react/index.d.ts +8 -8
  99. package/lib/src/react/index.d.ts.map +1 -1
  100. package/lib/src/react/index.js +1 -1
  101. package/lib/src/react/index.js.map +1 -1
  102. package/lib/src/react/index.spec.js +7 -7
  103. package/lib/src/react/index.spec.js.map +1 -1
  104. package/lib/src/types.d.ts +124 -36
  105. package/lib/src/types.d.ts.map +1 -1
  106. package/lib/src/types.js +79 -11
  107. package/lib/src/types.js.map +1 -1
  108. package/lib/src/utils.d.ts +5 -0
  109. package/lib/src/utils.d.ts.map +1 -1
  110. package/lib/src/utils.js +17 -0
  111. package/lib/src/utils.js.map +1 -1
  112. package/lib/src/utils.spec.js +34 -1
  113. package/lib/src/utils.spec.js.map +1 -1
  114. package/lib/src/visual-embed-sdk.d.ts +215 -46
  115. package/package.json +1 -1
  116. package/src/api-intercept.ts +2 -1
  117. package/src/css-variables.ts +1 -1
  118. package/src/embed/conversation.ts +5 -5
  119. package/src/embed/liveboard.spec.ts +4 -4
  120. package/src/embed/liveboard.ts +3 -1
  121. package/src/embed/search.spec.ts +31 -0
  122. package/src/embed/ts-embed.spec.ts +70 -16
  123. package/src/embed/ts-embed.ts +32 -20
  124. package/src/index.ts +2 -0
  125. package/src/react/all-types-export.ts +1 -0
  126. package/src/react/index.spec.tsx +7 -7
  127. package/src/react/index.tsx +9 -9
  128. package/src/types.ts +125 -36
  129. package/src/utils.spec.ts +44 -0
  130. package/src/utils.ts +16 -0
package/src/types.ts CHANGED
@@ -899,9 +899,11 @@ export interface FrameParams {
899
899
 
900
900
  /**
901
901
  * Configuration for the pre-render wrapper element.
902
- * All properties here mirror the top-level preRender properties on
903
- * {@link BaseViewConfig} and take precedence over them when both are set,
904
- * so existing top-level usage continues to work without any changes.
902
+ * Each property here supersedes its deprecated top-level counterpart on
903
+ * {@link BaseViewConfig} `id` over `preRenderId`, `containerSelector` over
904
+ * `preRenderContainer` and `doNotTrackSize` over `doNotTrackPreRenderSize`
905
+ * and takes precedence when both are set, so existing top-level usage continues
906
+ * to work without any changes.
905
907
  *
906
908
  * @version SDK: 1.52.0
907
909
  * @example
@@ -909,9 +911,9 @@ export interface FrameParams {
909
911
  * init({ thoughtSpotHost: '...', authType: AuthType.None });
910
912
  * const embed = new LiveboardEmbed('#tsEmbed', {
911
913
  * preRenderConfig: {
912
- * preRenderId: 'my-liveboard',
913
- * preRenderContainer: '#my-scroll-container',
914
- * doNotTrackPreRenderSize: false,
914
+ * id: 'my-liveboard',
915
+ * containerSelector: '#my-scroll-container',
916
+ * doNotTrackSize: false,
915
917
  * zIndex: -10,
916
918
  * },
917
919
  * });
@@ -932,7 +934,7 @@ export interface PreRenderConfig {
932
934
  *
933
935
  * @default undefined
934
936
  */
935
- preRenderId?: string;
937
+ id?: string;
936
938
  /**
937
939
  * The DOM element or CSS selector string specifying the container into
938
940
  * which the pre-rendered wrapper is inserted.
@@ -948,7 +950,7 @@ export interface PreRenderConfig {
948
950
  *
949
951
  * @default document.body
950
952
  */
951
- preRenderContainer?: string | HTMLElement;
953
+ containerSelector?: string | HTMLElement;
952
954
  /**
953
955
  * Disables the `ResizeObserver` that keeps the wrapper sized to the
954
956
  * placeholder element.
@@ -960,7 +962,7 @@ export interface PreRenderConfig {
960
962
  *
961
963
  * @default false
962
964
  */
963
- doNotTrackPreRenderSize?: boolean;
965
+ doNotTrackSize?: boolean;
964
966
  /**
965
967
  * CSS `z-index` value applied to the pre-render wrapper when hidden.
966
968
  * Override this when the host page's stacking context does not reach `-1000`
@@ -1167,7 +1169,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1167
1169
  *
1168
1170
  * Supported embed types: `AppEmbed`, `LiveboardEmbed`, `SearchEmbed`, `SpotterAgentEmbed`, `SpotterEmbed`, `SearchBarEmbed`
1169
1171
  * @version SDK: 1.25.0 | ThoughtSpot: 9.6.0.cl, 9.8.0.sw
1170
- * @deprecated Use {@link PreRenderConfig.preRenderId} via `preRenderConfig` instead.
1172
+ * @deprecated Use {@link PreRenderConfig.id} via `preRenderConfig` instead.
1171
1173
  * @example
1172
1174
  * ```js
1173
1175
  * // Replace <EmbedComponent> with embed component name. For example, AppEmbed, SearchEmbed, or LiveboardEmbed
@@ -1188,7 +1190,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1188
1190
  * @type {boolean}
1189
1191
  * @default false
1190
1192
  * @version SDK: 1.24.0 | ThoughtSpot: 9.4.0.cl, 9.4.0.sw
1191
- * @deprecated Use {@link PreRenderConfig.doNotTrackPreRenderSize} via `preRenderConfig` instead.
1193
+ * @deprecated Use {@link PreRenderConfig.doNotTrackSize} via `preRenderConfig` instead.
1192
1194
  * @example
1193
1195
  * ```js
1194
1196
  * // Disable tracking PreRender size in the configuration
@@ -1230,7 +1232,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1230
1232
  *
1231
1233
  * @type {string | HTMLElement}
1232
1234
  * @version SDK: 1.49.2 | ThoughtSpot: *
1233
- * @deprecated Use {@link PreRenderConfig.preRenderContainer} via `preRenderConfig` instead.
1235
+ * @deprecated Use {@link PreRenderConfig.containerSelector} via `preRenderConfig` instead.
1234
1236
  * @example
1235
1237
  * ```js
1236
1238
  * const embed = new LiveboardEmbed('#tsEmbed', {
@@ -1243,9 +1245,11 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1243
1245
  preRenderContainer?: string | HTMLElement;
1244
1246
  /**
1245
1247
  * Configuration for the pre-render wrapper element.
1246
- * All properties here mirror the top-level preRender properties on
1247
- * `BaseViewConfig` and take precedence over them when both are set,
1248
- * so existing top-level usage continues to work without any changes.
1248
+ * Each property here supersedes its deprecated top-level counterpart on
1249
+ * `BaseViewConfig` `id` over `preRenderId`, `containerSelector` over
1250
+ * `preRenderContainer` and `doNotTrackSize` over `doNotTrackPreRenderSize`
1251
+ * and takes precedence when both are set, so existing top-level usage
1252
+ * continues to work without any changes.
1249
1253
  * See {@link PreRenderConfig} for available options.
1250
1254
  *
1251
1255
  * @version SDK: 1.52.0
@@ -1253,7 +1257,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1253
1257
  * ```js
1254
1258
  * const embed = new LiveboardEmbed('#tsEmbed', {
1255
1259
  * preRenderConfig: {
1256
- * preRenderId: 'my-liveboard',
1260
+ * id: 'my-liveboard',
1257
1261
  * zIndex: -10,
1258
1262
  * },
1259
1263
  * });
@@ -2035,7 +2039,7 @@ export interface LiveboardAppEmbedViewConfig {
2035
2039
  *
2036
2040
  * Supported embed types: `AppEmbed`, `LiveboardEmbed`
2037
2041
  * @type {boolean}
2038
- * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
2042
+ * @version SDK: 1.51.1 | ThoughtSpot Cloud: 26.8.0.cl
2039
2043
  * @default false
2040
2044
  * @example
2041
2045
  * ```js
@@ -2160,7 +2164,7 @@ export interface LiveboardAppEmbedViewConfig {
2160
2164
  *
2161
2165
  * Supported embed types: `AppEmbed`, `LiveboardEmbed`
2162
2166
  * @type {number}
2163
- * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
2167
+ * @version SDK: 1.51.1 | ThoughtSpot Cloud: 26.8.0.cl
2164
2168
  * @example
2165
2169
  * ```js
2166
2170
  * // Replace <EmbedComponent> with embed component name. For example, AppEmbed or LiveboardEmbed
@@ -3849,7 +3853,32 @@ export enum EmbedEvent {
3849
3853
  */
3850
3854
  OrgSwitched = 'orgSwitched',
3851
3855
  /**
3852
- * Emitted when the user intercepts a URL.
3856
+ * Emitted before the embedded ThoughtSpot app sends a network request whose
3857
+ * fully resolved URL matches one of the `interceptUrls` in the view config.
3858
+ * The request is held until you call `responder`, which decides whether the
3859
+ * real request goes out or a response you supply is used in its place.
3860
+ *
3861
+ * Setting `interceptUrls` is what enables this; there is no separate enable
3862
+ * flag. If `responder` is not called within `interceptTimeout` (30000 ms by
3863
+ * default) the request fails and `EmbedEvent.Error` is emitted.
3864
+ *
3865
+ * The payload is `{ input, init, urlType }`, where `input` is the request
3866
+ * URL and `init` is the `fetch` init object, with `init.body` parsed into an
3867
+ * object when it is valid JSON. `urlType` is the matching
3868
+ * `InterceptedApiType`; it is `InterceptedApiType.ALL` for any URL outside
3869
+ * the recognized API groups.
3870
+ *
3871
+ * Interception wraps the outermost layer of `fetch`, so `init` holds the
3872
+ * request as the application composed it, before ThoughtSpot attaches its
3873
+ * authentication headers. Those headers, and any token refresh and retry,
3874
+ * are applied afterwards and only when you pass `execute: true`. Only
3875
+ * requests made through `fetch` are intercepted.
3876
+ *
3877
+ * Pass `execute: true` to let the original request proceed untouched, in
3878
+ * which case any `response` you supply alongside it is ignored. With
3879
+ * `execute: false` the request is never sent, and your `response.body` is
3880
+ * returned to the app as JSON, defaulting to status 200 and a
3881
+ * `Content-Type: application/json` header.
3853
3882
  *
3854
3883
  * Supported on all embed types.
3855
3884
  *
@@ -4672,7 +4701,7 @@ export enum HostEvent {
4672
4701
  *
4673
4702
  * Unlike {@link HostEvent.OpenFilter}, which opens the panel of an
4674
4703
  * existing filter, this event starts the creation of a new filter.
4675
- * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
4704
+ * @version SDK: 1.51.1 | ThoughtSpot Cloud: 26.8.0.cl
4676
4705
  * @example
4677
4706
  * ```js
4678
4707
  * liveboardEmbed.trigger(HostEvent.OpenAddFilterModal);
@@ -4688,7 +4717,7 @@ export enum HostEvent {
4688
4717
  * Hiding the *Add parameter* button with `hiddenActions:
4689
4718
  * [Action.AddParameter]` does not block this event, but disabling it
4690
4719
  * with `disabledActions` does.
4691
- * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
4720
+ * @version SDK: 1.51.1 | ThoughtSpot Cloud: 26.8.0.cl
4692
4721
  * @example
4693
4722
  * ```js
4694
4723
  * liveboardEmbed.trigger(HostEvent.OpenAddParameterModal);
@@ -6567,7 +6596,13 @@ export enum HostEvent {
6567
6596
  */
6568
6597
  UpdateEmbedParams = 'updateEmbedParams',
6569
6598
  /**
6570
- * Triggered when the embed needs to be destroyed. This is used to clean up any embed-related resources internally.
6599
+ * Notifies the embedded ThoughtSpot app that the embed is being torn down, so that
6600
+ * it can release any resources it holds before the iframe is removed from the DOM.
6601
+ *
6602
+ * This is triggered for you by `embed.destroy()`; you rarely need to trigger it
6603
+ * directly. If `waitForCleanupOnDestroy` is set in the embed config, `destroy()`
6604
+ * waits for the app to acknowledge this event (up to `cleanupTimeout`) before
6605
+ * removing the iframe.
6571
6606
  * @example
6572
6607
  * ```js
6573
6608
  * liveboardEmbed.trigger(HostEvent.DestroyEmbed);
@@ -8724,7 +8759,7 @@ export enum Action {
8724
8759
  * ```js
8725
8760
  * hiddenActions: [Action.QuickSearchPill]
8726
8761
  * ```
8727
- * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
8762
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
8728
8763
  */
8729
8764
  QuickSearchPill = 'quickSearchPill',
8730
8765
  /**
@@ -8739,7 +8774,7 @@ export enum Action {
8739
8774
  * ```js
8740
8775
  * hiddenActions: [Action.DeepAnalysisPill]
8741
8776
  * ```
8742
- * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
8777
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
8743
8778
  */
8744
8779
  DeepAnalysisPill = 'deepAnalysisPill',
8745
8780
  /**
@@ -8754,7 +8789,7 @@ export enum Action {
8754
8789
  * ```js
8755
8790
  * hiddenActions: [Action.DataLiteracyPill]
8756
8791
  * ```
8757
- * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
8792
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
8758
8793
  */
8759
8794
  DataLiteracyPill = 'dataLiteracyPill',
8760
8795
  /**
@@ -9375,10 +9410,42 @@ export interface EmbedErrorDetailsEvent {
9375
9410
  message: string | string[];
9376
9411
  /** Machine-readable error code for programmatic error handling */
9377
9412
  code: EmbedErrorCodes;
9413
+ /** How badly the embed is affected. Defaults to {@link EmbedErrorSeverity.SEV3}. */
9414
+ severity?: EmbedErrorSeverity;
9378
9415
  /** Additional context-specific for backward compatibility */
9379
9416
  [key: string]: any;
9380
9417
  }
9381
9418
 
9419
+ /**
9420
+ * How badly an error affects the embed, so the host can decide whether it is
9421
+ * worth surfacing to the end user.
9422
+ *
9423
+ * Mirrors the severity that ThoughtSpot itself stamps on errors raised inside
9424
+ * the embedded app, so a host can apply one rule to both sources.
9425
+ *
9426
+ * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
9427
+ * @group Error Handling
9428
+ *
9429
+ * @example
9430
+ * Only surface errors that took the embed down
9431
+ *
9432
+ * ```js
9433
+ * embed.on(EmbedEvent.Error, (error) => {
9434
+ * if (error.severity === EmbedErrorSeverity.SEV1) {
9435
+ * showBanner(error.message);
9436
+ * }
9437
+ * });
9438
+ * ```
9439
+ */
9440
+ export enum EmbedErrorSeverity {
9441
+ /** The embed cannot render. Nothing usable is on screen. */
9442
+ SEV1 = 1,
9443
+ /** Something is degraded but the embed still works. */
9444
+ SEV2 = 2,
9445
+ /** Everything else, including validation of the embedder's own input. */
9446
+ SEV3 = 3,
9447
+ }
9448
+
9382
9449
  /**
9383
9450
  * Context types for specifying the page context when triggering host events.
9384
9451
  * Used as the third parameter in the `trigger` method to help ThoughtSpot
@@ -9439,26 +9506,41 @@ export interface DefaultAppInitData {
9439
9506
  }
9440
9507
 
9441
9508
  /**
9442
- * Enum for the type of API intercepted
9509
+ * Named groups of ThoughtSpot APIs that can be intercepted, for use in
9510
+ * `interceptUrls`. Each group expands to the underlying request URLs, so you do
9511
+ * not have to list them individually.
9443
9512
  */
9444
9513
  export enum InterceptedApiType {
9445
9514
  /**
9446
- * The apis that are use to get the data for the embed
9515
+ * The APIs that fetch the data backing an Answer, including its chart,
9516
+ * table, and headline data.
9447
9517
  */
9448
9518
  AnswerData = 'AnswerData',
9449
9519
  /**
9450
- * This will intercept all the apis
9520
+ * Intercepts every `fetch` request the embedded application makes, not only
9521
+ * the data APIs. This includes authentication, session, and metadata calls,
9522
+ * so the handler must respond to requests it does not recognize by passing
9523
+ * `execute: true`. Listing this alongside other entries in `interceptUrls`
9524
+ * supersedes them.
9451
9525
  */
9452
9526
  ALL = 'ALL',
9453
9527
  /**
9454
- * The apis that are use to get the data for the liveboard
9528
+ * The APIs that fetch the data backing a Liveboard.
9455
9529
  */
9456
9530
  LiveboardData = 'LiveboardData',
9457
9531
  }
9458
9532
 
9459
9533
  export type ApiInterceptFlags = {
9460
9534
  /**
9461
- * Flag that allows using `EmbedEvent.OnBeforeGetVizDataIntercept`.
9535
+ * Emits `EmbedEvent.OnBeforeGetVizDataIntercept` before the Answer data
9536
+ * APIs are called. This is the earlier, narrower form of interception, kept
9537
+ * for backward compatibility and implemented on top of
9538
+ * `EmbedEvent.ApiIntercept`. Prefer `interceptUrls` with
9539
+ * `InterceptedApiType.AnswerData` in new code.
9540
+ *
9541
+ * Setting this also intercepts the Answer data APIs, so both
9542
+ * `EmbedEvent.OnBeforeGetVizDataIntercept` and `EmbedEvent.ApiIntercept`
9543
+ * are emitted for those requests.
9462
9544
  *
9463
9545
  * Can be used for Search and App Embed from SDK 1.29.0
9464
9546
  *
@@ -9466,14 +9548,21 @@ export type ApiInterceptFlags = {
9466
9548
  */
9467
9549
  isOnBeforeGetVizDataInterceptEnabled?: boolean;
9468
9550
  /**
9469
- * This allows to intercept the urls passed, once intercepted the api will only
9470
- * run based on the response from the responder of ApiIntercept event.
9551
+ * The requests to intercept, given as `InterceptedApiType` groups, absolute
9552
+ * URLs, or paths beginning with `/` that are resolved against the
9553
+ * ThoughtSpot host. Setting this is what turns interception on.
9554
+ *
9555
+ * A URL matches only on exact equality with the request's fully resolved
9556
+ * URL, query string included, so prefer an `InterceptedApiType` group where
9557
+ * one covers the API you need.
9558
+ *
9559
+ * Each intercepted request pauses and emits `EmbedEvent.ApiIntercept`, then
9560
+ * proceeds according to the response passed to that event's responder.
9471
9561
  *
9472
9562
  * @example
9473
9563
  * ```js
9474
9564
  * const embed = new LiveboardEmbed('#embed', {
9475
9565
  * ...viewConfig,
9476
- * enableApiIntercept: true,
9477
9566
  * interceptUrls: [InterceptedApiType.LiveboardData],
9478
9567
  * })
9479
9568
  * ```
@@ -9482,14 +9571,14 @@ export type ApiInterceptFlags = {
9482
9571
  */
9483
9572
  interceptUrls?: (string | InterceptedApiType)[];
9484
9573
  /**
9485
- * The timeout for the intercept, default is 30000ms
9486
- * the api will error out if the timeout is reached
9574
+ * How long, in milliseconds, an intercepted request waits for the
9575
+ * `EmbedEvent.ApiIntercept` responder before it is abandoned. Defaults to
9576
+ * 30000. On timeout the request fails and `EmbedEvent.Error` is emitted.
9487
9577
  *
9488
9578
  * @example
9489
9579
  * ```js
9490
9580
  * const embed = new LiveboardEmbed('#embed', {
9491
9581
  * ...viewConfig,
9492
- * enableApiIntercept: true,
9493
9582
  * interceptUrls: [InterceptedApiType.ALL],
9494
9583
  * interceptTimeout: 1000,
9495
9584
  * })
package/src/utils.spec.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  getQueryParamString,
3
+ deserializeParam,
3
4
  getFilterQuery,
4
5
  getCssDimension,
5
6
  getEncodedQueryParamsString,
@@ -349,7 +350,50 @@ describe('unit test for utils', () => {
349
350
  });
350
351
  });
351
352
 
353
+ describe('deserializeParam', () => {
354
+ // Inverse of URL param serialization — must mirror the app's URL parser.
355
+ test('parses a JSON-string array back to a real array (SCAL-334713)', () => {
356
+ expect(deserializeParam('["4dd30af7-9ed7-4847-8f28-b65b44a841d8"]')).toEqual([
357
+ '4dd30af7-9ed7-4847-8f28-b65b44a841d8',
358
+ ]);
359
+ });
360
+
361
+ test('does not URI-decode strings — raw %xx content must survive', () => {
362
+ expect(deserializeParam('%5Bcommit%20date%5D%5Brevenue%5D')).toBe(
363
+ '%5Bcommit%20date%5D%5Brevenue%5D',
364
+ );
365
+ });
366
+
367
+ test('parses JSON objects and booleans', () => {
368
+ expect(deserializeParam('{"a":1}')).toEqual({ a: 1 });
369
+ expect(deserializeParam('true')).toBe(true);
370
+ });
371
+
372
+ test('keeps numeric strings as strings, matching the app URL parser', () => {
373
+ expect(deserializeParam('123')).toBe('123');
374
+ expect(deserializeParam('1.5')).toBe('1.5');
375
+ });
376
+
377
+ test('keeps plain non-JSON strings unchanged', () => {
378
+ expect(deserializeParam('local-host')).toBe('local-host');
379
+ expect(deserializeParam('AuthServerCookieless')).toBe('AuthServerCookieless');
380
+ });
381
+
382
+ test('keeps a malformed percent-sequence string as-is', () => {
383
+ expect(deserializeParam('100% legit')).toBe('100% legit');
384
+ });
385
+
386
+ test('passes non-string values through untouched', () => {
387
+ const arr = ['a'];
388
+ expect(deserializeParam(arr)).toBe(arr);
389
+ expect(deserializeParam(true)).toBe(true);
390
+ expect(deserializeParam(42)).toBe(42);
391
+ expect(deserializeParam(undefined)).toBeUndefined();
392
+ });
393
+ });
394
+
352
395
  describe('Fullscreen Utility Functions', () => {
396
+
353
397
  let originalExitFullscreen: any;
354
398
  let mockIframe: HTMLIFrameElement;
355
399
 
package/src/utils.ts CHANGED
@@ -85,6 +85,22 @@ const serializeParam = (value: any) => {
85
85
  return JSON.stringify(value);
86
86
  };
87
87
 
88
+ /**
89
+ * Inverse of serializeParam: JSON.parse with fallback to the raw string,
90
+ * matching how the app parses the same values from the iframe URL.
91
+ */
92
+ export const deserializeParam = (value: unknown): unknown => {
93
+ if (typeof value !== 'string') return value;
94
+ try {
95
+ const parsed = JSON.parse(value);
96
+ // Numeric strings stay strings ('123' !== 123), same as the app's
97
+ // URL parser — param consumers expect string ids/versions.
98
+ return typeof parsed === 'number' ? value : parsed;
99
+ } catch (e) {
100
+ return value;
101
+ }
102
+ };
103
+
88
104
  /**
89
105
  * Convert a value to a string:
90
106
  * in case of an array, we convert it to CSV.