@thoughtspot/visual-embed-sdk 1.45.0 → 1.45.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 (131) hide show
  1. package/cjs/package.json +2 -2
  2. package/cjs/src/authToken.d.ts +1 -1
  3. package/cjs/src/authToken.d.ts.map +1 -1
  4. package/cjs/src/authToken.js +2 -2
  5. package/cjs/src/authToken.js.map +1 -1
  6. package/cjs/src/authToken.spec.js +71 -0
  7. package/cjs/src/authToken.spec.js.map +1 -1
  8. package/cjs/src/embed/hostEventClient/contracts.d.ts +3 -3
  9. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  10. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  11. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +8 -8
  12. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  13. package/cjs/src/embed/hostEventClient/host-event-client.js +18 -18
  14. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  15. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +7 -7
  16. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  17. package/cjs/src/embed/liveboard.d.ts +2 -2
  18. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  19. package/cjs/src/embed/liveboard.js +2 -2
  20. package/cjs/src/embed/liveboard.js.map +1 -1
  21. package/cjs/src/embed/liveboard.spec.js +1 -1
  22. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  23. package/cjs/src/embed/ts-embed.d.ts +23 -2
  24. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  25. package/cjs/src/embed/ts-embed.js +64 -22
  26. package/cjs/src/embed/ts-embed.js.map +1 -1
  27. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  28. package/cjs/src/embed/ts-embed.spec.js +138 -19
  29. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  30. package/cjs/src/index.d.ts +2 -2
  31. package/cjs/src/index.d.ts.map +1 -1
  32. package/cjs/src/index.js +3 -2
  33. package/cjs/src/index.js.map +1 -1
  34. package/cjs/src/types.d.ts +164 -2
  35. package/cjs/src/types.d.ts.map +1 -1
  36. package/cjs/src/types.js +43 -1
  37. package/cjs/src/types.js.map +1 -1
  38. package/cjs/src/utils/processTrigger.d.ts +3 -2
  39. package/cjs/src/utils/processTrigger.d.ts.map +1 -1
  40. package/cjs/src/utils/processTrigger.js +4 -2
  41. package/cjs/src/utils/processTrigger.js.map +1 -1
  42. package/cjs/src/utils.d.ts +5 -1
  43. package/cjs/src/utils.d.ts.map +1 -1
  44. package/cjs/src/utils.js +8 -1
  45. package/cjs/src/utils.js.map +1 -1
  46. package/dist/{index-Dk-SLdNk.js → index-BdkKLLo1.js} +1 -1
  47. package/dist/src/authToken.d.ts +1 -1
  48. package/dist/src/authToken.d.ts.map +1 -1
  49. package/dist/src/embed/hostEventClient/contracts.d.ts +3 -3
  50. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  51. package/dist/src/embed/hostEventClient/host-event-client.d.ts +8 -8
  52. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  53. package/dist/src/embed/liveboard.d.ts +2 -2
  54. package/dist/src/embed/liveboard.d.ts.map +1 -1
  55. package/dist/src/embed/ts-embed.d.ts +23 -2
  56. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  57. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  58. package/dist/src/index.d.ts +2 -2
  59. package/dist/src/index.d.ts.map +1 -1
  60. package/dist/src/types.d.ts +164 -2
  61. package/dist/src/types.d.ts.map +1 -1
  62. package/dist/src/utils/processTrigger.d.ts +3 -2
  63. package/dist/src/utils/processTrigger.d.ts.map +1 -1
  64. package/dist/src/utils.d.ts +5 -1
  65. package/dist/src/utils.d.ts.map +1 -1
  66. package/dist/tsembed-react.es.js +140 -49
  67. package/dist/tsembed-react.js +139 -48
  68. package/dist/tsembed.es.js +155 -64
  69. package/dist/tsembed.js +29640 -29549
  70. package/dist/visual-embed-sdk-react-full.d.ts +196 -13
  71. package/dist/visual-embed-sdk-react.d.ts +196 -13
  72. package/dist/visual-embed-sdk.d.ts +196 -13
  73. package/lib/package.json +2 -2
  74. package/lib/src/authToken.d.ts +1 -1
  75. package/lib/src/authToken.d.ts.map +1 -1
  76. package/lib/src/authToken.js +2 -2
  77. package/lib/src/authToken.js.map +1 -1
  78. package/lib/src/authToken.spec.js +72 -1
  79. package/lib/src/authToken.spec.js.map +1 -1
  80. package/lib/src/embed/hostEventClient/contracts.d.ts +3 -3
  81. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  82. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  83. package/lib/src/embed/hostEventClient/host-event-client.d.ts +8 -8
  84. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  85. package/lib/src/embed/hostEventClient/host-event-client.js +18 -18
  86. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  87. package/lib/src/embed/hostEventClient/host-event-client.spec.js +7 -7
  88. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  89. package/lib/src/embed/liveboard.d.ts +2 -2
  90. package/lib/src/embed/liveboard.d.ts.map +1 -1
  91. package/lib/src/embed/liveboard.js +2 -2
  92. package/lib/src/embed/liveboard.js.map +1 -1
  93. package/lib/src/embed/liveboard.spec.js +1 -1
  94. package/lib/src/embed/liveboard.spec.js.map +1 -1
  95. package/lib/src/embed/ts-embed.d.ts +23 -2
  96. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  97. package/lib/src/embed/ts-embed.js +64 -22
  98. package/lib/src/embed/ts-embed.js.map +1 -1
  99. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  100. package/lib/src/embed/ts-embed.spec.js +139 -20
  101. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  102. package/lib/src/index.d.ts +2 -2
  103. package/lib/src/index.d.ts.map +1 -1
  104. package/lib/src/index.js +2 -2
  105. package/lib/src/index.js.map +1 -1
  106. package/lib/src/types.d.ts +164 -2
  107. package/lib/src/types.d.ts.map +1 -1
  108. package/lib/src/types.js +42 -0
  109. package/lib/src/types.js.map +1 -1
  110. package/lib/src/utils/processTrigger.d.ts +3 -2
  111. package/lib/src/utils/processTrigger.d.ts.map +1 -1
  112. package/lib/src/utils/processTrigger.js +4 -2
  113. package/lib/src/utils/processTrigger.js.map +1 -1
  114. package/lib/src/utils.d.ts +5 -1
  115. package/lib/src/utils.d.ts.map +1 -1
  116. package/lib/src/utils.js +6 -0
  117. package/lib/src/utils.js.map +1 -1
  118. package/package.json +2 -2
  119. package/src/authToken.spec.ts +91 -2
  120. package/src/authToken.ts +2 -2
  121. package/src/embed/hostEventClient/contracts.ts +4 -4
  122. package/src/embed/hostEventClient/host-event-client.spec.ts +7 -1
  123. package/src/embed/hostEventClient/host-event-client.ts +22 -11
  124. package/src/embed/liveboard.spec.ts +1 -1
  125. package/src/embed/liveboard.ts +5 -3
  126. package/src/embed/ts-embed.spec.ts +184 -8
  127. package/src/embed/ts-embed.ts +81 -24
  128. package/src/index.ts +2 -0
  129. package/src/types.ts +171 -0
  130. package/src/utils/processTrigger.ts +6 -3
  131. package/src/utils.ts +8 -0
@@ -15,6 +15,8 @@ import {
15
15
  SageViewConfig,
16
16
  SearchViewConfig,
17
17
  AnswerService,
18
+ SpotterEmbed,
19
+ SpotterEmbedViewConfig,
18
20
  } from '../index';
19
21
  import {
20
22
  Action,
@@ -31,6 +33,7 @@ import {
31
33
  DefaultAppInitData,
32
34
  ErrorDetailsTypes,
33
35
  EmbedErrorCodes,
36
+ ContextObject,
34
37
  } from '../types';
35
38
  import {
36
39
  executeAfterWait,
@@ -64,6 +67,7 @@ import { UIPassthroughEvent } from './hostEventClient/contracts';
64
67
  import * as sessionInfoService from '../utils/sessionInfoService';
65
68
  import * as authToken from '../authToken';
66
69
  import * as apiIntercept from '../api-intercept';
70
+ import * as processData from '../utils/processData';
67
71
 
68
72
  jest.mock('../utils/processTrigger');
69
73
 
@@ -204,6 +208,7 @@ describe('Unit test case for ts embed', () => {
204
208
  parameters: payload,
205
209
  type: UIPassthroughEvent.PinAnswerToLiveboard,
206
210
  },
211
+ undefined,
207
212
  );
208
213
  });
209
214
  });
@@ -224,6 +229,7 @@ describe('Unit test case for ts embed', () => {
224
229
  HostEvent.Save,
225
230
  'http://tshost',
226
231
  {},
232
+ undefined,
227
233
  );
228
234
  });
229
235
  });
@@ -245,6 +251,7 @@ describe('Unit test case for ts embed', () => {
245
251
  HostEvent.Save,
246
252
  'http://tshost',
247
253
  false,
254
+ undefined,
248
255
  );
249
256
  });
250
257
  });
@@ -1332,6 +1339,7 @@ describe('Unit test case for ts embed', () => {
1332
1339
  HostEvent.InfoSuccess,
1333
1340
  'http://tshost',
1334
1341
  expect.objectContaining({ info: expect.any(Object) }),
1342
+ undefined,
1335
1343
  );
1336
1344
  });
1337
1345
  });
@@ -1468,6 +1476,7 @@ describe('Unit test case for ts embed', () => {
1468
1476
  HostEvent.InfoSuccess,
1469
1477
  'http://tshost',
1470
1478
  expect.objectContaining({ info: expect.any(Object) }),
1479
+ undefined,
1471
1480
  );
1472
1481
  });
1473
1482
  });
@@ -1482,6 +1491,7 @@ describe('Unit test case for ts embed', () => {
1482
1491
  HostEvent.InfoSuccess,
1483
1492
  'http://tshost',
1484
1493
  expect.objectContaining({ info: expect.any(Object) }),
1494
+ undefined,
1485
1495
  );
1486
1496
  });
1487
1497
  });
@@ -1496,6 +1506,7 @@ describe('Unit test case for ts embed', () => {
1496
1506
  HostEvent.InfoSuccess,
1497
1507
  'http://tshost',
1498
1508
  expect.objectContaining({ info: expect.any(Object) }),
1509
+ undefined,
1499
1510
  );
1500
1511
  });
1501
1512
  });
@@ -1510,6 +1521,7 @@ describe('Unit test case for ts embed', () => {
1510
1521
  HostEvent.InfoSuccess,
1511
1522
  'http://tshost',
1512
1523
  expect.objectContaining({ info: expect.any(Object) }),
1524
+ undefined,
1513
1525
  );
1514
1526
  });
1515
1527
  });
@@ -2800,7 +2812,7 @@ describe('Unit test case for ts embed', () => {
2800
2812
  jest.clearAllMocks();
2801
2813
  document.body.innerHTML = getDocumentBody();
2802
2814
  mockPort.postMessage.mockClear();
2803
- jest.spyOn(authToken, 'getAuthenticationToken').mockResolvedValue('test-token');
2815
+ jest.spyOn(authToken, 'getAuthenticationToken').mockResolvedValue('mock-test-token-placeholder');
2804
2816
 
2805
2817
  jest.spyOn(baseInstance, 'handleAuth').mockImplementation(() => Promise.resolve(true));
2806
2818
  jest.spyOn(baseInstance, 'notifyAuthFailure').mockImplementation(() => { });
@@ -2829,7 +2841,7 @@ describe('Unit test case for ts embed', () => {
2829
2841
  expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2830
2842
  expect(mockPort.postMessage).toHaveBeenCalledWith({
2831
2843
  type: EmbedEvent.AuthExpire,
2832
- data: { authToken: 'test-token' },
2844
+ data: { authToken: 'mock-test-token-placeholder' },
2833
2845
  });
2834
2846
  });
2835
2847
  });
@@ -2864,7 +2876,7 @@ describe('Unit test case for ts embed', () => {
2864
2876
  expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2865
2877
  expect(mockPort.postMessage).toHaveBeenCalledWith({
2866
2878
  type: EmbedEvent.AuthExpire,
2867
- data: { authToken: 'test-token' },
2879
+ data: { authToken: 'mock-test-token-placeholder' },
2868
2880
  });
2869
2881
  });
2870
2882
  });
@@ -2921,6 +2933,113 @@ describe('Unit test case for ts embed', () => {
2921
2933
  });
2922
2934
  });
2923
2935
 
2936
+ describe('AutoLogin behavior in tokenRefresh', () => {
2937
+ const mockPort = { postMessage: jest.fn() };
2938
+ const mockEmbedEventPayload = { type: EmbedEvent.RefreshAuthToken, data: {} };
2939
+
2940
+ beforeEach(() => {
2941
+ jest.clearAllMocks();
2942
+ document.body.innerHTML = getDocumentBody();
2943
+ mockPort.postMessage.mockClear();
2944
+ jest.spyOn(authToken, 'getAuthenticationToken').mockResolvedValue('mock-test-token-placeholder');
2945
+ jest.spyOn(processData, 'processAuthFailure').mockImplementation(() => ({} as any));
2946
+ jest.spyOn(logger, 'error').mockImplementation(() => {});
2947
+ });
2948
+
2949
+ const renderAndTriggerRefreshAuthToken = async () => {
2950
+ const spotterEmbed = new SpotterEmbed(getRootEl(), {
2951
+ worksheetId: 'test-worksheet',
2952
+ searchOptions: {
2953
+ searchQuery: 'test query',
2954
+ },
2955
+ } as SpotterEmbedViewConfig);
2956
+ await spotterEmbed.render();
2957
+ await executeAfterWait(() => {
2958
+ const iframe = getIFrameEl();
2959
+ postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
2960
+ });
2961
+ };
2962
+
2963
+ test('Cookieless with autoLogin undefined should default to true and refresh token', async () => {
2964
+ init({
2965
+ thoughtSpotHost: 'tshost',
2966
+ authType: AuthType.TrustedAuthTokenCookieless,
2967
+ // autoLogin undefined
2968
+ });
2969
+
2970
+ await renderAndTriggerRefreshAuthToken();
2971
+
2972
+ await executeAfterWait(() => {
2973
+ expect(authToken.getAuthenticationToken).toHaveBeenCalledWith(
2974
+ expect.any(Object),
2975
+ true
2976
+ );
2977
+ });
2978
+ });
2979
+
2980
+ test('Cookieless with autoLogin true should refresh token', async () => {
2981
+ init({
2982
+ thoughtSpotHost: 'tshost',
2983
+ authType: AuthType.TrustedAuthTokenCookieless,
2984
+ autoLogin: true,
2985
+ });
2986
+
2987
+ await renderAndTriggerRefreshAuthToken();
2988
+
2989
+ await executeAfterWait(() => {
2990
+ expect(authToken.getAuthenticationToken).toHaveBeenCalledWith(
2991
+ expect.any(Object),
2992
+ true
2993
+ );
2994
+ });
2995
+ });
2996
+
2997
+ test('Cookieless with autoLogin false should not refresh token', async () => {
2998
+ init({
2999
+ thoughtSpotHost: 'tshost',
3000
+ authType: AuthType.TrustedAuthTokenCookieless,
3001
+ autoLogin: false,
3002
+ });
3003
+
3004
+ await renderAndTriggerRefreshAuthToken();
3005
+
3006
+ await executeAfterWait(() => {
3007
+ expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
3008
+ expect(mockPort.postMessage).not.toHaveBeenCalled();
3009
+ });
3010
+ });
3011
+
3012
+ test('Should handle error when getAuthenticationToken fails', async () => {
3013
+ const error = new Error('Token fetch failed');
3014
+ jest.spyOn(authToken, 'getAuthenticationToken').mockRejectedValue(error);
3015
+
3016
+ init({
3017
+ thoughtSpotHost: 'tshost',
3018
+ authType: AuthType.TrustedAuthTokenCookieless,
3019
+ autoLogin: true,
3020
+ });
3021
+
3022
+ await renderAndTriggerRefreshAuthToken();
3023
+
3024
+ await executeAfterWait(() => {
3025
+ expect(authToken.getAuthenticationToken).toHaveBeenCalledWith(
3026
+ expect.any(Object),
3027
+ true
3028
+ );
3029
+ // Check that logger.error was called with the token refresh error
3030
+ const errorCalls = (logger.error as jest.Mock).mock.calls.filter(
3031
+ (call) => call[0]?.includes(ERROR_MESSAGE.INVALID_TOKEN_ERROR) && call[0]?.includes('Token fetch failed')
3032
+ );
3033
+ expect(errorCalls.length).toBeGreaterThan(0);
3034
+ expect(processData.processAuthFailure).toHaveBeenCalledWith(
3035
+ error,
3036
+ expect.any(Element)
3037
+ );
3038
+ expect(mockPort.postMessage).not.toHaveBeenCalled();
3039
+ });
3040
+ });
3041
+ });
3042
+
2924
3043
  describe('Fullscreen Change Handler', () => {
2925
3044
  beforeEach(() => {
2926
3045
  document.body.innerHTML = getDocumentBody();
@@ -3159,6 +3278,59 @@ describe('Unit test case for ts embed', () => {
3159
3278
  expect(callback3).toHaveBeenCalledTimes(1);
3160
3279
  });
3161
3280
 
3281
+ describe('getCurrentContext', () => {
3282
+ const mockContext: ContextObject = {
3283
+ stack: [
3284
+ {
3285
+ name: 'Liveboard',
3286
+ type: 'Liveboard' as any,
3287
+ objectIds: { liveboardId: 'lb-123' },
3288
+ },
3289
+ ],
3290
+ currentContext: {
3291
+ name: 'Liveboard',
3292
+ type: 'Liveboard' as any,
3293
+ objectIds: { liveboardId: 'lb-123' },
3294
+ },
3295
+ };
3296
+
3297
+ test('should return context when embed container is already loaded', async () => {
3298
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3299
+ searchEmbed.isEmbedContainerLoaded = true;
3300
+
3301
+ const triggerSpy = jest.spyOn(searchEmbed, 'trigger')
3302
+ .mockResolvedValue(mockContext);
3303
+
3304
+ const context = await searchEmbed.getCurrentContext();
3305
+
3306
+ expect(context).toEqual(mockContext);
3307
+ expect(triggerSpy).toHaveBeenCalledWith(HostEvent.GetPageContext, {});
3308
+ });
3309
+
3310
+ test('should wait for embed container to load before returning context', async () => {
3311
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3312
+ searchEmbed.isEmbedContainerLoaded = false;
3313
+
3314
+ const triggerSpy = jest.spyOn(searchEmbed, 'trigger')
3315
+ .mockResolvedValue(mockContext);
3316
+
3317
+ const contextPromise = searchEmbed.getCurrentContext();
3318
+
3319
+ // Context should not be resolved yet
3320
+ await executeAfterWait(() => {
3321
+ expect(triggerSpy).not.toHaveBeenCalled();
3322
+ }, 10);
3323
+
3324
+ // Simulate embed container becoming ready
3325
+ searchEmbed['executeEmbedContainerReadyCallbacks']();
3326
+
3327
+ const context = await contextPromise;
3328
+
3329
+ expect(context).toEqual(mockContext);
3330
+ expect(triggerSpy).toHaveBeenCalledWith(HostEvent.GetPageContext, {});
3331
+ });
3332
+ });
3333
+
3162
3334
  test('should register embed container event handlers during construction', () => {
3163
3335
  const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3164
3336
 
@@ -4056,7 +4228,7 @@ describe('Destroy error handling', () => {
4056
4228
  }).not.toThrow();
4057
4229
 
4058
4230
  expect(logSpy).toHaveBeenCalledWith('Error destroying TS Embed', expect.any(Error));
4059
- logSpy.mockRestore();
4231
+ logSpy.mockReset();
4060
4232
  });
4061
4233
  });
4062
4234
 
@@ -4099,11 +4271,12 @@ describe('Fullscreen change handler behavior', () => {
4099
4271
  document.dispatchEvent(event);
4100
4272
 
4101
4273
  await executeAfterWait(() => {
4102
- expect(mockProcessTrigger).toHaveBeenCalledWith(
4274
+ expect(mockProcessTrigger).toHaveBeenLastCalledWith(
4103
4275
  expect.any(Object),
4104
4276
  HostEvent.ExitPresentMode,
4105
4277
  expect.any(String),
4106
4278
  expect.any(Object),
4279
+ undefined,
4107
4280
  );
4108
4281
  });
4109
4282
  });
@@ -4196,13 +4369,14 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
4196
4369
  embed2.showPreRender();
4197
4370
 
4198
4371
  await executeAfterWait(() => {
4199
- expect(mockProcessTrigger).toHaveBeenCalledWith(
4372
+ expect(mockProcessTrigger).toHaveBeenLastCalledWith(
4200
4373
  expect.any(Object),
4201
4374
  HostEvent.UpdateEmbedParams,
4202
4375
  expect.any(String),
4203
4376
  expect.objectContaining({
4204
4377
  liveboardId: 'updated-lb',
4205
4378
  }),
4379
+ undefined,
4206
4380
  );
4207
4381
  });
4208
4382
  });
@@ -4231,7 +4405,7 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
4231
4405
  embed2.showPreRender();
4232
4406
 
4233
4407
  await executeAfterWait(() => {
4234
- expect(mockProcessTrigger).toHaveBeenCalledWith(
4408
+ expect(mockProcessTrigger).toHaveBeenLastCalledWith(
4235
4409
  expect.any(Object),
4236
4410
  HostEvent.UpdateEmbedParams,
4237
4411
  expect.any(String),
@@ -4251,6 +4425,7 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
4251
4425
  },
4252
4426
  ],
4253
4427
  }),
4428
+ undefined,
4254
4429
  );
4255
4430
  });
4256
4431
  });
@@ -4283,7 +4458,7 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
4283
4458
  embed2.showPreRender();
4284
4459
 
4285
4460
  await executeAfterWait(() => {
4286
- expect(mockProcessTrigger).toHaveBeenCalledWith(
4461
+ expect(mockProcessTrigger).toHaveBeenLastCalledWith(
4287
4462
  expect.any(Object),
4288
4463
  HostEvent.UpdateEmbedParams,
4289
4464
  expect.any(String),
@@ -4298,6 +4473,7 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
4298
4473
  },
4299
4474
  ],
4300
4475
  }),
4476
+ undefined,
4301
4477
  );
4302
4478
  });
4303
4479
  });
@@ -60,6 +60,9 @@ import {
60
60
  EmbedErrorDetailsEvent,
61
61
  ErrorDetailsTypes,
62
62
  EmbedErrorCodes,
63
+ MessagePayload,
64
+ ContextType,
65
+ ContextObject,
63
66
  } from '../types';
64
67
  import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
65
68
  import { processEventData, processAuthFailure } from '../utils/processData';
@@ -75,6 +78,7 @@ import { ERROR_MESSAGE } from '../errors';
75
78
  import { getPreauthInfo } from '../utils/sessionInfoService';
76
79
  import { HostEventClient } from './hostEventClient/host-event-client';
77
80
  import { getInterceptInitData, handleInterceptEvent, processApiInterceptResponse, processLegacyInterceptResponse } from '../api-intercept';
81
+ import { getHostEventsConfig } from '../utils';
78
82
 
79
83
  const { version } = pkgInfo;
80
84
 
@@ -479,7 +483,9 @@ export class TsEmbed {
479
483
  this.embedConfig.customVariablesForThirdPartyTools || {},
480
484
  hiddenListColumns: this.viewConfig.hiddenListColumns || [],
481
485
  customActions: customActionsResult.actions,
486
+ embedExpiryInAuthToken: this.viewConfig.refreshAuthTokenOnNearExpiry,
482
487
  ...getInterceptInitData(this.viewConfig),
488
+ ...getHostEventsConfig(this.viewConfig),
483
489
  };
484
490
 
485
491
  return baseInitData;
@@ -507,29 +513,65 @@ export class TsEmbed {
507
513
  }
508
514
  };
509
515
 
516
+ /**
517
+ * Helper method to refresh/update auth token for TrustedAuthTokenCookieless auth type
518
+ * @param responder - Function to send response back
519
+ * @param eventType - The embed event type to send
520
+ * @param forceRefresh - Whether to force refresh the token
521
+ * @returns Promise that resolves if token was refreshed, rejects otherwise
522
+ */
523
+ private async refreshAuthTokenForCookieless(
524
+ responder: (data: any) => void,
525
+ eventType: EmbedEvent,
526
+ forceRefresh: boolean = false
527
+ ): Promise<void> {
528
+ const { authType, autoLogin } = this.embedConfig;
529
+ const isAutoLoginTrue = autoLogin ?? (authType === AuthType.TrustedAuthTokenCookieless);
530
+
531
+ if (isAutoLoginTrue && authType === AuthType.TrustedAuthTokenCookieless) {
532
+ const authToken = await getAuthenticationToken(this.embedConfig, forceRefresh);
533
+ responder({
534
+ type: eventType,
535
+ data: { authToken },
536
+ });
537
+ }
538
+ }
539
+
540
+ private handleAuthFailure = (error: Error) => {
541
+ logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${error?.message}`);
542
+ processAuthFailure(error, this.isPreRendered ? this.preRenderWrapper : this.el);
543
+ }
544
+
545
+ /**
546
+ * Refresh the auth token if the autoLogin is true and the authType is TrustedAuthTokenCookieless
547
+ * @param _
548
+ * @param responder
549
+ */
550
+ private tokenRefresh = async (_: MessagePayload, responder: (data: {type: EmbedEvent, data: {authToken: string}}) => void) => {
551
+ try {
552
+ await this.refreshAuthTokenForCookieless(responder, EmbedEvent.RefreshAuthToken, true);
553
+ } catch (e) {
554
+ this.handleAuthFailure(e);
555
+ }
556
+ }
557
+
510
558
  /**
511
559
  * Sends updated auth token to the iFrame to avoid user logout
512
560
  * @param _
513
561
  * @param responder
514
562
  */
515
- private updateAuthToken = async (_: any, responder: any) => {
516
- const { authType } = this.embedConfig;
517
- let { autoLogin } = this.embedConfig;
518
- // Default autoLogin: true for cookieless if undefined/null, otherwise
519
- // false
520
- autoLogin = autoLogin ?? (authType === AuthType.TrustedAuthTokenCookieless);
521
- if (autoLogin && authType === AuthType.TrustedAuthTokenCookieless) {
522
- try {
523
- const authToken = await getAuthenticationToken(this.embedConfig);
524
- responder({
525
- type: EmbedEvent.AuthExpire,
526
- data: { authToken },
527
- });
528
- } catch (e) {
529
- logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${e?.message}`);
530
- processAuthFailure(e, this.isPreRendered ? this.preRenderWrapper : this.el);
531
- }
532
- } else if (autoLogin) {
563
+ private updateAuthToken = async (_: MessagePayload, responder: any) => {
564
+ const { authType, autoLogin: autoLoginConfig } = this.embedConfig;
565
+ // Default autoLogin: true for cookieless if undefined/null, otherwise false
566
+ const autoLogin = autoLoginConfig ?? (authType === AuthType.TrustedAuthTokenCookieless);
567
+
568
+ try {
569
+ await this.refreshAuthTokenForCookieless(responder, EmbedEvent.AuthExpire, false);
570
+ } catch (e) {
571
+ this.handleAuthFailure(e);
572
+ }
573
+
574
+ if (autoLogin && authType !== AuthType.TrustedAuthTokenCookieless) {
533
575
  handleAuth();
534
576
  }
535
577
  notifyAuthFailure(AuthFailureType.EXPIRY);
@@ -550,8 +592,7 @@ export class TsEmbed {
550
592
  data: { authToken },
551
593
  });
552
594
  } catch (e) {
553
- logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${e?.message}`);
554
- processAuthFailure(e, this.isPreRendered ? this.preRenderWrapper : this.el);
595
+ this.handleAuthFailure(e);
555
596
  }
556
597
  }).catch((e) => {
557
598
  logger.error(`Auto Login failed, Error : ${e?.message}`);
@@ -569,9 +610,10 @@ export class TsEmbed {
569
610
 
570
611
  const embedListenerReadyHandler = this.createEmbedContainerHandler(EmbedEvent.EmbedListenerReady);
571
612
  this.on(EmbedEvent.EmbedListenerReady, embedListenerReadyHandler, { start: false }, true);
572
-
613
+
573
614
  const authInitHandler = this.createEmbedContainerHandler(EmbedEvent.AuthInit);
574
615
  this.on(EmbedEvent.AuthInit, authInitHandler, { start: false }, true);
616
+ this.on(EmbedEvent.RefreshAuthToken, this.tokenRefresh, { start: false }, true);
575
617
  };
576
618
 
577
619
  /**
@@ -1347,10 +1389,11 @@ export class TsEmbed {
1347
1389
  * @param {any} data The payload to send with the message
1348
1390
  * @returns A promise that resolves with the response from the embedded app
1349
1391
  */
1350
- public async trigger<HostEventT extends HostEvent, PayloadT>(
1392
+ public async trigger<HostEventT extends HostEvent, PayloadT, ContextT extends ContextType>(
1351
1393
  messageType: HostEventT,
1352
1394
  data: TriggerPayload<PayloadT, HostEventT> = {} as any,
1353
- ): Promise<TriggerResponse<PayloadT, HostEventT>> {
1395
+ context?: ContextT,
1396
+ ): Promise<TriggerResponse<PayloadT, HostEventT, ContextT>> {
1354
1397
  uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`);
1355
1398
 
1356
1399
  if (!this.isRendered) {
@@ -1383,7 +1426,7 @@ export class TsEmbed {
1383
1426
  }
1384
1427
 
1385
1428
  // send an empty object, this is needed for liveboard default handlers
1386
- return this.hostEventClient.triggerHostEvent(messageType, data);
1429
+ return this.hostEventClient.triggerHostEvent(messageType, data, context);
1387
1430
  }
1388
1431
 
1389
1432
  /**
@@ -1425,6 +1468,20 @@ export class TsEmbed {
1425
1468
  return this.render();
1426
1469
  }
1427
1470
 
1471
+ /**
1472
+ * Get the current context of the embedded TS component.
1473
+ * @returns The current context object containing the page type and object ids.
1474
+ * @version SDK: 1.45.2 | ThoughtSpot: 26.3.0.cl
1475
+ */
1476
+ public async getCurrentContext(): Promise<ContextObject> {
1477
+ return new Promise((resolve) => {
1478
+ this.executeAfterEmbedContainerLoaded(async () => {
1479
+ const context = await this.trigger(HostEvent.GetPageContext, {});
1480
+ resolve(context);
1481
+ });
1482
+ });
1483
+ }
1484
+
1428
1485
  /**
1429
1486
  * Creates the preRender shell
1430
1487
  * @param showPreRenderByDefault - Show the preRender after render, hidden by default
package/src/index.ts CHANGED
@@ -68,6 +68,7 @@ import {
68
68
  InterceptedApiType,
69
69
  EmbedErrorCodes,
70
70
  ErrorDetailsTypes,
71
+ ContextType,
71
72
  } from './types';
72
73
  import { CustomCssVariables } from './css-variables';
73
74
  import { SageEmbed, SageViewConfig } from './embed/sage';
@@ -121,6 +122,7 @@ export {
121
122
  RuntimeFilterOp,
122
123
  EmbedEvent,
123
124
  HostEvent,
125
+ ContextType,
124
126
  DataSourceVisualMode,
125
127
  Action,
126
128
  ContextMenuTriggerOptions,