@thoughtspot/visual-embed-sdk 1.49.2 → 1.50.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 (153) hide show
  1. package/cjs/package.json +4 -10
  2. package/cjs/src/authToken.spec.js +5 -0
  3. package/cjs/src/authToken.spec.js.map +1 -1
  4. package/cjs/src/embed/app.d.ts +7 -1
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +6 -0
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +11 -2
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/conversation.d.ts +12 -0
  11. package/cjs/src/embed/conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/conversation.js.map +1 -1
  13. package/cjs/src/embed/conversation.spec.js +30 -0
  14. package/cjs/src/embed/conversation.spec.js.map +1 -1
  15. package/cjs/src/embed/embedConfig.spec.d.ts +2 -0
  16. package/cjs/src/embed/embedConfig.spec.d.ts.map +1 -0
  17. package/cjs/src/embed/embedConfig.spec.js +74 -0
  18. package/cjs/src/embed/embedConfig.spec.js.map +1 -0
  19. package/cjs/src/embed/host-events.spec.d.ts +2 -0
  20. package/cjs/src/embed/host-events.spec.d.ts.map +1 -0
  21. package/cjs/src/embed/host-events.spec.js +1219 -0
  22. package/cjs/src/embed/host-events.spec.js.map +1 -0
  23. package/cjs/src/embed/liveboard.d.ts +6 -0
  24. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  25. package/cjs/src/embed/liveboard.js.map +1 -1
  26. package/cjs/src/embed/spotter-viz-utils.d.ts +29 -0
  27. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  28. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  29. package/cjs/src/index.d.ts +2 -2
  30. package/cjs/src/index.d.ts.map +1 -1
  31. package/cjs/src/index.js.map +1 -1
  32. package/cjs/src/mixpanel-service.spec.js +14 -0
  33. package/cjs/src/mixpanel-service.spec.js.map +1 -1
  34. package/cjs/src/types.d.ts +93 -6
  35. package/cjs/src/types.d.ts.map +1 -1
  36. package/cjs/src/types.js +88 -3
  37. package/cjs/src/types.js.map +1 -1
  38. package/cjs/src/utils/custom-actions.spec.js +26 -0
  39. package/cjs/src/utils/custom-actions.spec.js.map +1 -1
  40. package/cjs/src/utils/graphql/answerService/answerService.spec.js +15 -0
  41. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  42. package/cjs/src/utils/processData.spec.js +30 -0
  43. package/cjs/src/utils/processData.spec.js.map +1 -1
  44. package/cjs/src/utils/reporting.spec.js +21 -0
  45. package/cjs/src/utils/reporting.spec.js.map +1 -1
  46. package/cjs/src/utils/sessionInfoService.spec.d.ts +2 -0
  47. package/cjs/src/utils/sessionInfoService.spec.d.ts.map +1 -0
  48. package/cjs/src/utils/sessionInfoService.spec.js +130 -0
  49. package/cjs/src/utils/sessionInfoService.spec.js.map +1 -0
  50. package/cjs/src/utils.js +2 -3
  51. package/cjs/src/utils.js.map +1 -1
  52. package/cjs/src/utils.spec.js +158 -0
  53. package/cjs/src/utils.spec.js.map +1 -1
  54. package/dist/{index-CS7yJ2Jj.js → index-B5xoN6Cp.js} +303 -187
  55. package/dist/src/embed/app.d.ts +7 -1
  56. package/dist/src/embed/app.d.ts.map +1 -1
  57. package/dist/src/embed/conversation.d.ts +12 -0
  58. package/dist/src/embed/conversation.d.ts.map +1 -1
  59. package/dist/src/embed/embedConfig.spec.d.ts +2 -0
  60. package/dist/src/embed/embedConfig.spec.d.ts.map +1 -0
  61. package/dist/src/embed/host-events.spec.d.ts +2 -0
  62. package/dist/src/embed/host-events.spec.d.ts.map +1 -0
  63. package/dist/src/embed/liveboard.d.ts +6 -0
  64. package/dist/src/embed/liveboard.d.ts.map +1 -1
  65. package/dist/src/embed/spotter-viz-utils.d.ts +29 -0
  66. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  67. package/dist/src/index.d.ts +2 -2
  68. package/dist/src/index.d.ts.map +1 -1
  69. package/dist/src/types.d.ts +93 -6
  70. package/dist/src/types.d.ts.map +1 -1
  71. package/dist/src/utils/sessionInfoService.spec.d.ts +2 -0
  72. package/dist/src/utils/sessionInfoService.spec.d.ts.map +1 -0
  73. package/dist/tsembed-react.es.js +126 -18
  74. package/dist/tsembed-react.js +427 -203
  75. package/dist/tsembed.es.js +126 -18
  76. package/dist/tsembed.js +427 -203
  77. package/dist/visual-embed-sdk-react-full.d.ts +147 -7
  78. package/dist/visual-embed-sdk-react.d.ts +147 -7
  79. package/dist/visual-embed-sdk.d.ts +147 -7
  80. package/lib/package.json +4 -10
  81. package/lib/src/authToken.spec.js +5 -0
  82. package/lib/src/authToken.spec.js.map +1 -1
  83. package/lib/src/embed/app.d.ts +7 -1
  84. package/lib/src/embed/app.d.ts.map +1 -1
  85. package/lib/src/embed/app.js +6 -0
  86. package/lib/src/embed/app.js.map +1 -1
  87. package/lib/src/embed/app.spec.js +11 -2
  88. package/lib/src/embed/app.spec.js.map +1 -1
  89. package/lib/src/embed/conversation.d.ts +12 -0
  90. package/lib/src/embed/conversation.d.ts.map +1 -1
  91. package/lib/src/embed/conversation.js.map +1 -1
  92. package/lib/src/embed/conversation.spec.js +30 -0
  93. package/lib/src/embed/conversation.spec.js.map +1 -1
  94. package/lib/src/embed/embedConfig.spec.d.ts +2 -0
  95. package/lib/src/embed/embedConfig.spec.d.ts.map +1 -0
  96. package/lib/src/embed/embedConfig.spec.js +72 -0
  97. package/lib/src/embed/embedConfig.spec.js.map +1 -0
  98. package/lib/src/embed/host-events.spec.d.ts +2 -0
  99. package/lib/src/embed/host-events.spec.d.ts.map +1 -0
  100. package/lib/src/embed/host-events.spec.js +1216 -0
  101. package/lib/src/embed/host-events.spec.js.map +1 -0
  102. package/lib/src/embed/liveboard.d.ts +6 -0
  103. package/lib/src/embed/liveboard.d.ts.map +1 -1
  104. package/lib/src/embed/liveboard.js.map +1 -1
  105. package/lib/src/embed/spotter-viz-utils.d.ts +29 -0
  106. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  107. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  108. package/lib/src/index.d.ts +2 -2
  109. package/lib/src/index.d.ts.map +1 -1
  110. package/lib/src/index.js.map +1 -1
  111. package/lib/src/mixpanel-service.spec.js +14 -0
  112. package/lib/src/mixpanel-service.spec.js.map +1 -1
  113. package/lib/src/types.d.ts +93 -6
  114. package/lib/src/types.d.ts.map +1 -1
  115. package/lib/src/types.js +88 -3
  116. package/lib/src/types.js.map +1 -1
  117. package/lib/src/utils/custom-actions.spec.js +26 -0
  118. package/lib/src/utils/custom-actions.spec.js.map +1 -1
  119. package/lib/src/utils/graphql/answerService/answerService.spec.js +15 -0
  120. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  121. package/lib/src/utils/processData.spec.js +30 -0
  122. package/lib/src/utils/processData.spec.js.map +1 -1
  123. package/lib/src/utils/reporting.spec.js +21 -0
  124. package/lib/src/utils/reporting.spec.js.map +1 -1
  125. package/lib/src/utils/sessionInfoService.spec.d.ts +2 -0
  126. package/lib/src/utils/sessionInfoService.spec.d.ts.map +1 -0
  127. package/lib/src/utils/sessionInfoService.spec.js +127 -0
  128. package/lib/src/utils/sessionInfoService.spec.js.map +1 -0
  129. package/lib/src/utils.js +1 -1
  130. package/lib/src/utils.js.map +1 -1
  131. package/lib/src/utils.spec.js +159 -1
  132. package/lib/src/utils.spec.js.map +1 -1
  133. package/lib/src/visual-embed-sdk.d.ts +147 -7
  134. package/package.json +4 -10
  135. package/src/authToken.spec.ts +6 -0
  136. package/src/embed/app.spec.ts +15 -2
  137. package/src/embed/app.ts +13 -1
  138. package/src/embed/conversation.spec.ts +32 -0
  139. package/src/embed/conversation.ts +12 -0
  140. package/src/embed/embedConfig.spec.ts +79 -0
  141. package/src/embed/host-events.spec.ts +1635 -0
  142. package/src/embed/liveboard.ts +6 -0
  143. package/src/embed/spotter-viz-utils.ts +30 -0
  144. package/src/index.ts +2 -1
  145. package/src/mixpanel-service.spec.ts +15 -0
  146. package/src/types.ts +96 -6
  147. package/src/utils/custom-actions.spec.ts +28 -0
  148. package/src/utils/graphql/answerService/answerService.spec.ts +18 -0
  149. package/src/utils/processData.spec.ts +32 -0
  150. package/src/utils/reporting.spec.ts +27 -0
  151. package/src/utils/sessionInfoService.spec.ts +151 -0
  152. package/src/utils.spec.ts +195 -0
  153. package/src/utils.ts +1 -1
package/src/utils.spec.ts CHANGED
@@ -27,6 +27,13 @@ import {
27
27
  validateHttpUrl,
28
28
  setParamIfDefined,
29
29
  querySelectorAcrossShadowRoot,
30
+ getSSOMarker,
31
+ deepMerge,
32
+ getHostEventsConfig,
33
+ isWindowUndefined,
34
+ getOffsetTop,
35
+ getDOMNode,
36
+ getOperationNameFromQuery,
30
37
  } from './utils';
31
38
  import { RuntimeFilterOp } from './types';
32
39
  import { logger } from './utils/logger';
@@ -388,6 +395,18 @@ describe('Fullscreen Utility Functions', () => {
388
395
  expect(logger.error).toHaveBeenCalledWith('Fullscreen API is not supported by this browser.');
389
396
  });
390
397
 
398
+ it('should catch error and log warning when requestFullscreen throws (covers line 506)', async () => {
399
+ // Covers line 506: catch block inside fullscreen method attempt
400
+ (mockIframe.requestFullscreen as jest.Mock).mockRejectedValue(new Error('permission denied'));
401
+
402
+ await handlePresentEvent(mockIframe);
403
+
404
+ expect(logger.warn).toHaveBeenCalledWith(
405
+ expect.stringContaining('Failed to enter fullscreen'),
406
+ expect.any(Error),
407
+ );
408
+ });
409
+
391
410
  it('should not attempt fullscreen when already in fullscreen mode', () => {
392
411
  Object.defineProperty(document, 'fullscreenElement', {
393
412
  writable: true,
@@ -1009,6 +1028,24 @@ describe('isValidCssMargin', () => {
1009
1028
  expect(isValidCssMargin('invalid')).toBe(false);
1010
1029
  expect(isValidCssMargin('10')).toBe(false); // missing unit
1011
1030
  });
1031
+
1032
+ it('should return false and log error when value is not a string (non-string type)', () => {
1033
+ // Covers line 147-148: typeof value !== 'string' branch
1034
+ expect(isValidCssMargin(42 as any)).toBe(false);
1035
+ expect(logger.error).toHaveBeenCalledWith('Please provide a valid lazyLoadingMargin value (e.g., "10px")');
1036
+ });
1037
+
1038
+ it('should return false when more than 4 space-separated parts are given', () => {
1039
+ // Covers line 157-158: parts.length > 4 branch
1040
+ expect(isValidCssMargin('10px 20px 30px 40px 50px')).toBe(false);
1041
+ expect(logger.error).toHaveBeenCalledWith('Please provide a valid lazyLoadingMargin value (e.g., "10px")');
1042
+ });
1043
+
1044
+ it('should return true for valid multi-part margin (up to 4 parts)', () => {
1045
+ expect(isValidCssMargin('10px 20px')).toBe(true);
1046
+ expect(isValidCssMargin('10px 20px 30px 40px')).toBe(true);
1047
+ expect(isValidCssMargin('auto')).toBe(true);
1048
+ });
1012
1049
  });
1013
1050
 
1014
1051
  describe('getValueFromWindow and storeValueInWindow', () => {
@@ -1140,3 +1177,161 @@ describe('getValueFromWindow and storeValueInWindow', () => {
1140
1177
  });
1141
1178
  });
1142
1179
  });
1180
+
1181
+ // ---------------------------------------------------------------------------
1182
+ // getSSOMarker
1183
+ // ---------------------------------------------------------------------------
1184
+ describe('getSSOMarker', () => {
1185
+ test('returns tsSSOMarker query string with encoded markerId', () => {
1186
+ expect(getSSOMarker('abc123')).toBe('tsSSOMarker=abc123');
1187
+ });
1188
+
1189
+ test('URL-encodes special characters in markerId', () => {
1190
+ expect(getSSOMarker('hello world')).toBe('tsSSOMarker=hello%20world');
1191
+ expect(getSSOMarker('foo=bar&baz')).toBe('tsSSOMarker=foo%3Dbar%26baz');
1192
+ });
1193
+
1194
+ test('handles empty string markerId', () => {
1195
+ expect(getSSOMarker('')).toBe('tsSSOMarker=');
1196
+ });
1197
+ });
1198
+
1199
+ // ---------------------------------------------------------------------------
1200
+ // deepMerge
1201
+ // ---------------------------------------------------------------------------
1202
+ describe('deepMerge', () => {
1203
+ test('merges two flat objects', () => {
1204
+ const result = deepMerge({ a: 1 }, { b: 2 });
1205
+ expect(result).toEqual({ a: 1, b: 2 });
1206
+ });
1207
+
1208
+ test('source overrides target for same keys', () => {
1209
+ const result = deepMerge({ a: 1, b: 2 }, { b: 99 });
1210
+ expect(result).toEqual({ a: 1, b: 99 });
1211
+ });
1212
+
1213
+ test('deep merges nested objects', () => {
1214
+ const result = deepMerge({ a: { x: 1, y: 2 } }, { a: { y: 99, z: 3 } });
1215
+ expect(result).toEqual({ a: { x: 1, y: 99, z: 3 } });
1216
+ });
1217
+
1218
+ test('handles empty source', () => {
1219
+ const result = deepMerge({ a: 1 }, {});
1220
+ expect(result).toEqual({ a: 1 });
1221
+ });
1222
+
1223
+ test('handles empty target', () => {
1224
+ const result = deepMerge({}, { b: 2 });
1225
+ expect(result).toEqual({ b: 2 });
1226
+ });
1227
+ });
1228
+
1229
+ // ---------------------------------------------------------------------------
1230
+ // getHostEventsConfig
1231
+ // ---------------------------------------------------------------------------
1232
+ describe('getHostEventsConfig', () => {
1233
+ test('returns shouldBypassPayloadValidation and useHostEventsV2 from viewConfig', () => {
1234
+ const viewConfig: any = { shouldBypassPayloadValidation: true, useHostEventsV2: false };
1235
+ expect(getHostEventsConfig(viewConfig)).toEqual({
1236
+ shouldBypassPayloadValidation: true,
1237
+ useHostEventsV2: false,
1238
+ });
1239
+ });
1240
+
1241
+ test('returns undefined for missing keys', () => {
1242
+ const result = getHostEventsConfig({} as any);
1243
+ expect(result.shouldBypassPayloadValidation).toBeUndefined();
1244
+ expect(result.useHostEventsV2).toBeUndefined();
1245
+ });
1246
+
1247
+ test('ignores unrelated config properties', () => {
1248
+ const viewConfig: any = {
1249
+ shouldBypassPayloadValidation: false,
1250
+ useHostEventsV2: true,
1251
+ liveboardId: 'lb-1',
1252
+ };
1253
+ expect(getHostEventsConfig(viewConfig)).toEqual({
1254
+ shouldBypassPayloadValidation: false,
1255
+ useHostEventsV2: true,
1256
+ });
1257
+ });
1258
+ });
1259
+
1260
+ // ---------------------------------------------------------------------------
1261
+ // isWindowUndefined
1262
+ // ---------------------------------------------------------------------------
1263
+ describe('isWindowUndefined', () => {
1264
+ test('returns false when window is defined (browser/jsdom env)', () => {
1265
+ // In jest/jsdom, window is always defined
1266
+ expect(isWindowUndefined()).toBe(false);
1267
+ });
1268
+ });
1269
+
1270
+ // ---------------------------------------------------------------------------
1271
+ // getOffsetTop
1272
+ // ---------------------------------------------------------------------------
1273
+ describe('getOffsetTop', () => {
1274
+ test('returns rect.top + window.scrollY', () => {
1275
+ const mockElement = {
1276
+ getBoundingClientRect: () => ({ top: 50 }),
1277
+ };
1278
+ Object.defineProperty(window, 'scrollY', { value: 100, configurable: true });
1279
+ expect(getOffsetTop(mockElement)).toBe(150);
1280
+ });
1281
+
1282
+ test('returns rect.top when scrollY is 0', () => {
1283
+ const mockElement = {
1284
+ getBoundingClientRect: () => ({ top: 30 }),
1285
+ };
1286
+ Object.defineProperty(window, 'scrollY', { value: 0, configurable: true });
1287
+ expect(getOffsetTop(mockElement)).toBe(30);
1288
+ });
1289
+ });
1290
+
1291
+ // ---------------------------------------------------------------------------
1292
+ // getDOMNode
1293
+ // ---------------------------------------------------------------------------
1294
+ describe('getDOMNode', () => {
1295
+ test('returns the element from document.querySelector when passed a string selector', () => {
1296
+ const div = document.createElement('div');
1297
+ div.id = 'test-dom-node';
1298
+ document.body.appendChild(div);
1299
+ expect(getDOMNode('#test-dom-node')).toBe(div);
1300
+ document.body.removeChild(div);
1301
+ });
1302
+
1303
+ test('returns the element directly when passed an HTMLElement', () => {
1304
+ const div = document.createElement('div');
1305
+ expect(getDOMNode(div)).toBe(div);
1306
+ });
1307
+
1308
+ test('returns null for a selector that matches nothing', () => {
1309
+ expect(getDOMNode('#nonexistent-element-xyz')).toBeNull();
1310
+ });
1311
+ });
1312
+
1313
+ // ---------------------------------------------------------------------------
1314
+ // getOperationNameFromQuery
1315
+ // ---------------------------------------------------------------------------
1316
+ describe('getOperationNameFromQuery', () => {
1317
+ test('extracts operation name from a query string', () => {
1318
+ expect(getOperationNameFromQuery('query GetUser { user { id } }')).toBe('GetUser');
1319
+ });
1320
+
1321
+ test('extracts operation name from a mutation string', () => {
1322
+ expect(getOperationNameFromQuery('mutation CreateUser { createUser { id } }')).toBe('CreateUser');
1323
+ });
1324
+
1325
+ test('returns undefined when no operation name is present', () => {
1326
+ expect(getOperationNameFromQuery('{ user { id } }')).toBeUndefined();
1327
+ });
1328
+
1329
+ test('handles multiline query strings', () => {
1330
+ const query = `
1331
+ query FetchData {
1332
+ data { id }
1333
+ }
1334
+ `;
1335
+ expect(getOperationNameFromQuery(query)).toBe('FetchData');
1336
+ });
1337
+ });
package/src/utils.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
7
7
  */
8
8
 
9
- import merge from 'ts-deepmerge';
9
+ import { merge } from 'ts-deepmerge';
10
10
  import {
11
11
  EmbedConfig,
12
12
  QueryParams,