@thoughtspot/visual-embed-sdk 1.51.0 → 1.51.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/config.d.ts +1 -0
  3. package/cjs/src/config.d.ts.map +1 -1
  4. package/cjs/src/config.js +2 -1
  5. package/cjs/src/config.js.map +1 -1
  6. package/cjs/src/css-variables.d.ts +27 -0
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts +43 -12
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +29 -3
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +253 -1
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/base.d.ts +1 -1
  15. package/cjs/src/embed/base.js +1 -1
  16. package/cjs/src/embed/conversation.d.ts +171 -1
  17. package/cjs/src/embed/conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/conversation.js +4 -2
  19. package/cjs/src/embed/conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.spec.js +125 -0
  21. package/cjs/src/embed/conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/events.spec.js +3 -0
  23. package/cjs/src/embed/events.spec.js.map +1 -1
  24. package/cjs/src/embed/host-events.spec.js +36 -0
  25. package/cjs/src/embed/host-events.spec.js.map +1 -1
  26. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  27. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  28. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +18 -0
  29. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  30. package/cjs/src/embed/liveboard.d.ts +40 -13
  31. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  32. package/cjs/src/embed/liveboard.js +25 -4
  33. package/cjs/src/embed/liveboard.js.map +1 -1
  34. package/cjs/src/embed/liveboard.spec.js +349 -2
  35. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  36. package/cjs/src/embed/search.spec.js +28 -0
  37. package/cjs/src/embed/search.spec.js.map +1 -1
  38. package/cjs/src/embed/spotter-utils.d.ts +8 -1
  39. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  40. package/cjs/src/embed/spotter-utils.js +15 -1
  41. package/cjs/src/embed/spotter-utils.js.map +1 -1
  42. package/cjs/src/embed/spotter-utils.spec.js +68 -0
  43. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  44. package/cjs/src/embed/spotter-viz-utils.d.ts +9 -10
  45. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  46. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  47. package/cjs/src/embed/ts-embed.d.ts +97 -9
  48. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  49. package/cjs/src/embed/ts-embed.js +76 -35
  50. package/cjs/src/embed/ts-embed.js.map +1 -1
  51. package/cjs/src/embed/ts-embed.spec.js +537 -3
  52. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  53. package/cjs/src/index.d.ts +3 -3
  54. package/cjs/src/index.d.ts.map +1 -1
  55. package/cjs/src/index.js +3 -2
  56. package/cjs/src/index.js.map +1 -1
  57. package/cjs/src/react/all-types-export.d.ts +1 -1
  58. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  59. package/cjs/src/react/all-types-export.js +2 -1
  60. package/cjs/src/react/all-types-export.js.map +1 -1
  61. package/cjs/src/react/all-types-export.parity.spec.d.ts +2 -0
  62. package/cjs/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  63. package/cjs/src/react/all-types-export.parity.spec.js +194 -0
  64. package/cjs/src/react/all-types-export.parity.spec.js.map +1 -0
  65. package/cjs/src/react/index.d.ts +66 -32
  66. package/cjs/src/react/index.d.ts.map +1 -1
  67. package/cjs/src/react/index.js +5 -3
  68. package/cjs/src/react/index.js.map +1 -1
  69. package/cjs/src/react/index.spec.js +101 -0
  70. package/cjs/src/react/index.spec.js.map +1 -1
  71. package/cjs/src/types.d.ts +330 -18
  72. package/cjs/src/types.d.ts.map +1 -1
  73. package/cjs/src/types.js +182 -12
  74. package/cjs/src/types.js.map +1 -1
  75. package/cjs/src/utils.d.ts +5 -0
  76. package/cjs/src/utils.d.ts.map +1 -1
  77. package/cjs/src/utils.js +19 -1
  78. package/cjs/src/utils.js.map +1 -1
  79. package/cjs/src/utils.spec.js +37 -0
  80. package/cjs/src/utils.spec.js.map +1 -1
  81. package/dist/{index-aBzH5ZwF.js → index-D8_Zs-Nr.js} +1 -1
  82. package/dist/src/config.d.ts +1 -0
  83. package/dist/src/config.d.ts.map +1 -1
  84. package/dist/src/css-variables.d.ts +27 -0
  85. package/dist/src/css-variables.d.ts.map +1 -1
  86. package/dist/src/embed/app.d.ts +43 -12
  87. package/dist/src/embed/app.d.ts.map +1 -1
  88. package/dist/src/embed/base.d.ts +1 -1
  89. package/dist/src/embed/conversation.d.ts +171 -1
  90. package/dist/src/embed/conversation.d.ts.map +1 -1
  91. package/dist/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  92. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  93. package/dist/src/embed/liveboard.d.ts +40 -13
  94. package/dist/src/embed/liveboard.d.ts.map +1 -1
  95. package/dist/src/embed/spotter-utils.d.ts +8 -1
  96. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  97. package/dist/src/embed/spotter-viz-utils.d.ts +9 -10
  98. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  99. package/dist/src/embed/ts-embed.d.ts +97 -9
  100. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  101. package/dist/src/index.d.ts +3 -3
  102. package/dist/src/index.d.ts.map +1 -1
  103. package/dist/src/react/all-types-export.d.ts +1 -1
  104. package/dist/src/react/all-types-export.d.ts.map +1 -1
  105. package/dist/src/react/all-types-export.parity.spec.d.ts +2 -0
  106. package/dist/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  107. package/dist/src/react/index.d.ts +66 -32
  108. package/dist/src/react/index.d.ts.map +1 -1
  109. package/dist/src/types.d.ts +330 -18
  110. package/dist/src/types.d.ts.map +1 -1
  111. package/dist/src/utils.d.ts +5 -0
  112. package/dist/src/utils.d.ts.map +1 -1
  113. package/dist/tsembed-react.es.js +354 -64
  114. package/dist/tsembed-react.js +353 -63
  115. package/dist/tsembed.es.js +414 -126
  116. package/dist/tsembed.js +416 -128
  117. package/dist/visual-embed-sdk-react-full.d.ts +777 -90
  118. package/dist/visual-embed-sdk-react.d.ts +773 -89
  119. package/dist/visual-embed-sdk.d.ts +713 -60
  120. package/lib/package.json +1 -1
  121. package/lib/src/config.d.ts +1 -0
  122. package/lib/src/config.d.ts.map +1 -1
  123. package/lib/src/config.js +1 -0
  124. package/lib/src/config.js.map +1 -1
  125. package/lib/src/css-variables.d.ts +27 -0
  126. package/lib/src/css-variables.d.ts.map +1 -1
  127. package/lib/src/embed/app.d.ts +43 -12
  128. package/lib/src/embed/app.d.ts.map +1 -1
  129. package/lib/src/embed/app.js +30 -4
  130. package/lib/src/embed/app.js.map +1 -1
  131. package/lib/src/embed/app.spec.js +253 -1
  132. package/lib/src/embed/app.spec.js.map +1 -1
  133. package/lib/src/embed/base.d.ts +1 -1
  134. package/lib/src/embed/base.js +1 -1
  135. package/lib/src/embed/conversation.d.ts +171 -1
  136. package/lib/src/embed/conversation.d.ts.map +1 -1
  137. package/lib/src/embed/conversation.js +5 -3
  138. package/lib/src/embed/conversation.js.map +1 -1
  139. package/lib/src/embed/conversation.spec.js +125 -0
  140. package/lib/src/embed/conversation.spec.js.map +1 -1
  141. package/lib/src/embed/events.spec.js +3 -0
  142. package/lib/src/embed/events.spec.js.map +1 -1
  143. package/lib/src/embed/host-events.spec.js +36 -0
  144. package/lib/src/embed/host-events.spec.js.map +1 -1
  145. package/lib/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  146. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  147. package/lib/src/embed/hostEventClient/host-event-client.spec.js +18 -0
  148. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  149. package/lib/src/embed/liveboard.d.ts +40 -13
  150. package/lib/src/embed/liveboard.d.ts.map +1 -1
  151. package/lib/src/embed/liveboard.js +25 -4
  152. package/lib/src/embed/liveboard.js.map +1 -1
  153. package/lib/src/embed/liveboard.spec.js +349 -2
  154. package/lib/src/embed/liveboard.spec.js.map +1 -1
  155. package/lib/src/embed/search.spec.js +28 -0
  156. package/lib/src/embed/search.spec.js.map +1 -1
  157. package/lib/src/embed/spotter-utils.d.ts +8 -1
  158. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  159. package/lib/src/embed/spotter-utils.js +13 -0
  160. package/lib/src/embed/spotter-utils.js.map +1 -1
  161. package/lib/src/embed/spotter-utils.spec.js +69 -1
  162. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  163. package/lib/src/embed/spotter-viz-utils.d.ts +9 -10
  164. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  165. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  166. package/lib/src/embed/ts-embed.d.ts +97 -9
  167. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  168. package/lib/src/embed/ts-embed.js +77 -36
  169. package/lib/src/embed/ts-embed.js.map +1 -1
  170. package/lib/src/embed/ts-embed.spec.js +537 -3
  171. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  172. package/lib/src/index.d.ts +3 -3
  173. package/lib/src/index.d.ts.map +1 -1
  174. package/lib/src/index.js +2 -2
  175. package/lib/src/index.js.map +1 -1
  176. package/lib/src/react/all-types-export.d.ts +1 -1
  177. package/lib/src/react/all-types-export.d.ts.map +1 -1
  178. package/lib/src/react/all-types-export.js +1 -1
  179. package/lib/src/react/all-types-export.js.map +1 -1
  180. package/lib/src/react/all-types-export.parity.spec.d.ts +2 -0
  181. package/lib/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  182. package/lib/src/react/all-types-export.parity.spec.js +191 -0
  183. package/lib/src/react/all-types-export.parity.spec.js.map +1 -0
  184. package/lib/src/react/index.d.ts +66 -32
  185. package/lib/src/react/index.d.ts.map +1 -1
  186. package/lib/src/react/index.js +5 -3
  187. package/lib/src/react/index.js.map +1 -1
  188. package/lib/src/react/index.spec.js +102 -1
  189. package/lib/src/react/index.spec.js.map +1 -1
  190. package/lib/src/types.d.ts +330 -18
  191. package/lib/src/types.d.ts.map +1 -1
  192. package/lib/src/types.js +182 -12
  193. package/lib/src/types.js.map +1 -1
  194. package/lib/src/utils.d.ts +5 -0
  195. package/lib/src/utils.d.ts.map +1 -1
  196. package/lib/src/utils.js +17 -0
  197. package/lib/src/utils.js.map +1 -1
  198. package/lib/src/utils.spec.js +38 -1
  199. package/lib/src/utils.spec.js.map +1 -1
  200. package/lib/src/visual-embed-sdk.d.ts +713 -60
  201. package/package.json +1 -1
  202. package/src/config.ts +1 -0
  203. package/src/css-variables.ts +32 -0
  204. package/src/embed/app.spec.ts +335 -1
  205. package/src/embed/app.ts +71 -13
  206. package/src/embed/base.ts +1 -1
  207. package/src/embed/conversation.spec.ts +136 -0
  208. package/src/embed/conversation.ts +181 -3
  209. package/src/embed/events.spec.ts +4 -0
  210. package/src/embed/host-events.spec.ts +48 -0
  211. package/src/embed/hostEventClient/host-event-client.spec.ts +34 -0
  212. package/src/embed/hostEventClient/host-event-client.ts +2 -2
  213. package/src/embed/liveboard.spec.ts +457 -2
  214. package/src/embed/liveboard.ts +74 -15
  215. package/src/embed/search.spec.ts +31 -0
  216. package/src/embed/spotter-utils.spec.ts +72 -0
  217. package/src/embed/spotter-utils.ts +21 -1
  218. package/src/embed/spotter-viz-utils.ts +9 -10
  219. package/src/embed/ts-embed.spec.ts +699 -3
  220. package/src/embed/ts-embed.ts +91 -41
  221. package/src/index.ts +43 -2
  222. package/src/react/all-types-export.parity.spec.ts +208 -0
  223. package/src/react/all-types-export.ts +22 -0
  224. package/src/react/index.spec.tsx +158 -0
  225. package/src/react/index.tsx +70 -33
  226. package/src/types.ts +329 -16
  227. package/src/utils.spec.ts +49 -0
  228. package/src/utils.ts +16 -0
package/src/types.ts CHANGED
@@ -897,6 +897,86 @@ export interface FrameParams {
897
897
  [key: string]: string | number | boolean | undefined;
898
898
  }
899
899
 
900
+ /**
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.
905
+ *
906
+ * @version SDK: 1.52.0
907
+ * @example
908
+ * ```js
909
+ * init({ thoughtSpotHost: '...', authType: AuthType.None });
910
+ * const embed = new LiveboardEmbed('#tsEmbed', {
911
+ * preRenderConfig: {
912
+ * preRenderId: 'my-liveboard',
913
+ * preRenderContainer: '#my-scroll-container',
914
+ * doNotTrackPreRenderSize: false,
915
+ * zIndex: -10,
916
+ * },
917
+ * });
918
+ * embed.preRender();
919
+ * embed.showPreRender();
920
+ * ```
921
+ */
922
+ export interface PreRenderConfig {
923
+ /**
924
+ * Pre-render ID to identify the pre-render instance.
925
+ * Takes precedence over the top-level `preRenderId` when both are set.
926
+ *
927
+ * Matches the embed warmed by `preRender()` to the one revealed by
928
+ * `showPreRender()`. Embeds sharing an ID share one loaded frame: reuse the ID for
929
+ * the same view, and give unrelated views their own or they will collide.
930
+ * Required by `preRender()`, `showPreRender()`, and `hidePreRender()`, which log
931
+ * and do nothing without it.
932
+ *
933
+ * @default undefined
934
+ */
935
+ preRenderId?: string;
936
+ /**
937
+ * The DOM element or CSS selector string specifying the container into
938
+ * which the pre-rendered wrapper is inserted.
939
+ * Takes precedence over the top-level `preRenderContainer` when both are set.
940
+ *
941
+ * Set this when your app scrolls inside an element rather than the page (for
942
+ * example `<body>` has `overflow: hidden`). Point it at the element that actually
943
+ * scrolls, keep that element mounted while the embed is warm, and prefer a
944
+ * selector string — it is re-resolved on reposition and so survives a remount,
945
+ * while a detached element reference cannot be recovered. An invalid selector is
946
+ * logged and falls back to `document.body`.
947
+ * See {@link BaseViewConfig.preRenderContainer} for details, including Shadow DOM.
948
+ *
949
+ * @default document.body
950
+ */
951
+ preRenderContainer?: string | HTMLElement;
952
+ /**
953
+ * Disables the `ResizeObserver` that keeps the wrapper sized to the
954
+ * placeholder element.
955
+ * Takes precedence over the top-level `doNotTrackPreRenderSize` when both are set.
956
+ *
957
+ * Set this only when you size the embed yourself; you then own alignment and must
958
+ * call `syncPreRenderStyle()` after any change that moves or resizes it. Tracking
959
+ * already pauses while hidden, so this is not needed to avoid work then.
960
+ *
961
+ * @default false
962
+ */
963
+ doNotTrackPreRenderSize?: boolean;
964
+ /**
965
+ * CSS `z-index` value applied to the pre-render wrapper when hidden.
966
+ * Override this when the host page's stacking context does not reach `-1000`
967
+ * and the hidden wrapper still appears above other elements.
968
+ *
969
+ * A page that creates its own stacking context — a positioned app shell, a
970
+ * transformed wrapper, a modal layer — can clamp `-1000`, and the hidden wrapper
971
+ * then shows through or swallows clicks meant for your UI. Reach for this when you
972
+ * see a faint panel behind your content, or clicks landing on nothing in the
973
+ * region where the embed will eventually appear.
974
+ *
975
+ * @default -1000
976
+ */
977
+ zIndex?: number;
978
+ }
979
+
900
980
  /**
901
981
  * The common configuration object for an embedded view.
902
982
  */
@@ -982,7 +1062,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
982
1062
  * // Replace <EmbedComponent> with embed component name. For example, AppEmbed, SearchEmbed, or LiveboardEmbed
983
1063
  * const embed = new <EmbedComponent>('#tsEmbed', {
984
1064
  * ... // other embed view config
985
- * hiddenActions: [Action.Download, Action.Export],
1065
+ * hiddenActions: [Action.Download, Action.ExportTML],
986
1066
  * });
987
1067
  * ```
988
1068
  * @important
@@ -1004,7 +1084,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1004
1084
  * // Replace <EmbedComponent> with embed component name. For example, AppEmbed, SearchEmbed, or LiveboardEmbed
1005
1085
  * const embed = new <EmbedComponent>('#tsEmbed', {
1006
1086
  * ... // other embed view config
1007
- * visibleActions: [Action.Download, Action.Export],
1087
+ * visibleActions: [Action.Download, Action.ExportTML],
1008
1088
  * });
1009
1089
  * ```
1010
1090
  */
@@ -1087,6 +1167,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1087
1167
  *
1088
1168
  * Supported embed types: `AppEmbed`, `LiveboardEmbed`, `SearchEmbed`, `SpotterAgentEmbed`, `SpotterEmbed`, `SearchBarEmbed`
1089
1169
  * @version SDK: 1.25.0 | ThoughtSpot: 9.6.0.cl, 9.8.0.sw
1170
+ * @deprecated Use {@link PreRenderConfig.preRenderId} via `preRenderConfig` instead.
1090
1171
  * @example
1091
1172
  * ```js
1092
1173
  * // Replace <EmbedComponent> with embed component name. For example, AppEmbed, SearchEmbed, or LiveboardEmbed
@@ -1107,6 +1188,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1107
1188
  * @type {boolean}
1108
1189
  * @default false
1109
1190
  * @version SDK: 1.24.0 | ThoughtSpot: 9.4.0.cl, 9.4.0.sw
1191
+ * @deprecated Use {@link PreRenderConfig.doNotTrackPreRenderSize} via `preRenderConfig` instead.
1110
1192
  * @example
1111
1193
  * ```js
1112
1194
  * // Disable tracking PreRender size in the configuration
@@ -1148,6 +1230,7 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1148
1230
  *
1149
1231
  * @type {string | HTMLElement}
1150
1232
  * @version SDK: 1.49.2 | ThoughtSpot: *
1233
+ * @deprecated Use {@link PreRenderConfig.preRenderContainer} via `preRenderConfig` instead.
1151
1234
  * @example
1152
1235
  * ```js
1153
1236
  * const embed = new LiveboardEmbed('#tsEmbed', {
@@ -1158,6 +1241,27 @@ export interface BaseViewConfig extends ApiInterceptFlags {
1158
1241
  * ```
1159
1242
  */
1160
1243
  preRenderContainer?: string | HTMLElement;
1244
+ /**
1245
+ * 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.
1249
+ * See {@link PreRenderConfig} for available options.
1250
+ *
1251
+ * @version SDK: 1.52.0
1252
+ * @example
1253
+ * ```js
1254
+ * const embed = new LiveboardEmbed('#tsEmbed', {
1255
+ * preRenderConfig: {
1256
+ * preRenderId: 'my-liveboard',
1257
+ * zIndex: -10,
1258
+ * },
1259
+ * });
1260
+ * embed.preRender();
1261
+ * embed.showPreRender();
1262
+ * ```
1263
+ */
1264
+ preRenderConfig?: PreRenderConfig;
1161
1265
  /**
1162
1266
  * Enable the V2 shell. This can provide performance benefits
1163
1267
  * due to a lighter-weight shell.
@@ -1609,7 +1713,7 @@ export interface HomePageConfig {
1609
1713
  *
1610
1714
  * const embed = new AppEmbed('#tsEmbed', {
1611
1715
  * ... //other embed view config
1612
- * hiddenListColumns : [ListPageColumns.Favorite,ListPageColumns.Author],
1716
+ * hiddenListColumns : [ListPageColumns.Favorites,ListPageColumns.Author],
1613
1717
  * })
1614
1718
  * ```
1615
1719
  */
@@ -1924,6 +2028,25 @@ export interface LiveboardAppEmbedViewConfig {
1924
2028
  * ```
1925
2029
  */
1926
2030
  enable2ColumnLayout?: boolean;
2031
+ /**
2032
+ * This attribute keeps an embedded Liveboard on the 12-column layout at
2033
+ * every width, instead of switching to the two-column or single-column
2034
+ * layout as the container narrows.
2035
+ *
2036
+ * Supported embed types: `AppEmbed`, `LiveboardEmbed`
2037
+ * @type {boolean}
2038
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
2039
+ * @default false
2040
+ * @example
2041
+ * ```js
2042
+ * // Replace <EmbedComponent> with embed component name. For example, AppEmbed or LiveboardEmbed
2043
+ * const embed = new <EmbedComponent>('#tsEmbed', {
2044
+ * ... // other embed view config
2045
+ * isLiveboardAlwaysOn12ColLayout: true,
2046
+ * })
2047
+ * ```
2048
+ */
2049
+ isLiveboardAlwaysOn12ColLayout?: boolean;
1927
2050
  /**
1928
2051
  * This flag can be used to enable the compact header in Liveboard
1929
2052
  *
@@ -2028,6 +2151,26 @@ export interface LiveboardAppEmbedViewConfig {
2028
2151
  * ```
2029
2152
  */
2030
2153
  coverAndFilterOptionInPDF?: boolean;
2154
+ /**
2155
+ * Sets the gutter space (in pixels) between the visualization tiles of
2156
+ * an embedded Liveboard grid layout and its outer layout padding.
2157
+ * Accepts a non-negative integer; `0` renders the tiles without any gap
2158
+ * and removes the outer padding. When omitted, the gutter saved in the
2159
+ * Liveboard's styling settings (or the ThoughtSpot default) applies.
2160
+ *
2161
+ * Supported embed types: `AppEmbed`, `LiveboardEmbed`
2162
+ * @type {number}
2163
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
2164
+ * @example
2165
+ * ```js
2166
+ * // Replace <EmbedComponent> with embed component name. For example, AppEmbed or LiveboardEmbed
2167
+ * const embed = new <EmbedComponent>('#tsEmbed', {
2168
+ * ... // other embed view config
2169
+ * liveboardGutter: 8,
2170
+ * })
2171
+ * ```
2172
+ */
2173
+ liveboardGutter?: number;
2031
2174
  /**
2032
2175
  * This flag is used to enable or disable the new centralized Liveboard filter UX
2033
2176
  * (v2). When enabled, a unified modal is used to manage and update multiple filters
@@ -2497,7 +2640,7 @@ export enum EmbedEvent {
2497
2640
  * @returns nonFilteredColumns - The columns that were not filtered
2498
2641
  * @example
2499
2642
  * ```js
2500
- * searchEmbed.on(EmbedEvent.DrillDown, {
2643
+ * searchEmbed.on(EmbedEvent.Drilldown, {
2501
2644
  * points: {
2502
2645
  * clickedPoint,
2503
2646
  * selectedPoints: selectedPoint
@@ -2558,7 +2701,7 @@ export enum EmbedEvent {
2558
2701
  * @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
2559
2702
  * @example
2560
2703
  * ```js
2561
- * appEmbed.on(EmbedEvent.customAction, payload => {
2704
+ * appEmbed.on(EmbedEvent.CustomAction, payload => {
2562
2705
  * const data = payload.data;
2563
2706
  * if (data.id === 'insert Custom Action ID here') {
2564
2707
  * console.log('Custom Action event:', data.embedAnswerData);
@@ -2826,8 +2969,8 @@ export enum EmbedEvent {
2826
2969
  *
2827
2970
  * **Note**: This event is deprecated in v1.21.0.
2828
2971
  * To fire an event when a download action is initiated on a chart or table,
2829
- * use `EmbedEvent.DownloadAsPng`, `EmbedEvent.DownloadAsPDF`,
2830
- * `EmbedEvent.DownloadAsCSV`, or `EmbedEvent.DownloadAsXLSX`
2972
+ * use `EmbedEvent.DownloadAsPng`, `EmbedEvent.DownloadAsPdf`,
2973
+ * `EmbedEvent.DownloadAsCsv`, or `EmbedEvent.DownloadAsXlsx`
2831
2974
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
2832
2975
  * @example
2833
2976
  * ```js
@@ -2877,10 +3020,10 @@ export enum EmbedEvent {
2877
3020
  * @example
2878
3021
  * ```js
2879
3022
  * //emit when action starts
2880
- * searchEmbed.on(EmbedEvent.DownloadAsCSV, payload => {
3023
+ * searchEmbed.on(EmbedEvent.DownloadAsCsv, payload => {
2881
3024
  * console.log('download CSV', payload)}, {start: true })
2882
3025
  * //emit when action ends
2883
- * searchEmbed.on(EmbedEvent.DownloadAsCSV, payload => {
3026
+ * searchEmbed.on(EmbedEvent.DownloadAsCsv, payload => {
2884
3027
  * console.log('download CSV', payload)})
2885
3028
  * ```
2886
3029
  */
@@ -4350,6 +4493,7 @@ export enum HostEvent {
4350
4493
  * const url = await appEmbed.trigger(HostEvent.GetIframeUrl, {}, ContextType.Answer);
4351
4494
  * console.log("iFrameURL", url);
4352
4495
  * ```
4496
+ * @returns iframeUrl - The URL currently loaded in the embedded iframe.
4353
4497
  * @version SDK: 1.35.0 | ThoughtSpot: 10.4.0.cl
4354
4498
  */
4355
4499
  GetIframeUrl = 'GetIframeUrl',
@@ -4516,6 +4660,41 @@ export enum HostEvent {
4516
4660
  * @version SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl
4517
4661
  */
4518
4662
  OpenFilter = 'openFilter',
4663
+ /**
4664
+ * Open the add-filter modal of a Liveboard, the same dialog that the
4665
+ * *Add filter* button in the Liveboard edit header opens, so the host
4666
+ * app can start the add-filter flow from its own UI.
4667
+ *
4668
+ * The Liveboard must be in edit mode; the event is ignored otherwise.
4669
+ * Hiding the *Add filter* button with `hiddenActions:
4670
+ * [Action.AddFilter]` does not block this event, but disabling it with
4671
+ * `disabledActions` does.
4672
+ *
4673
+ * Unlike {@link HostEvent.OpenFilter}, which opens the panel of an
4674
+ * existing filter, this event starts the creation of a new filter.
4675
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
4676
+ * @example
4677
+ * ```js
4678
+ * liveboardEmbed.trigger(HostEvent.OpenAddFilterModal);
4679
+ * ```
4680
+ */
4681
+ OpenAddFilterModal = 'openAddFilterModal',
4682
+ /**
4683
+ * Open the add-parameter panel of a Liveboard, the same panel that the
4684
+ * *Add parameter* button in the Liveboard edit header opens.
4685
+ * Mirrors {@link HostEvent.OpenAddFilterModal} for parameters.
4686
+ *
4687
+ * The Liveboard must be in edit mode; the event is ignored otherwise.
4688
+ * Hiding the *Add parameter* button with `hiddenActions:
4689
+ * [Action.AddParameter]` does not block this event, but disabling it
4690
+ * with `disabledActions` does.
4691
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
4692
+ * @example
4693
+ * ```js
4694
+ * liveboardEmbed.trigger(HostEvent.OpenAddParameterModal);
4695
+ * ```
4696
+ */
4697
+ OpenAddParameterModal = 'openAddParameterModal',
4519
4698
  /**
4520
4699
  * Open the parameter panel for a particular parameter on a Liveboard.
4521
4700
  * Mirrors {@link HostEvent.OpenFilter} for parameters.
@@ -4597,6 +4776,10 @@ export enum HostEvent {
4597
4776
  * liveboardEmbed.trigger(HostEvent.getExportRequestForCurrentPinboard).then(
4598
4777
  * data=>console.log(data))
4599
4778
  * ```
4779
+ * @returns data - Object with a `v2Content` string: the export request
4780
+ * payload for the current Liveboard.
4781
+ * @returns type - The passthrough event name,
4782
+ * `getExportRequestForCurrentPinboard`.
4600
4783
  * @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl, 8.8.1.sw
4601
4784
  */
4602
4785
  getExportRequestForCurrentPinboard = 'getExportRequestForCurrentPinboard',
@@ -4699,6 +4882,9 @@ export enum HostEvent {
4699
4882
  * }, ContextType.Spotter);
4700
4883
  * ```
4701
4884
  *
4885
+ * @returns liveboardId - GUID of the Liveboard the Answer was pinned to.
4886
+ * @returns tabId - GUID of the tab within that Liveboard.
4887
+ * @returns vizId - GUID of the newly created visualization.
4702
4888
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
4703
4889
  */
4704
4890
  Pin = 'pin',
@@ -4737,13 +4923,13 @@ export enum HostEvent {
4737
4923
  * Trigger the **Manage schedule** action on an embedded Liveboard
4738
4924
  * @example
4739
4925
  * ```js
4740
- * liveboardEmbed.trigger(HostEvent.ScheduleList)
4926
+ * liveboardEmbed.trigger(HostEvent.SchedulesList)
4741
4927
  * ```
4742
4928
  * @example
4743
4929
  * ```js
4744
4930
  * // Manage schedules from liveboard context
4745
4931
  * import { ContextType } from '@thoughtspot/visual-embed-sdk';
4746
- * liveboardEmbed.trigger(HostEvent.ScheduleList, {}, ContextType.Liveboard);
4932
+ * liveboardEmbed.trigger(HostEvent.SchedulesList, {}, ContextType.Liveboard);
4747
4933
  * ```
4748
4934
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
4749
4935
  */
@@ -5188,6 +5374,7 @@ export enum HostEvent {
5188
5374
  * console.log(tml.answer);
5189
5375
  * });
5190
5376
  * ```
5377
+ * @returns The TML representation of the current Answer, as an object.
5191
5378
  * @version SDK: 1.18.0 | ThoughtSpot: 8.10.0.cl, 9.0.1.sw
5192
5379
  * @important
5193
5380
  */
@@ -5632,6 +5819,8 @@ export enum HostEvent {
5632
5819
  * const data = await liveboardEmbed.trigger(HostEvent.GetFilters, {}, ContextType.Liveboard);
5633
5820
  * console.log('filters', data);
5634
5821
  * ```
5822
+ * @returns liveboardFilters - Filters applied on the Liveboard.
5823
+ * @returns runtimeFilters - Runtime filters applied on the Liveboard.
5635
5824
  * @version SDK: 1.23.0 | ThoughtSpot: 9.4.0.cl
5636
5825
  */
5637
5826
  GetFilters = 'getFilters',
@@ -5781,6 +5970,9 @@ export enum HostEvent {
5781
5970
  * console.log('tabs', tabDetails);
5782
5971
  * });
5783
5972
  * ```
5973
+ * @returns orderedTabIds - Tab GUIDs in the order they appear.
5974
+ * @returns numberOfTabs - Total number of tabs on the Liveboard.
5975
+ * @returns Tabs - Tab details, each with at least `id` and `name`.
5784
5976
  * @version SDK: 1.26.0 | ThoughtSpot: 9.7.0.cl
5785
5977
  */
5786
5978
  GetTabs = 'getTabs',
@@ -5803,6 +5995,9 @@ export enum HostEvent {
5803
5995
  * console.log('groups', groupDetails);
5804
5996
  * });
5805
5997
  * ```
5998
+ * @returns orderedGroupIds - Group GUIDs in the order they appear.
5999
+ * @returns numberOfGroups - Total number of groups on the Liveboard.
6000
+ * @returns Groups - Group details, each with at least `id` and `name`.
5806
6001
  * @version SDK: 1.53.0 | ThoughtSpot: 26.10.0.cl
5807
6002
  */
5808
6003
  GetGroups = 'getGroups',
@@ -5877,6 +6072,9 @@ export enum HostEvent {
5877
6072
  * // Alternative direct usage (not recommended)
5878
6073
  * const {session} = await embed.trigger( HostEvent.GetAnswerSession )
5879
6074
  * ```
6075
+ * @returns session - Session identifier for the Answer, for use with the
6076
+ * `AnswerService`.
6077
+ * @returns embedAnswerData - Data backing the Answer, when available.
5880
6078
  * @version SDK: 1.26.0 | ThoughtSpot: 9.10.0.cl, 10.1.0.sw
5881
6079
  */
5882
6080
  GetAnswerSession = 'getAnswerSession',
@@ -6010,12 +6208,16 @@ export enum HostEvent {
6010
6208
  * console.log('parameters', parameters);
6011
6209
  * });
6012
6210
  * ```
6211
+ * @returns parameters - Parameters currently applied on the Liveboard.
6013
6212
  * @version SDK: 1.29.0 | ThoughtSpot: 10.1.0.cl, 10.1.0.sw
6014
6213
  */
6015
6214
  GetParameters = 'GetParameters',
6016
6215
  /**
6017
6216
  * Triggers an event to update a personalized view of a Liveboard.
6018
- * This event is deprecated. Use {@link HostEvent.UpdatePersonalizedView} instead.
6217
+ * This event is deprecated. Use {@link HostEvent.SelectPersonalizedView} instead,
6218
+ * which additionally accepts a `viewName`, resets to the original view when
6219
+ * called with an empty payload, and reports an error when a named view
6220
+ * cannot be found.
6019
6221
  * ```js
6020
6222
  * liveboardEmbed.trigger(HostEvent.UpdatePersonalisedView, {viewId: '1234'})
6021
6223
  * ```
@@ -6033,10 +6235,15 @@ export enum HostEvent {
6033
6235
  UpdatePersonalisedView = 'UpdatePersonalisedView',
6034
6236
  /**
6035
6237
  * Triggers an event to update a personalized view of a Liveboard.
6238
+ * This event is deprecated. Use {@link HostEvent.SelectPersonalizedView} instead,
6239
+ * which additionally accepts a `viewName`, resets to the original view when
6240
+ * called with an empty payload, and reports an error when a named view
6241
+ * cannot be found.
6036
6242
  * ```js
6037
6243
  * liveboardEmbed.trigger(HostEvent.UpdatePersonalisedView, {viewId: '1234'})
6038
6244
  * ```
6039
6245
  * @version SDK: 1.48.0 | ThoughtSpot: 26.5.0.cl
6246
+ * @deprecated SDK: 1.53.0 | ThoughtSpot: 26.10.0.cl
6040
6247
  */
6041
6248
  UpdatePersonalizedView = UpdatePersonalisedView,
6042
6249
  /**
@@ -6139,6 +6346,10 @@ export enum HostEvent {
6139
6346
  * description: "Generated from Spotter"
6140
6347
  * }, ContextType.Spotter);
6141
6348
  * ```
6349
+ * @returns answerId - GUID of the saved Answer.
6350
+ * @returns saveResponse - Raw response from the save operation.
6351
+ * @returns shareResponse - Raw response from the share operation, when the
6352
+ * Answer was also made discoverable.
6142
6353
  * @version SDK: 1.36.0 | ThoughtSpot: 10.6.0.cl
6143
6354
  */
6144
6355
  SaveAnswer = 'saveAnswer',
@@ -6631,6 +6842,7 @@ export enum Param {
6631
6842
  NumberFormatLocale = 'numberFormatLocale',
6632
6843
  CurrencyFormat = 'currencyFormat',
6633
6844
  Enable2ColumnLayout = 'enable2ColumnLayout',
6845
+ IsLiveboardAlwaysOn12ColLayout = 'isLiveboardAlwaysOn12ColLayout',
6634
6846
  IsFullAppEmbed = 'isFullAppEmbed',
6635
6847
  IsOnBeforeGetVizDataInterceptEnabled = 'isOnBeforeGetVizDataInterceptEnabled',
6636
6848
  FocusSearchBarOnRender = 'focusSearchBarOnRender',
@@ -6654,6 +6866,7 @@ export enum Param {
6654
6866
  PrimaryAction = 'primaryAction',
6655
6867
  isSpotterAgentEmbed = 'isSpotterAgentEmbed',
6656
6868
  IsLiveboardStylingAndGroupingEnabled = 'isLiveboardStylingAndGroupingEnabled',
6869
+ LiveboardGutter = 'liveboardGutter',
6657
6870
  IsLazyLoadingForEmbedEnabled = 'isLazyLoadingForEmbedEnabled',
6658
6871
  RootMarginForLazyLoad = 'rootMarginForLazyLoad',
6659
6872
  isPNGInScheduledEmailsEnabled = 'isPNGInScheduledEmailsEnabled',
@@ -6689,6 +6902,8 @@ export enum Param {
6689
6902
  IsStarterPromptsEnabled = 'enableStarterPrompts',
6690
6903
  UpdatedSpotterExperience = 'updatedSpotterExperience',
6691
6904
  SpotterDataSources = 'spotterDataSources',
6905
+ AnalystId = 'analystId',
6906
+ OpenSpotterOnLiveboardByDefault = 'openSpotterOnLiveboardByDefault',
6692
6907
  }
6693
6908
 
6694
6909
  /**
@@ -6703,9 +6918,10 @@ export type SpotterFileUploadFileTypes = {
6703
6918
  * ThoughtSpot application pages include actions and menu commands
6704
6919
  * for various user-initiated operations. These actions are represented
6705
6920
  * as enumeration members in the SDK. To control actions in the embedded view:
6706
- * - disabledActions — the action is grayed out and still visible, but non-interactive (user can see but not click).
6707
- * - hiddenActions — the action is completely removed from the UI (user cannot see it at all).
6708
- * - visibleActions — allowlist, only these actions are shown; all others are hidden.
6921
+ * - disabledActions — the action is grayed out and still visible, but non-interactive
6922
+ * (user can see but not click). - hiddenActions — the action is completely removed from
6923
+ * the UI (user cannot see it at all). - visibleActions — allowlist, only these actions
6924
+ * are shown; all others are hidden.
6709
6925
  *
6710
6926
  * Use disabledActions to disable (gray out) an action.
6711
6927
  * Use hiddenActions to hide (fully remove) an action.
@@ -6759,6 +6975,17 @@ export enum Action {
6759
6975
  * ```
6760
6976
  */
6761
6977
  SaveAsView = 'saveAsView',
6978
+ /**
6979
+ * The **EditInputTable** action on a Liveboard
6980
+ * page. Allows users to edit an input table used in an Answer directly from
6981
+ * a Liveboard.
6982
+ * @example
6983
+ * ```js
6984
+ * disabledActions: [Action.EditInputTable]
6985
+ * ```
6986
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
6987
+ */
6988
+ EditInputTable = 'editInputTable',
6762
6989
  /**
6763
6990
  * The **Make a copy** action on a Liveboard or Answer
6764
6991
  * page. Creates a copy of the Liveboard.
@@ -8096,6 +8323,10 @@ export enum Action {
8096
8323
  * The **Add to Coaching** feature allows adding reference questions and
8097
8324
  * business terms to improve Spotter’s responses. This feature is generally available
8098
8325
  * (GA) from version 26.2.0.cl and enabled by default on embed deployments.
8326
+ *
8327
+ * This action governs both the answer-card **Add to memory** CTA and its
8328
+ * Spotter 3 successor, the response-footer **Remember this** CTA
8329
+ * (they are mutually exclusive).
8099
8330
  * @example
8100
8331
  * ```js
8101
8332
  * hiddenAction: [Action.InConversationTraining]
@@ -8476,6 +8707,56 @@ export enum Action {
8476
8707
  * @version SDK: 1.48.0 | ThoughtSpot Cloud: 26.5.0.cl
8477
8708
  */
8478
8709
  SpotterChatModeSwitcher = 'spotterChatModeSwitcher',
8710
+ /**
8711
+ * The **Basic Search** starter prompt pill.
8712
+ *
8713
+ * Starter prompt pills are the row of category buttons shown above the
8714
+ * Spotter chat input before a conversation starts. They give a new user
8715
+ * ready-made questions to click instead of typing one from scratch, and
8716
+ * disappear once the conversation begins. There are three, one per action
8717
+ * below.
8718
+ *
8719
+ * Clicking this pill opens a card of suggested simple questions; picking one
8720
+ * submits it to Spotter right away. Visible by default, and hidden along
8721
+ * with the other pills when the surface itself is off (see
8722
+ * {@link SpotterChatViewConfig.starterPrompts}).
8723
+ * @example
8724
+ * ```js
8725
+ * hiddenActions: [Action.QuickSearchPill]
8726
+ * ```
8727
+ * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
8728
+ */
8729
+ QuickSearchPill = 'quickSearchPill',
8730
+ /**
8731
+ * The **Deep Analysis** starter prompt pill, next to
8732
+ * {@link Action.QuickSearchPill} above the Spotter chat input.
8733
+ *
8734
+ * Clicking it opens a card of suggested investigative questions ("why did
8735
+ * revenue drop?"). Picking one fills the chat input in Deep Analysis mode
8736
+ * rather than submitting immediately, so the user can edit it first.
8737
+ * Visible by default.
8738
+ * @example
8739
+ * ```js
8740
+ * hiddenActions: [Action.DeepAnalysisPill]
8741
+ * ```
8742
+ * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
8743
+ */
8744
+ DeepAnalysisPill = 'deepAnalysisPill',
8745
+ /**
8746
+ * The **Data Literacy** starter prompt pill, next to
8747
+ * {@link Action.QuickSearchPill} above the Spotter chat input.
8748
+ *
8749
+ * Unlike the other two pills it opens no card: clicking it submits a prompt
8750
+ * that describes the data the model can answer over, helping a user who does
8751
+ * not yet know what is in the data source. The prompt text always comes from
8752
+ * ThoughtSpot, so only its label is customizable. Visible by default.
8753
+ * @example
8754
+ * ```js
8755
+ * hiddenActions: [Action.DataLiteracyPill]
8756
+ * ```
8757
+ * @version SDK: 1.52.0 | ThoughtSpot Cloud: 26.9.0.cl
8758
+ */
8759
+ DataLiteracyPill = 'dataLiteracyPill',
8479
8760
  /**
8480
8761
  * The **Include current period** checkbox for date filters.
8481
8762
  * Controls the visibility and availability of the option to include
@@ -8627,6 +8908,38 @@ export enum Action {
8627
8908
  * ```
8628
8909
  */
8629
8910
  SpotterAnalystSidebar = 'spotterAnalystSidebar',
8911
+ /**
8912
+ * Controls visibility and disable state of the analyst list
8913
+ * ("Show all") in the Spotter Analyst interface.
8914
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
8915
+ * @example
8916
+ * ```js
8917
+ * hiddenActions: [Action.SpotterAnalystList]
8918
+ * disabledActions: [Action.SpotterAnalystList]
8919
+ * ```
8920
+ */
8921
+ SpotterAnalystList = 'spotterAnalystList',
8922
+ /**
8923
+ * Controls visibility and disable state of the default Spotter analyst
8924
+ * entry in the Spotter Analyst interface.
8925
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
8926
+ * @example
8927
+ * ```js
8928
+ * hiddenActions: [Action.SpotterDefaultAnalyst]
8929
+ * disabledActions: [Action.SpotterDefaultAnalyst]
8930
+ * ```
8931
+ */
8932
+ SpotterDefaultAnalyst = 'spotterDefaultAnalyst',
8933
+ /**
8934
+ * The **Spotter** button in the Liveboard header.
8935
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.10.0.cl
8936
+ * @example
8937
+ * ```js
8938
+ * hiddenActions: [Action.SpotterOnLiveboard]
8939
+ * disabledActions: [Action.SpotterOnLiveboard]
8940
+ * ```
8941
+ */
8942
+ SpotterOnLiveboard = 'spotterOnLiveboard',
8630
8943
  }
8631
8944
  export interface AnswerServiceType {
8632
8945
  getAnswer?: (offset: number, batchSize: number) => any;
@@ -9161,7 +9474,7 @@ export type ApiInterceptFlags = {
9161
9474
  * const embed = new LiveboardEmbed('#embed', {
9162
9475
  * ...viewConfig,
9163
9476
  * enableApiIntercept: true,
9164
- * interceptUrls: [InterceptedApiType.DATA],
9477
+ * interceptUrls: [InterceptedApiType.LiveboardData],
9165
9478
  * })
9166
9479
  * ```
9167
9480
  *
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,
@@ -37,6 +38,7 @@ import {
37
38
  } from './utils';
38
39
  import { RuntimeFilterOp } from './types';
39
40
  import { logger } from './utils/logger';
41
+ import { DEFAULT_LAZY_LOADING_MARGIN } from './config';
40
42
  import { ERROR_MESSAGE } from './errors';
41
43
 
42
44
  // Mock logger
@@ -348,7 +350,50 @@ describe('unit test for utils', () => {
348
350
  });
349
351
  });
350
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
+
351
395
  describe('Fullscreen Utility Functions', () => {
396
+
352
397
  let originalExitFullscreen: any;
353
398
  let mockIframe: HTMLIFrameElement;
354
399
 
@@ -1029,6 +1074,10 @@ describe('isValidCssMargin', () => {
1029
1074
  expect(isValidCssMargin('10')).toBe(false); // missing unit
1030
1075
  });
1031
1076
 
1077
+ it('should accept DEFAULT_LAZY_LOADING_MARGIN', () => {
1078
+ expect(isValidCssMargin(DEFAULT_LAZY_LOADING_MARGIN)).toBe(true);
1079
+ });
1080
+
1032
1081
  it('should return false and log error when value is not a string (non-string type)', () => {
1033
1082
  // Covers line 147-148: typeof value !== 'string' branch
1034
1083
  expect(isValidCssMargin(42 as any)).toBe(false);