@thoughtspot/visual-embed-sdk 1.52.0 → 1.52.2-beta

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 (385) hide show
  1. package/cjs/package.json +19 -4
  2. package/cjs/src/contracts/contracts.spec.d.ts +2 -0
  3. package/cjs/src/contracts/contracts.spec.d.ts.map +1 -0
  4. package/cjs/src/contracts/contracts.spec.js +345 -0
  5. package/cjs/src/contracts/contracts.spec.js.map +1 -0
  6. package/cjs/src/contracts/embed-event-payloads.d.ts +73 -0
  7. package/cjs/src/contracts/embed-event-payloads.d.ts.map +1 -0
  8. package/cjs/src/contracts/embed-event-payloads.js +3 -0
  9. package/cjs/src/contracts/embed-event-payloads.js.map +1 -0
  10. package/cjs/src/contracts/host-event-contracts.d.ts +416 -0
  11. package/cjs/src/contracts/host-event-contracts.d.ts.map +1 -0
  12. package/cjs/src/contracts/host-event-contracts.js +3 -0
  13. package/cjs/src/contracts/host-event-contracts.js.map +1 -0
  14. package/cjs/src/contracts/index.d.ts +22 -0
  15. package/cjs/src/contracts/index.d.ts.map +1 -0
  16. package/cjs/src/contracts/index.js +33 -0
  17. package/cjs/src/contracts/index.js.map +1 -0
  18. package/cjs/src/contracts/ui-passthrough-contracts.d.ts +277 -0
  19. package/cjs/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
  20. package/cjs/src/{embed/hostEventClient/contracts.js → contracts/ui-passthrough-contracts.js} +6 -2
  21. package/cjs/src/contracts/ui-passthrough-contracts.js.map +1 -0
  22. package/cjs/src/embed/app.d.ts +21 -143
  23. package/cjs/src/embed/app.d.ts.map +1 -1
  24. package/cjs/src/embed/app.js +21 -121
  25. package/cjs/src/embed/app.js.map +1 -1
  26. package/cjs/src/embed/app.spec.js +80 -26
  27. package/cjs/src/embed/app.spec.js.map +1 -1
  28. package/cjs/src/embed/auto-frame-renderer.js +1 -1
  29. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  30. package/cjs/src/embed/auto-frame-renderer.spec.js +24 -13
  31. package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
  32. package/cjs/src/embed/bodyless-conversation.js +1 -1
  33. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  34. package/cjs/src/embed/conversation.d.ts +1 -0
  35. package/cjs/src/embed/conversation.d.ts.map +1 -1
  36. package/cjs/src/embed/conversation.js +4 -4
  37. package/cjs/src/embed/conversation.js.map +1 -1
  38. package/cjs/src/embed/conversation.spec.js +35 -24
  39. package/cjs/src/embed/conversation.spec.js.map +1 -1
  40. package/cjs/src/embed/embedConfig.spec.js +2 -1
  41. package/cjs/src/embed/embedConfig.spec.js.map +1 -1
  42. package/cjs/src/embed/events.spec.js +12 -2
  43. package/cjs/src/embed/events.spec.js.map +1 -1
  44. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +5 -4
  45. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  46. package/cjs/src/embed/hostEventClient/host-event-client.js +34 -23
  47. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  48. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +50 -44
  49. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  50. package/cjs/src/embed/hostEventClient/utils.d.ts +10 -1
  51. package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
  52. package/cjs/src/embed/hostEventClient/utils.js +52 -6
  53. package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
  54. package/cjs/src/embed/hostEventClient/utils.spec.js +151 -0
  55. package/cjs/src/embed/hostEventClient/utils.spec.js.map +1 -1
  56. package/cjs/src/embed/liveboard.d.ts +13 -164
  57. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  58. package/cjs/src/embed/liveboard.js +72 -135
  59. package/cjs/src/embed/liveboard.js.map +1 -1
  60. package/cjs/src/embed/liveboard.spec.js +213 -29
  61. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  62. package/cjs/src/embed/search-bar.js +1 -1
  63. package/cjs/src/embed/search-bar.js.map +1 -1
  64. package/cjs/src/embed/search.d.ts +14 -0
  65. package/cjs/src/embed/search.d.ts.map +1 -1
  66. package/cjs/src/embed/search.js +5 -2
  67. package/cjs/src/embed/search.js.map +1 -1
  68. package/cjs/src/embed/search.spec.js +85 -0
  69. package/cjs/src/embed/search.spec.js.map +1 -1
  70. package/cjs/src/embed/spotter-utils.d.ts +8 -1
  71. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  72. package/cjs/src/embed/spotter-utils.js +14 -1
  73. package/cjs/src/embed/spotter-utils.js.map +1 -1
  74. package/cjs/src/embed/spotter-utils.spec.js +26 -0
  75. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  76. package/cjs/src/embed/ts-embed.d.ts +20 -22
  77. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  78. package/cjs/src/embed/ts-embed.js +171 -66
  79. package/cjs/src/embed/ts-embed.js.map +1 -1
  80. package/cjs/src/embed/ts-embed.spec.js +486 -38
  81. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  82. package/cjs/src/errors.js +1 -1
  83. package/cjs/src/errors.js.map +1 -1
  84. package/cjs/src/full-height.d.ts +137 -0
  85. package/cjs/src/full-height.d.ts.map +1 -0
  86. package/cjs/src/full-height.js +272 -0
  87. package/cjs/src/full-height.js.map +1 -0
  88. package/cjs/src/full-height.spec.d.ts +2 -0
  89. package/cjs/src/full-height.spec.d.ts.map +1 -0
  90. package/cjs/src/full-height.spec.js +835 -0
  91. package/cjs/src/full-height.spec.js.map +1 -0
  92. package/cjs/src/index.d.ts +5 -3
  93. package/cjs/src/index.d.ts.map +1 -1
  94. package/cjs/src/index.js +6 -4
  95. package/cjs/src/index.js.map +1 -1
  96. package/cjs/src/react/all-types-export.d.ts +1 -1
  97. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  98. package/cjs/src/react/all-types-export.js +2 -1
  99. package/cjs/src/react/all-types-export.js.map +1 -1
  100. package/cjs/src/react/all-types-export.parity.spec.js +55 -3
  101. package/cjs/src/react/all-types-export.parity.spec.js.map +1 -1
  102. package/cjs/src/types.d.ts +584 -24
  103. package/cjs/src/types.d.ts.map +1 -1
  104. package/cjs/src/types.js +370 -22
  105. package/cjs/src/types.js.map +1 -1
  106. package/cjs/src/utils/authService/tokenizedAuthService.spec.js +2 -1
  107. package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  108. package/cjs/src/utils/custom-actions.spec.js +4 -2
  109. package/cjs/src/utils/custom-actions.spec.js.map +1 -1
  110. package/cjs/src/utils/filterConverter.d.ts +106 -0
  111. package/cjs/src/utils/filterConverter.d.ts.map +1 -0
  112. package/cjs/src/utils/filterConverter.js +215 -0
  113. package/cjs/src/utils/filterConverter.js.map +1 -0
  114. package/cjs/src/utils/filterConverter.spec.d.ts +2 -0
  115. package/cjs/src/utils/filterConverter.spec.d.ts.map +1 -0
  116. package/cjs/src/utils/filterConverter.spec.js +709 -0
  117. package/cjs/src/utils/filterConverter.spec.js.map +1 -0
  118. package/cjs/src/utils/processData.spec.js +2 -1
  119. package/cjs/src/utils/processData.spec.js.map +1 -1
  120. package/cjs/src/utils/processTrigger.d.ts +3 -1
  121. package/cjs/src/utils/processTrigger.d.ts.map +1 -1
  122. package/cjs/src/utils/processTrigger.js +19 -51
  123. package/cjs/src/utils/processTrigger.js.map +1 -1
  124. package/cjs/src/utils/transport/iframe-transport.d.ts +55 -0
  125. package/cjs/src/utils/transport/iframe-transport.d.ts.map +1 -0
  126. package/cjs/src/utils/transport/iframe-transport.js +108 -0
  127. package/cjs/src/utils/transport/iframe-transport.js.map +1 -0
  128. package/cjs/src/utils/transport/iframe-transport.spec.d.ts +2 -0
  129. package/cjs/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
  130. package/cjs/src/utils/transport/iframe-transport.spec.js +140 -0
  131. package/cjs/src/utils/transport/iframe-transport.spec.js.map +1 -0
  132. package/cjs/src/utils.d.ts +18 -0
  133. package/cjs/src/utils.d.ts.map +1 -1
  134. package/cjs/src/utils.js +39 -1
  135. package/cjs/src/utils.js.map +1 -1
  136. package/cjs/src/utils.spec.js +62 -0
  137. package/cjs/src/utils.spec.js.map +1 -1
  138. package/dist/{index-BMppCU63.js → index-CcBYlGo9.js} +1 -1
  139. package/dist/src/contracts/contracts.spec.d.ts +2 -0
  140. package/dist/src/contracts/contracts.spec.d.ts.map +1 -0
  141. package/dist/src/contracts/embed-event-payloads.d.ts +73 -0
  142. package/dist/src/contracts/embed-event-payloads.d.ts.map +1 -0
  143. package/dist/src/contracts/host-event-contracts.d.ts +416 -0
  144. package/dist/src/contracts/host-event-contracts.d.ts.map +1 -0
  145. package/dist/src/contracts/index.d.ts +22 -0
  146. package/dist/src/contracts/index.d.ts.map +1 -0
  147. package/dist/src/contracts/ui-passthrough-contracts.d.ts +277 -0
  148. package/dist/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
  149. package/dist/src/embed/app.d.ts +21 -143
  150. package/dist/src/embed/app.d.ts.map +1 -1
  151. package/dist/src/embed/conversation.d.ts +1 -0
  152. package/dist/src/embed/conversation.d.ts.map +1 -1
  153. package/dist/src/embed/hostEventClient/host-event-client.d.ts +5 -4
  154. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  155. package/dist/src/embed/hostEventClient/utils.d.ts +10 -1
  156. package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
  157. package/dist/src/embed/liveboard.d.ts +13 -164
  158. package/dist/src/embed/liveboard.d.ts.map +1 -1
  159. package/dist/src/embed/search.d.ts +14 -0
  160. package/dist/src/embed/search.d.ts.map +1 -1
  161. package/dist/src/embed/spotter-utils.d.ts +8 -1
  162. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  163. package/dist/src/embed/ts-embed.d.ts +20 -22
  164. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  165. package/dist/src/full-height.d.ts +137 -0
  166. package/dist/src/full-height.d.ts.map +1 -0
  167. package/dist/src/full-height.spec.d.ts +2 -0
  168. package/dist/src/full-height.spec.d.ts.map +1 -0
  169. package/dist/src/index.d.ts +5 -3
  170. package/dist/src/index.d.ts.map +1 -1
  171. package/dist/src/react/all-types-export.d.ts +1 -1
  172. package/dist/src/react/all-types-export.d.ts.map +1 -1
  173. package/dist/src/types.d.ts +584 -24
  174. package/dist/src/types.d.ts.map +1 -1
  175. package/dist/src/utils/filterConverter.d.ts +106 -0
  176. package/dist/src/utils/filterConverter.d.ts.map +1 -0
  177. package/dist/src/utils/filterConverter.spec.d.ts +2 -0
  178. package/dist/src/utils/filterConverter.spec.d.ts.map +1 -0
  179. package/dist/src/utils/processTrigger.d.ts +3 -1
  180. package/dist/src/utils/processTrigger.d.ts.map +1 -1
  181. package/dist/src/utils/transport/iframe-transport.d.ts +55 -0
  182. package/dist/src/utils/transport/iframe-transport.d.ts.map +1 -0
  183. package/dist/src/utils/transport/iframe-transport.spec.d.ts +2 -0
  184. package/dist/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
  185. package/dist/src/utils.d.ts +18 -0
  186. package/dist/src/utils.d.ts.map +1 -1
  187. package/dist/tsembed-react.es.js +1144 -412
  188. package/dist/tsembed-react.js +1143 -411
  189. package/dist/tsembed.es.js +1357 -418
  190. package/dist/tsembed.js +1352 -412
  191. package/dist/visual-embed-sdk-react-full.d.ts +1514 -651
  192. package/dist/visual-embed-sdk-react.d.ts +1351 -632
  193. package/dist/visual-embed-sdk.d.ts +1508 -668
  194. package/lib/package.json +19 -4
  195. package/lib/src/contracts/contracts.spec.d.ts +2 -0
  196. package/lib/src/contracts/contracts.spec.d.ts.map +1 -0
  197. package/lib/src/contracts/contracts.spec.js +342 -0
  198. package/lib/src/contracts/contracts.spec.js.map +1 -0
  199. package/lib/src/contracts/embed-event-payloads.d.ts +73 -0
  200. package/lib/src/contracts/embed-event-payloads.d.ts.map +1 -0
  201. package/lib/src/contracts/embed-event-payloads.js +2 -0
  202. package/lib/src/contracts/embed-event-payloads.js.map +1 -0
  203. package/lib/src/contracts/host-event-contracts.d.ts +416 -0
  204. package/lib/src/contracts/host-event-contracts.d.ts.map +1 -0
  205. package/lib/src/contracts/host-event-contracts.js +2 -0
  206. package/lib/src/contracts/host-event-contracts.js.map +1 -0
  207. package/lib/src/contracts/index.d.ts +22 -0
  208. package/lib/src/contracts/index.d.ts.map +1 -0
  209. package/lib/src/contracts/index.js +22 -0
  210. package/lib/src/contracts/index.js.map +1 -0
  211. package/lib/src/contracts/ui-passthrough-contracts.d.ts +277 -0
  212. package/lib/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
  213. package/lib/src/{embed/hostEventClient/contracts.js → contracts/ui-passthrough-contracts.js} +6 -2
  214. package/lib/src/contracts/ui-passthrough-contracts.js.map +1 -0
  215. package/lib/src/embed/app.d.ts +21 -143
  216. package/lib/src/embed/app.d.ts.map +1 -1
  217. package/lib/src/embed/app.js +23 -123
  218. package/lib/src/embed/app.js.map +1 -1
  219. package/lib/src/embed/app.spec.js +80 -26
  220. package/lib/src/embed/app.spec.js.map +1 -1
  221. package/lib/src/embed/auto-frame-renderer.js +1 -1
  222. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  223. package/lib/src/embed/auto-frame-renderer.spec.js +24 -13
  224. package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
  225. package/lib/src/embed/bodyless-conversation.js +1 -1
  226. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  227. package/lib/src/embed/conversation.d.ts +1 -0
  228. package/lib/src/embed/conversation.d.ts.map +1 -1
  229. package/lib/src/embed/conversation.js +5 -5
  230. package/lib/src/embed/conversation.js.map +1 -1
  231. package/lib/src/embed/conversation.spec.js +35 -24
  232. package/lib/src/embed/conversation.spec.js.map +1 -1
  233. package/lib/src/embed/embedConfig.spec.js +2 -1
  234. package/lib/src/embed/embedConfig.spec.js.map +1 -1
  235. package/lib/src/embed/events.spec.js +12 -2
  236. package/lib/src/embed/events.spec.js.map +1 -1
  237. package/lib/src/embed/hostEventClient/host-event-client.d.ts +5 -4
  238. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  239. package/lib/src/embed/hostEventClient/host-event-client.js +19 -8
  240. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  241. package/lib/src/embed/hostEventClient/host-event-client.spec.js +15 -9
  242. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  243. package/lib/src/embed/hostEventClient/utils.d.ts +10 -1
  244. package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
  245. package/lib/src/embed/hostEventClient/utils.js +48 -3
  246. package/lib/src/embed/hostEventClient/utils.js.map +1 -1
  247. package/lib/src/embed/hostEventClient/utils.spec.js +152 -1
  248. package/lib/src/embed/hostEventClient/utils.spec.js.map +1 -1
  249. package/lib/src/embed/liveboard.d.ts +13 -164
  250. package/lib/src/embed/liveboard.d.ts.map +1 -1
  251. package/lib/src/embed/liveboard.js +73 -136
  252. package/lib/src/embed/liveboard.js.map +1 -1
  253. package/lib/src/embed/liveboard.spec.js +213 -29
  254. package/lib/src/embed/liveboard.spec.js.map +1 -1
  255. package/lib/src/embed/search-bar.js +1 -1
  256. package/lib/src/embed/search-bar.js.map +1 -1
  257. package/lib/src/embed/search.d.ts +14 -0
  258. package/lib/src/embed/search.d.ts.map +1 -1
  259. package/lib/src/embed/search.js +5 -2
  260. package/lib/src/embed/search.js.map +1 -1
  261. package/lib/src/embed/search.spec.js +85 -0
  262. package/lib/src/embed/search.spec.js.map +1 -1
  263. package/lib/src/embed/spotter-utils.d.ts +8 -1
  264. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  265. package/lib/src/embed/spotter-utils.js +12 -0
  266. package/lib/src/embed/spotter-utils.js.map +1 -1
  267. package/lib/src/embed/spotter-utils.spec.js +27 -1
  268. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  269. package/lib/src/embed/ts-embed.d.ts +20 -22
  270. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  271. package/lib/src/embed/ts-embed.js +171 -66
  272. package/lib/src/embed/ts-embed.js.map +1 -1
  273. package/lib/src/embed/ts-embed.spec.js +484 -36
  274. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  275. package/lib/src/errors.js +1 -1
  276. package/lib/src/errors.js.map +1 -1
  277. package/lib/src/full-height.d.ts +137 -0
  278. package/lib/src/full-height.d.ts.map +1 -0
  279. package/lib/src/full-height.js +268 -0
  280. package/lib/src/full-height.js.map +1 -0
  281. package/lib/src/full-height.spec.d.ts +2 -0
  282. package/lib/src/full-height.spec.d.ts.map +1 -0
  283. package/lib/src/full-height.spec.js +833 -0
  284. package/lib/src/full-height.spec.js.map +1 -0
  285. package/lib/src/index.d.ts +5 -3
  286. package/lib/src/index.d.ts.map +1 -1
  287. package/lib/src/index.js +3 -2
  288. package/lib/src/index.js.map +1 -1
  289. package/lib/src/react/all-types-export.d.ts +1 -1
  290. package/lib/src/react/all-types-export.d.ts.map +1 -1
  291. package/lib/src/react/all-types-export.js +1 -1
  292. package/lib/src/react/all-types-export.js.map +1 -1
  293. package/lib/src/react/all-types-export.parity.spec.js +55 -3
  294. package/lib/src/react/all-types-export.parity.spec.js.map +1 -1
  295. package/lib/src/types.d.ts +584 -24
  296. package/lib/src/types.d.ts.map +1 -1
  297. package/lib/src/types.js +370 -22
  298. package/lib/src/types.js.map +1 -1
  299. package/lib/src/utils/authService/tokenizedAuthService.spec.js +2 -1
  300. package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  301. package/lib/src/utils/custom-actions.spec.js +4 -2
  302. package/lib/src/utils/custom-actions.spec.js.map +1 -1
  303. package/lib/src/utils/filterConverter.d.ts +106 -0
  304. package/lib/src/utils/filterConverter.d.ts.map +1 -0
  305. package/lib/src/utils/filterConverter.js +210 -0
  306. package/lib/src/utils/filterConverter.js.map +1 -0
  307. package/lib/src/utils/filterConverter.spec.d.ts +2 -0
  308. package/lib/src/utils/filterConverter.spec.d.ts.map +1 -0
  309. package/lib/src/utils/filterConverter.spec.js +707 -0
  310. package/lib/src/utils/filterConverter.spec.js.map +1 -0
  311. package/lib/src/utils/processData.spec.js +2 -1
  312. package/lib/src/utils/processData.spec.js.map +1 -1
  313. package/lib/src/utils/processTrigger.d.ts +3 -1
  314. package/lib/src/utils/processTrigger.d.ts.map +1 -1
  315. package/lib/src/utils/processTrigger.js +19 -51
  316. package/lib/src/utils/processTrigger.js.map +1 -1
  317. package/lib/src/utils/transport/iframe-transport.d.ts +55 -0
  318. package/lib/src/utils/transport/iframe-transport.d.ts.map +1 -0
  319. package/lib/src/utils/transport/iframe-transport.js +101 -0
  320. package/lib/src/utils/transport/iframe-transport.js.map +1 -0
  321. package/lib/src/utils/transport/iframe-transport.spec.d.ts +2 -0
  322. package/lib/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
  323. package/lib/src/utils/transport/iframe-transport.spec.js +138 -0
  324. package/lib/src/utils/transport/iframe-transport.spec.js.map +1 -0
  325. package/lib/src/utils.d.ts +18 -0
  326. package/lib/src/utils.d.ts.map +1 -1
  327. package/lib/src/utils.js +37 -0
  328. package/lib/src/utils.js.map +1 -1
  329. package/lib/src/utils.spec.js +63 -1
  330. package/lib/src/utils.spec.js.map +1 -1
  331. package/lib/src/visual-embed-sdk.d.ts +1508 -668
  332. package/package.json +19 -4
  333. package/src/contracts/contracts.spec.ts +392 -0
  334. package/src/contracts/embed-event-payloads.ts +83 -0
  335. package/src/contracts/host-event-contracts.ts +500 -0
  336. package/src/contracts/index.ts +53 -0
  337. package/src/contracts/ui-passthrough-contracts.ts +301 -0
  338. package/src/embed/app.spec.ts +101 -34
  339. package/src/embed/app.ts +42 -268
  340. package/src/embed/auto-frame-renderer.spec.ts +24 -13
  341. package/src/embed/auto-frame-renderer.ts +1 -1
  342. package/src/embed/bodyless-conversation.ts +1 -1
  343. package/src/embed/conversation.spec.ts +38 -27
  344. package/src/embed/conversation.ts +5 -5
  345. package/src/embed/embedConfig.spec.ts +2 -1
  346. package/src/embed/events.spec.ts +14 -2
  347. package/src/embed/hostEventClient/host-event-client.spec.ts +16 -10
  348. package/src/embed/hostEventClient/host-event-client.ts +31 -10
  349. package/src/embed/hostEventClient/utils.spec.ts +176 -1
  350. package/src/embed/hostEventClient/utils.ts +53 -3
  351. package/src/embed/liveboard.spec.ts +261 -41
  352. package/src/embed/liveboard.ts +85 -300
  353. package/src/embed/search-bar.tsx +1 -1
  354. package/src/embed/search.spec.ts +103 -0
  355. package/src/embed/search.ts +21 -1
  356. package/src/embed/spotter-utils.spec.ts +29 -0
  357. package/src/embed/spotter-utils.ts +16 -0
  358. package/src/embed/ts-embed.spec.ts +650 -36
  359. package/src/embed/ts-embed.ts +205 -76
  360. package/src/errors.ts +1 -1
  361. package/src/full-height.spec.ts +1008 -0
  362. package/src/full-height.ts +361 -0
  363. package/src/index.ts +103 -5
  364. package/src/react/all-types-export.parity.spec.ts +63 -3
  365. package/src/react/all-types-export.ts +49 -0
  366. package/src/types.ts +584 -22
  367. package/src/utils/authService/tokenizedAuthService.spec.ts +2 -1
  368. package/src/utils/custom-actions.spec.ts +4 -2
  369. package/src/utils/filterConverter.spec.ts +801 -0
  370. package/src/utils/filterConverter.ts +304 -0
  371. package/src/utils/processData.spec.ts +2 -1
  372. package/src/utils/processTrigger.ts +28 -58
  373. package/src/utils/transport/iframe-transport.spec.ts +177 -0
  374. package/src/utils/transport/iframe-transport.ts +122 -0
  375. package/src/utils.spec.ts +71 -0
  376. package/src/utils.ts +38 -0
  377. package/cjs/src/embed/hostEventClient/contracts.d.ts +0 -231
  378. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +0 -1
  379. package/cjs/src/embed/hostEventClient/contracts.js.map +0 -1
  380. package/dist/src/embed/hostEventClient/contracts.d.ts +0 -231
  381. package/dist/src/embed/hostEventClient/contracts.d.ts.map +0 -1
  382. package/lib/src/embed/hostEventClient/contracts.d.ts +0 -231
  383. package/lib/src/embed/hostEventClient/contracts.d.ts.map +0 -1
  384. package/lib/src/embed/hostEventClient/contracts.js.map +0 -1
  385. package/src/embed/hostEventClient/contracts.ts +0 -262
@@ -0,0 +1,801 @@
1
+ import { RuntimeFilterOp } from '../types';
2
+ import { isValidUpdateFiltersPayload } from '../embed/hostEventClient/utils';
3
+ import { convertFilterChangedToUpdateFiltersPayload, FilterChangedPayload } from './filterConverter';
4
+
5
+ describe('convertFilterChangedToUpdateFiltersPayload', () => {
6
+ test('returns an empty filters array for an empty payload', () => {
7
+ expect(convertFilterChangedToUpdateFiltersPayload({})).toEqual({ filters: [] });
8
+ });
9
+
10
+ test('returns an empty filters array for null/undefined input', () => {
11
+ expect(convertFilterChangedToUpdateFiltersPayload(null as any)).toEqual({ filters: [] });
12
+ expect(convertFilterChangedToUpdateFiltersPayload(undefined as any)).toEqual({ filters: [] });
13
+ });
14
+
15
+ test('converts runtime filters as-is', () => {
16
+ const payload: FilterChangedPayload = {
17
+ runtimeFilters: [
18
+ { columnName: 'state', operator: RuntimeFilterOp.EQ, values: ['california'] },
19
+ ],
20
+ };
21
+
22
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
23
+ filters: [
24
+ { columnName: 'state', operator: RuntimeFilterOp.EQ, values: ['california'] },
25
+ ],
26
+ });
27
+ });
28
+
29
+ test('converts a simple attribute filter (filterContent)', () => {
30
+ const payload: FilterChangedPayload = {
31
+ liveboardFilters: [
32
+ {
33
+ columnInfo: { name: 'item type' },
34
+ filters: [
35
+ {
36
+ filterContent: [
37
+ {
38
+ filterType: 'IN',
39
+ value: [{ key: 'bags' }, { key: 'shirts' }],
40
+ },
41
+ ],
42
+ },
43
+ ],
44
+ },
45
+ ],
46
+ };
47
+
48
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
49
+ filters: [
50
+ { columnName: 'item type', operator: 'IN', values: ['bags', 'shirts'] },
51
+ ],
52
+ });
53
+ });
54
+
55
+ test('includes negate when set on a filterContent filter', () => {
56
+ const payload: FilterChangedPayload = {
57
+ liveboardFilters: [
58
+ {
59
+ columnInfo: { name: 'region' },
60
+ filters: [
61
+ {
62
+ filterContent: [
63
+ {
64
+ filterType: 'EQ',
65
+ negate: true,
66
+ value: [{ key: 'west' }],
67
+ },
68
+ ],
69
+ },
70
+ ],
71
+ },
72
+ ],
73
+ };
74
+
75
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
76
+ filters: [
77
+ { columnName: 'region', operator: 'EQ', values: ['west'], negate: true },
78
+ ],
79
+ });
80
+ });
81
+
82
+ test('skips a filter group with no columnInfo.name', () => {
83
+ const payload: FilterChangedPayload = {
84
+ liveboardFilters: [
85
+ {
86
+ filters: [
87
+ { filterContent: [{ filterType: 'EQ', value: [{ key: 'x' }] }] },
88
+ ],
89
+ },
90
+ ],
91
+ };
92
+
93
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
94
+ });
95
+
96
+ test('skips a filter with neither filterContent nor dateFilterContent', () => {
97
+ const payload: FilterChangedPayload = {
98
+ liveboardFilters: [
99
+ {
100
+ columnInfo: { name: 'region' },
101
+ filters: [{}],
102
+ },
103
+ ],
104
+ };
105
+
106
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
107
+ });
108
+
109
+ test('converts an EXACT_DATE filter using epoch', () => {
110
+ const payload: FilterChangedPayload = {
111
+ liveboardFilters: [
112
+ {
113
+ columnInfo: { name: 'date' },
114
+ filters: [
115
+ {
116
+ dateFilterContent: [
117
+ {
118
+ dateFilter: { type: 'EXACT_DATE', op: 'EQ', epoch: '1690847400' },
119
+ },
120
+ ],
121
+ },
122
+ ],
123
+ },
124
+ ],
125
+ };
126
+
127
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
128
+ filters: [
129
+ {
130
+ columnName: 'date', operator: 'EQ', values: [1690847400], type: 'EXACT_DATE',
131
+ },
132
+ ],
133
+ });
134
+ });
135
+
136
+ test('converts an EXACT_DATE_RANGE filter using dateRange epochs', () => {
137
+ const payload: FilterChangedPayload = {
138
+ liveboardFilters: [
139
+ {
140
+ columnInfo: { name: 'date' },
141
+ filters: [
142
+ {
143
+ dateFilterContent: [
144
+ {
145
+ dateFilter: {
146
+ type: 'EXACT_DATE_RANGE',
147
+ op: 'BW_INC',
148
+ dateRange: { lowEpoch: '100', highEpoch: '200' },
149
+ },
150
+ },
151
+ ],
152
+ },
153
+ ],
154
+ },
155
+ ],
156
+ };
157
+
158
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
159
+ filters: [
160
+ {
161
+ columnName: 'date', operator: 'BW_INC', values: [100, 200], type: 'EXACT_DATE_RANGE',
162
+ },
163
+ ],
164
+ });
165
+ });
166
+
167
+ test('converts a MONTH_YEAR filter', () => {
168
+ const payload: FilterChangedPayload = {
169
+ liveboardFilters: [
170
+ {
171
+ columnInfo: { name: 'date' },
172
+ filters: [
173
+ {
174
+ dateFilterContent: [
175
+ {
176
+ dateFilter: {
177
+ type: 'MONTH_YEAR', op: 'EQ', monthName: 'JULY', yearName: '2023',
178
+ },
179
+ },
180
+ ],
181
+ },
182
+ ],
183
+ },
184
+ ],
185
+ };
186
+
187
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
188
+ filters: [
189
+ {
190
+ columnName: 'date', operator: 'EQ', values: ['JULY', '2023'], type: 'MONTH_YEAR',
191
+ },
192
+ ],
193
+ });
194
+ });
195
+
196
+ test('converts a QUARTER_YEAR filter', () => {
197
+ const payload: FilterChangedPayload = {
198
+ liveboardFilters: [
199
+ {
200
+ columnInfo: { name: 'date' },
201
+ filters: [
202
+ {
203
+ dateFilterContent: [
204
+ {
205
+ dateFilter: {
206
+ type: 'QUARTER_YEAR', op: 'EQ', quarterName: 'Q1', yearName: '2023',
207
+ },
208
+ },
209
+ ],
210
+ },
211
+ ],
212
+ },
213
+ ],
214
+ };
215
+
216
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
217
+ filters: [
218
+ {
219
+ columnName: 'date', operator: 'EQ', values: ['Q1', '2023'], type: 'QUARTER_YEAR',
220
+ },
221
+ ],
222
+ });
223
+ });
224
+
225
+ test('converts a YEAR_ONLY filter', () => {
226
+ const payload: FilterChangedPayload = {
227
+ liveboardFilters: [
228
+ {
229
+ columnInfo: { name: 'date' },
230
+ filters: [
231
+ {
232
+ dateFilterContent: [
233
+ { dateFilter: { type: 'YEAR_ONLY', op: 'EQ', yearName: '2023' } },
234
+ ],
235
+ },
236
+ ],
237
+ },
238
+ ],
239
+ };
240
+
241
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
242
+ filters: [
243
+ { columnName: 'date', operator: 'EQ', values: ['2023'], type: 'YEAR_ONLY' },
244
+ ],
245
+ });
246
+ });
247
+
248
+ test('converts a LAST_N_PERIOD filter with datePeriod and includeCurrentPeriod', () => {
249
+ const payload: FilterChangedPayload = {
250
+ liveboardFilters: [
251
+ {
252
+ columnInfo: { name: 'date' },
253
+ filters: [
254
+ {
255
+ dateFilterContent: [
256
+ {
257
+ negate: true,
258
+ dateFilter: {
259
+ type: 'LAST_N_PERIOD',
260
+ op: 'EQ',
261
+ number: 3,
262
+ datePeriod: 'MONTH',
263
+ includeCurrentPeriod: true,
264
+ },
265
+ },
266
+ ],
267
+ },
268
+ ],
269
+ },
270
+ ],
271
+ };
272
+
273
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
274
+ filters: [
275
+ {
276
+ columnName: 'date',
277
+ operator: 'EQ',
278
+ values: [3],
279
+ type: 'LAST_N_PERIOD',
280
+ datePeriod: 'MONTH',
281
+ includeCurrentPeriod: true,
282
+ negate: true,
283
+ },
284
+ ],
285
+ });
286
+ });
287
+
288
+ test('converts a period-only date filter (e.g. TODAY) with empty values', () => {
289
+ const payload: FilterChangedPayload = {
290
+ liveboardFilters: [
291
+ {
292
+ columnInfo: { name: 'date' },
293
+ filters: [
294
+ {
295
+ dateFilterContent: [
296
+ { dateFilter: { type: 'TODAY', op: 'EQ' } },
297
+ ],
298
+ },
299
+ ],
300
+ },
301
+ ],
302
+ };
303
+
304
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
305
+ filters: [
306
+ { columnName: 'date', operator: 'EQ', values: [], type: 'TODAY' },
307
+ ],
308
+ });
309
+ });
310
+
311
+ test('skips a dateFilterContent entry with no type', () => {
312
+ const payload: FilterChangedPayload = {
313
+ liveboardFilters: [
314
+ {
315
+ columnInfo: { name: 'date' },
316
+ filters: [
317
+ { dateFilterContent: [{ dateFilter: {} }] },
318
+ ],
319
+ },
320
+ ],
321
+ };
322
+
323
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
324
+ });
325
+
326
+ test('defaults operator to EQ when dateFilter.op is missing', () => {
327
+ const payload: FilterChangedPayload = {
328
+ liveboardFilters: [
329
+ {
330
+ columnInfo: { name: 'date' },
331
+ filters: [
332
+ { dateFilterContent: [{ dateFilter: { type: 'TODAY' } }] },
333
+ ],
334
+ },
335
+ ],
336
+ };
337
+
338
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
339
+ filters: [
340
+ { columnName: 'date', operator: RuntimeFilterOp.EQ, values: [], type: 'TODAY' },
341
+ ],
342
+ });
343
+ });
344
+
345
+ test('converts every filterContent entry on a filter, not just the first', () => {
346
+ const payload: FilterChangedPayload = {
347
+ liveboardFilters: [
348
+ {
349
+ columnInfo: { name: 'quantity' },
350
+ filters: [
351
+ {
352
+ filterContent: [
353
+ { filterType: 'GE', value: [{ key: 5 }] },
354
+ { filterType: 'LE', value: [{ key: 10 }] },
355
+ ],
356
+ },
357
+ ],
358
+ },
359
+ ],
360
+ };
361
+
362
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
363
+ filters: [
364
+ { columnName: 'quantity', operator: 'GE', values: [5] },
365
+ { columnName: 'quantity', operator: 'LE', values: [10] },
366
+ ],
367
+ });
368
+ });
369
+
370
+ test('converts every Filter entry in a filter group, not just the first', () => {
371
+ const payload: FilterChangedPayload = {
372
+ liveboardFilters: [
373
+ {
374
+ columnInfo: { name: 'region' },
375
+ filters: [
376
+ { filterContent: [{ filterType: 'EQ', value: [{ key: 'west' }] }] },
377
+ { filterContent: [{ filterType: 'EQ', value: [{ key: 'east' }] }] },
378
+ ],
379
+ },
380
+ ],
381
+ };
382
+
383
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
384
+ filters: [
385
+ { columnName: 'region', operator: 'EQ', values: ['west'] },
386
+ { columnName: 'region', operator: 'EQ', values: ['east'] },
387
+ ],
388
+ });
389
+ });
390
+
391
+ test('keeps falsy-but-defined filter values such as 0 and false', () => {
392
+ const payload: FilterChangedPayload = {
393
+ liveboardFilters: [
394
+ {
395
+ columnInfo: { name: 'flag' },
396
+ filters: [
397
+ {
398
+ filterContent: [
399
+ { filterType: 'IN', value: [{ key: 0 }, { key: false }] },
400
+ ],
401
+ },
402
+ ],
403
+ },
404
+ ],
405
+ };
406
+
407
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
408
+ filters: [
409
+ { columnName: 'flag', operator: 'IN', values: [0, false] },
410
+ ],
411
+ });
412
+ });
413
+
414
+ test('skips an EXACT_DATE filter missing its epoch instead of emitting empty values', () => {
415
+ const payload: FilterChangedPayload = {
416
+ liveboardFilters: [
417
+ {
418
+ columnInfo: { name: 'date' },
419
+ filters: [
420
+ { dateFilterContent: [{ dateFilter: { type: 'EXACT_DATE', op: 'EQ' } }] },
421
+ ],
422
+ },
423
+ ],
424
+ };
425
+
426
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
427
+ });
428
+
429
+ test('skips a MONTH_YEAR filter missing yearName instead of emitting empty values', () => {
430
+ const payload: FilterChangedPayload = {
431
+ liveboardFilters: [
432
+ {
433
+ columnInfo: { name: 'date' },
434
+ filters: [
435
+ {
436
+ dateFilterContent: [
437
+ { dateFilter: { type: 'MONTH_YEAR', op: 'EQ', monthName: 'JULY' } },
438
+ ],
439
+ },
440
+ ],
441
+ },
442
+ ],
443
+ };
444
+
445
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
446
+ });
447
+
448
+ test('skips an unrecognized date filter type rather than guessing', () => {
449
+ const payload: FilterChangedPayload = {
450
+ liveboardFilters: [
451
+ {
452
+ columnInfo: { name: 'date' },
453
+ filters: [
454
+ { dateFilterContent: [{ dateFilter: { type: 'SOME_FUTURE_TYPE', op: 'EQ' } }] },
455
+ ],
456
+ },
457
+ ],
458
+ };
459
+
460
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
461
+ });
462
+
463
+ test('output satisfies isValidUpdateFiltersPayload', () => {
464
+ const payload: FilterChangedPayload = {
465
+ liveboardFilters: [
466
+ {
467
+ columnInfo: { name: 'item type' },
468
+ filters: [
469
+ { filterContent: [{ filterType: 'IN', value: [{ key: 'bags' }] }] },
470
+ ],
471
+ },
472
+ ],
473
+ runtimeFilters: [
474
+ { columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['west'] },
475
+ ],
476
+ };
477
+
478
+ const converted = convertFilterChangedToUpdateFiltersPayload(payload);
479
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
480
+ });
481
+
482
+ test('combines multiple liveboard filters and runtime filters', () => {
483
+ const payload: FilterChangedPayload = {
484
+ liveboardFilters: [
485
+ {
486
+ columnInfo: { name: 'item type' },
487
+ filters: [
488
+ { filterContent: [{ filterType: 'IN', value: [{ key: 'bags' }] }] },
489
+ ],
490
+ },
491
+ ],
492
+ runtimeFilters: [
493
+ { columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['west'] },
494
+ ],
495
+ };
496
+
497
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
498
+ filters: [
499
+ { columnName: 'item type', operator: 'IN', values: ['bags'] },
500
+ { columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['west'] },
501
+ ],
502
+ });
503
+ });
504
+ // The payload arrives as JSON from the embedded app, so an absent field can
505
+ // be `null` rather than omitted. `Number(null)` is 0, so a naive coercion
506
+ // would turn a missing epoch into 1970 and a missing period count into 0.
507
+ describe('null and non-numeric values in the payload', () => {
508
+ const dateFilterPayload = (dateFilter: Record<string, unknown>): FilterChangedPayload => ({
509
+ liveboardFilters: [
510
+ {
511
+ columnInfo: { name: 'date' },
512
+ filters: [{ dateFilterContent: [{ dateFilter: dateFilter as any }] }],
513
+ },
514
+ ],
515
+ });
516
+
517
+ test.each([null, '', 'not-a-date'])(
518
+ 'skips an EXACT_DATE filter whose epoch is %p instead of emitting epoch 0',
519
+ (epoch) => {
520
+ const payload = dateFilterPayload({ type: 'EXACT_DATE', op: 'EQ', epoch });
521
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
522
+ },
523
+ );
524
+
525
+ test('skips an EXACT_DATE_RANGE filter when either bound is null', () => {
526
+ const missingHigh = dateFilterPayload({
527
+ type: 'EXACT_DATE_RANGE', op: 'BW', dateRange: { lowEpoch: 1000, highEpoch: null },
528
+ });
529
+ const missingLow = dateFilterPayload({
530
+ type: 'EXACT_DATE_RANGE', op: 'BW', dateRange: { lowEpoch: null, highEpoch: 2000 },
531
+ });
532
+
533
+ expect(convertFilterChangedToUpdateFiltersPayload(missingHigh)).toEqual({ filters: [] });
534
+ expect(convertFilterChangedToUpdateFiltersPayload(missingLow)).toEqual({ filters: [] });
535
+ });
536
+
537
+ test.each(['LAST_N_PERIOD', 'NEXT_N_PERIOD'])(
538
+ 'skips a %s filter whose number is null instead of emitting a 0-length period',
539
+ (type) => {
540
+ const payload = dateFilterPayload({ type, op: 'EQ', number: null, datePeriod: 'MONTH' });
541
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
542
+ },
543
+ );
544
+
545
+ test('accepts an epoch of 0 as a real value', () => {
546
+ const payload = dateFilterPayload({ type: 'EXACT_DATE', op: 'EQ', epoch: 0 });
547
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
548
+ filters: [{
549
+ columnName: 'date', operator: 'EQ', values: [0], type: 'EXACT_DATE',
550
+ }],
551
+ });
552
+ });
553
+
554
+ test('accepts a numeric epoch sent as a string', () => {
555
+ const payload = dateFilterPayload({ type: 'EXACT_DATE', op: 'EQ', epoch: '1700000000' });
556
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
557
+ filters: [{
558
+ columnName: 'date', operator: 'EQ', values: [1700000000], type: 'EXACT_DATE',
559
+ }],
560
+ });
561
+ });
562
+
563
+ test('omits includeCurrentPeriod when it is null', () => {
564
+ const payload = dateFilterPayload({
565
+ type: 'LAST_N_PERIOD', op: 'EQ', number: 3, datePeriod: 'MONTH', includeCurrentPeriod: null,
566
+ });
567
+ const [filter] = convertFilterChangedToUpdateFiltersPayload(payload).filters;
568
+
569
+ expect(filter).not.toHaveProperty('includeCurrentPeriod');
570
+ });
571
+
572
+ test('keeps includeCurrentPeriod when it is explicitly false', () => {
573
+ const payload = dateFilterPayload({
574
+ type: 'LAST_N_PERIOD', op: 'EQ', number: 3, datePeriod: 'MONTH', includeCurrentPeriod: false,
575
+ });
576
+ const [filter] = convertFilterChangedToUpdateFiltersPayload(payload).filters;
577
+
578
+ expect(filter.includeCurrentPeriod).toBe(false);
579
+ });
580
+
581
+ test('drops null keys from an attribute filter but keeps the rest', () => {
582
+ const payload: FilterChangedPayload = {
583
+ liveboardFilters: [
584
+ {
585
+ columnInfo: { name: 'item type' },
586
+ filters: [
587
+ {
588
+ filterContent: [
589
+ {
590
+ filterType: 'IN',
591
+ value: [{ key: 'bags' }, { key: null }, { key: 'shirts' }],
592
+ },
593
+ ],
594
+ },
595
+ ],
596
+ },
597
+ ],
598
+ };
599
+
600
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
601
+ filters: [{ columnName: 'item type', operator: 'IN', values: ['bags', 'shirts'] }],
602
+ });
603
+ });
604
+
605
+ test('keeps a falsy-but-real key such as 0 or false', () => {
606
+ const payload: FilterChangedPayload = {
607
+ liveboardFilters: [
608
+ {
609
+ columnInfo: { name: 'quantity' },
610
+ filters: [
611
+ { filterContent: [{ filterType: 'IN', value: [{ key: 0 }, { key: false }] }] },
612
+ ],
613
+ },
614
+ ],
615
+ };
616
+
617
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
618
+ filters: [{ columnName: 'quantity', operator: 'IN', values: [0, false] }],
619
+ });
620
+ });
621
+ });
622
+ // A runtime filter needs no reshaping, but it still arrives as JSON. One
623
+ // malformed entry fails isValidUpdateFiltersPayload for the WHOLE filters
624
+ // array, which would take every other converted filter down with it.
625
+ describe('malformed runtime filters', () => {
626
+ const malformed: Record<string, unknown>[] = [
627
+ { columnName: null, operator: RuntimeFilterOp.EQ, values: ['west'] },
628
+ { columnName: '', operator: RuntimeFilterOp.EQ, values: ['west'] },
629
+ { operator: RuntimeFilterOp.EQ, values: ['west'] },
630
+ { columnName: 'region', operator: null, values: ['west'] },
631
+ { columnName: 'region', values: ['west'] },
632
+ { columnName: 'region', operator: RuntimeFilterOp.EQ, values: null },
633
+ { columnName: 'region', operator: RuntimeFilterOp.EQ },
634
+ ];
635
+
636
+ test.each(malformed)('skips the malformed runtime filter %p', (runtimeFilter) => {
637
+ const payload = { runtimeFilters: [runtimeFilter] } as any as FilterChangedPayload;
638
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({ filters: [] });
639
+ });
640
+
641
+ test('a bad runtime filter does not discard the good filters alongside it', () => {
642
+ const payload = {
643
+ liveboardFilters: [
644
+ {
645
+ columnInfo: { name: 'item type' },
646
+ filters: [{ filterContent: [{ filterType: 'IN', value: [{ key: 'bags' }] }] }],
647
+ },
648
+ ],
649
+ runtimeFilters: [
650
+ { columnName: null, operator: RuntimeFilterOp.EQ, values: ['west'] },
651
+ { columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['west'] },
652
+ ],
653
+ } as any as FilterChangedPayload;
654
+
655
+ const converted = convertFilterChangedToUpdateFiltersPayload(payload);
656
+
657
+ expect(converted).toEqual({
658
+ filters: [
659
+ { columnName: 'item type', operator: 'IN', values: ['bags'] },
660
+ { columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['west'] },
661
+ ],
662
+ });
663
+ // The whole point: the surviving payload is still triggerable.
664
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
665
+ });
666
+
667
+ test('keeps a runtime filter with an empty values array', () => {
668
+ const payload: FilterChangedPayload = {
669
+ runtimeFilters: [{ columnName: 'region', operator: RuntimeFilterOp.EQ, values: [] }],
670
+ };
671
+
672
+ expect(convertFilterChangedToUpdateFiltersPayload(payload)).toEqual({
673
+ filters: [{ columnName: 'region', operator: RuntimeFilterOp.EQ, values: [] }],
674
+ });
675
+ });
676
+ });
677
+
678
+ // liveboardFilters entries carry an optional `applicability`
679
+ // ({level, targetId}) from SDK 1.53.0 / 26.10.0.cl, and UpdateFilters
680
+ // accepts it per filter. Dropping it would replay a tab-scoped filter
681
+ // across the whole Liveboard.
682
+ describe('applicability (filter scope)', () => {
683
+ const TAB_ID = 'e0836cad-4fdf-42d4-bd97-567a6b2a6058';
684
+
685
+ const groupWith = (applicability?: unknown) => ({
686
+ liveboardFilters: [
687
+ {
688
+ columnInfo: { name: 'item type' },
689
+ applicability,
690
+ filters: [{ filterContent: [{ filterType: 'IN', value: [{ key: 'bags' }] }] }],
691
+ },
692
+ ],
693
+ } as any as FilterChangedPayload);
694
+
695
+ test('carries TAB scope through to the converted filter', () => {
696
+ const converted = convertFilterChangedToUpdateFiltersPayload(
697
+ groupWith({ level: 'TAB', targetId: TAB_ID }),
698
+ );
699
+
700
+ expect(converted).toEqual({
701
+ filters: [{
702
+ columnName: 'item type',
703
+ operator: 'IN',
704
+ values: ['bags'],
705
+ applicability: { level: 'TAB', targetId: TAB_ID },
706
+ }],
707
+ });
708
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
709
+ });
710
+
711
+ test('carries GROUP scope through to the converted filter', () => {
712
+ const converted = convertFilterChangedToUpdateFiltersPayload(
713
+ groupWith({ level: 'GROUP', targetId: TAB_ID }),
714
+ );
715
+
716
+ expect(converted.filters[0].applicability).toEqual({ level: 'GROUP', targetId: TAB_ID });
717
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
718
+ });
719
+
720
+ test('carries LIVEBOARD scope, which needs no targetId', () => {
721
+ const converted = convertFilterChangedToUpdateFiltersPayload(
722
+ groupWith({ level: 'LIVEBOARD' }),
723
+ );
724
+
725
+ expect(converted.filters[0].applicability).toEqual({ level: 'LIVEBOARD' });
726
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
727
+ });
728
+
729
+ test('omits applicability entirely when the payload has none', () => {
730
+ const converted = convertFilterChangedToUpdateFiltersPayload(groupWith(undefined));
731
+
732
+ expect(converted.filters[0]).not.toHaveProperty('applicability');
733
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
734
+ });
735
+
736
+ test('applies the group scope to every filter the group produces', () => {
737
+ const payload = {
738
+ liveboardFilters: [
739
+ {
740
+ columnInfo: { name: 'quantity' },
741
+ applicability: { level: 'TAB', targetId: TAB_ID },
742
+ filters: [
743
+ {
744
+ filterContent: [
745
+ { filterType: 'GE', value: [{ key: 5 }] },
746
+ { filterType: 'LE', value: [{ key: 10 }] },
747
+ ],
748
+ },
749
+ ],
750
+ },
751
+ ],
752
+ } as any as FilterChangedPayload;
753
+
754
+ const converted = convertFilterChangedToUpdateFiltersPayload(payload);
755
+
756
+ expect(converted.filters).toHaveLength(2);
757
+ converted.filters.forEach((filter) => {
758
+ expect(filter.applicability).toEqual({ level: 'TAB', targetId: TAB_ID });
759
+ });
760
+ });
761
+
762
+ test.each([
763
+ [{ level: 'TAB' }, 'TAB with no targetId'],
764
+ [{ level: 'GROUP', targetId: ' ' }, 'GROUP with a blank targetId'],
765
+ [{ level: 'SOMETHING_ELSE', targetId: TAB_ID }, 'an unknown level'],
766
+ [{ targetId: TAB_ID }, 'no level at all'],
767
+ ])('skips a filter scoped with %p (%s) rather than widening it', (applicability, _label) => {
768
+ expect(convertFilterChangedToUpdateFiltersPayload(groupWith(applicability)))
769
+ .toEqual({ filters: [] });
770
+ });
771
+
772
+ test('a malformed scope on one column does not invalidate the others', () => {
773
+ const payload = {
774
+ liveboardFilters: [
775
+ {
776
+ columnInfo: { name: 'item type' },
777
+ applicability: { level: 'TAB' },
778
+ filters: [{ filterContent: [{ filterType: 'IN', value: [{ key: 'bags' }] }] }],
779
+ },
780
+ {
781
+ columnInfo: { name: 'region' },
782
+ applicability: { level: 'TAB', targetId: TAB_ID },
783
+ filters: [{ filterContent: [{ filterType: 'IN', value: [{ key: 'west' }] }] }],
784
+ },
785
+ ],
786
+ } as any as FilterChangedPayload;
787
+
788
+ const converted = convertFilterChangedToUpdateFiltersPayload(payload);
789
+
790
+ expect(converted).toEqual({
791
+ filters: [{
792
+ columnName: 'region',
793
+ operator: 'IN',
794
+ values: ['west'],
795
+ applicability: { level: 'TAB', targetId: TAB_ID },
796
+ }],
797
+ });
798
+ expect(isValidUpdateFiltersPayload(converted as any)).toBe(true);
799
+ });
800
+ });
801
+ });