@thoughtspot/visual-embed-sdk 1.24.0-dev → 1.24.0-preRender.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 (231) hide show
  1. package/cjs/package.json +2 -3
  2. package/cjs/src/embed/app.d.ts +3 -1
  3. package/cjs/src/embed/app.d.ts.map +1 -1
  4. package/cjs/src/embed/app.js +8 -2
  5. package/cjs/src/embed/app.js.map +1 -1
  6. package/cjs/src/embed/base.d.ts +2 -0
  7. package/cjs/src/embed/base.d.ts.map +1 -1
  8. package/cjs/src/embed/base.js +2 -0
  9. package/cjs/src/embed/base.js.map +1 -1
  10. package/cjs/src/embed/liveboard.d.ts +3 -2
  11. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  12. package/cjs/src/embed/liveboard.js +6 -5
  13. package/cjs/src/embed/liveboard.js.map +1 -1
  14. package/cjs/src/embed/sage.d.ts +4 -1
  15. package/cjs/src/embed/sage.d.ts.map +1 -1
  16. package/cjs/src/embed/sage.js +9 -2
  17. package/cjs/src/embed/sage.js.map +1 -1
  18. package/cjs/src/embed/search-bar.d.ts +1 -0
  19. package/cjs/src/embed/search-bar.d.ts.map +1 -1
  20. package/cjs/src/embed/search-bar.js +1 -0
  21. package/cjs/src/embed/search-bar.js.map +1 -1
  22. package/cjs/src/embed/search.d.ts +5 -1
  23. package/cjs/src/embed/search.d.ts.map +1 -1
  24. package/cjs/src/embed/search.js +10 -2
  25. package/cjs/src/embed/search.js.map +1 -1
  26. package/cjs/src/embed/ts-embed.d.ts +9 -3
  27. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  28. package/cjs/src/embed/ts-embed.js +50 -20
  29. package/cjs/src/embed/ts-embed.js.map +1 -1
  30. package/cjs/src/embed/ts-embed.spec.js +47 -0
  31. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  32. package/cjs/src/index.d.ts +3 -2
  33. package/cjs/src/index.d.ts.map +1 -1
  34. package/cjs/src/index.js +3 -1
  35. package/cjs/src/index.js.map +1 -1
  36. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  37. package/cjs/src/mixpanel-service.js +2 -0
  38. package/cjs/src/mixpanel-service.js.map +1 -1
  39. package/cjs/src/mixpanel-service.spec.js +1 -0
  40. package/cjs/src/mixpanel-service.spec.js.map +1 -1
  41. package/cjs/src/react/index.d.ts +5 -1
  42. package/cjs/src/react/index.d.ts.map +1 -1
  43. package/cjs/src/react/index.js +8 -8
  44. package/cjs/src/react/index.js.map +1 -1
  45. package/cjs/src/types.d.ts +46 -18
  46. package/cjs/src/types.d.ts.map +1 -1
  47. package/cjs/src/types.js +7 -13
  48. package/cjs/src/types.js.map +1 -1
  49. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +5 -0
  50. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -0
  51. package/cjs/src/utils/graphql/answerService/answer-queries.js +80 -0
  52. package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -0
  53. package/cjs/src/utils/graphql/answerService/answerService.d.ts +61 -0
  54. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -0
  55. package/cjs/src/utils/graphql/answerService/answerService.js +182 -0
  56. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -0
  57. package/cjs/src/utils/graphql/answerService/answerService.spec.d.ts +2 -0
  58. package/cjs/src/utils/graphql/answerService/answerService.spec.d.ts.map +1 -0
  59. package/cjs/src/utils/graphql/answerService/answerService.spec.js +201 -0
  60. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -0
  61. package/cjs/src/utils/graphql/graphql-request.d.ts +15 -0
  62. package/cjs/src/utils/graphql/graphql-request.d.ts.map +1 -0
  63. package/cjs/src/utils/graphql/graphql-request.js +40 -0
  64. package/cjs/src/utils/graphql/graphql-request.js.map +1 -0
  65. package/cjs/src/utils/graphql/sourceService.d.ts +8 -0
  66. package/cjs/src/utils/graphql/sourceService.d.ts.map +1 -0
  67. package/cjs/src/utils/graphql/sourceService.js +69 -0
  68. package/cjs/src/utils/graphql/sourceService.js.map +1 -0
  69. package/cjs/src/utils/graphql/sourceService.spec.d.ts +2 -0
  70. package/cjs/src/utils/graphql/sourceService.spec.d.ts.map +1 -0
  71. package/cjs/src/utils/graphql/sourceService.spec.js +12 -0
  72. package/cjs/src/utils/graphql/sourceService.spec.js.map +1 -0
  73. package/cjs/src/utils/processData.d.ts.map +1 -1
  74. package/cjs/src/utils/processData.js +7 -11
  75. package/cjs/src/utils/processData.js.map +1 -1
  76. package/cjs/src/utils/processData.spec.js +13 -17
  77. package/cjs/src/utils/processData.spec.js.map +1 -1
  78. package/cjs/src/utils.d.ts +6 -0
  79. package/cjs/src/utils.d.ts.map +1 -1
  80. package/cjs/src/utils.js +26 -1
  81. package/cjs/src/utils.js.map +1 -1
  82. package/dist/src/embed/app.d.ts +3 -1
  83. package/dist/src/embed/app.d.ts.map +1 -1
  84. package/dist/src/embed/base.d.ts +2 -0
  85. package/dist/src/embed/base.d.ts.map +1 -1
  86. package/dist/src/embed/liveboard.d.ts +3 -2
  87. package/dist/src/embed/liveboard.d.ts.map +1 -1
  88. package/dist/src/embed/sage.d.ts +4 -1
  89. package/dist/src/embed/sage.d.ts.map +1 -1
  90. package/dist/src/embed/search-bar.d.ts +1 -0
  91. package/dist/src/embed/search-bar.d.ts.map +1 -1
  92. package/dist/src/embed/search.d.ts +5 -1
  93. package/dist/src/embed/search.d.ts.map +1 -1
  94. package/dist/src/embed/ts-embed.d.ts +9 -3
  95. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  96. package/dist/src/index.d.ts +3 -2
  97. package/dist/src/index.d.ts.map +1 -1
  98. package/dist/src/mixpanel-service.d.ts.map +1 -1
  99. package/dist/src/react/index.d.ts +5 -1
  100. package/dist/src/react/index.d.ts.map +1 -1
  101. package/dist/src/types.d.ts +46 -18
  102. package/dist/src/types.d.ts.map +1 -1
  103. package/dist/src/utils/graphql/answerService/answer-queries.d.ts +5 -0
  104. package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -0
  105. package/dist/src/utils/graphql/answerService/answerService.d.ts +61 -0
  106. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -0
  107. package/dist/src/utils/graphql/answerService/answerService.spec.d.ts +2 -0
  108. package/dist/src/utils/graphql/answerService/answerService.spec.d.ts.map +1 -0
  109. package/dist/src/utils/graphql/graphql-request.d.ts +15 -0
  110. package/dist/src/utils/graphql/graphql-request.d.ts.map +1 -0
  111. package/dist/src/utils/graphql/sourceService.d.ts +8 -0
  112. package/dist/src/utils/graphql/sourceService.d.ts.map +1 -0
  113. package/dist/src/utils/graphql/sourceService.spec.d.ts +2 -0
  114. package/dist/src/utils/graphql/sourceService.spec.d.ts.map +1 -0
  115. package/dist/src/utils/processData.d.ts.map +1 -1
  116. package/dist/src/utils.d.ts +6 -0
  117. package/dist/src/utils.d.ts.map +1 -1
  118. package/dist/tsembed-react.es.js +468 -107
  119. package/dist/tsembed-react.js +471 -106
  120. package/dist/tsembed.es.js +511 -103
  121. package/dist/tsembed.js +511 -102
  122. package/dist/visual-embed-sdk-react-full.d.ts +132 -28
  123. package/dist/visual-embed-sdk-react.d.ts +132 -28
  124. package/dist/visual-embed-sdk.d.ts +127 -27
  125. package/lib/package.json +2 -3
  126. package/lib/src/embed/app.d.ts +3 -1
  127. package/lib/src/embed/app.d.ts.map +1 -1
  128. package/lib/src/embed/app.js +8 -2
  129. package/lib/src/embed/app.js.map +1 -1
  130. package/lib/src/embed/base.d.ts +2 -0
  131. package/lib/src/embed/base.d.ts.map +1 -1
  132. package/lib/src/embed/base.js +2 -0
  133. package/lib/src/embed/base.js.map +1 -1
  134. package/lib/src/embed/liveboard.d.ts +3 -2
  135. package/lib/src/embed/liveboard.d.ts.map +1 -1
  136. package/lib/src/embed/liveboard.js +6 -5
  137. package/lib/src/embed/liveboard.js.map +1 -1
  138. package/lib/src/embed/sage.d.ts +4 -1
  139. package/lib/src/embed/sage.d.ts.map +1 -1
  140. package/lib/src/embed/sage.js +9 -2
  141. package/lib/src/embed/sage.js.map +1 -1
  142. package/lib/src/embed/search-bar.d.ts +1 -0
  143. package/lib/src/embed/search-bar.d.ts.map +1 -1
  144. package/lib/src/embed/search-bar.js +1 -0
  145. package/lib/src/embed/search-bar.js.map +1 -1
  146. package/lib/src/embed/search.d.ts +5 -1
  147. package/lib/src/embed/search.d.ts.map +1 -1
  148. package/lib/src/embed/search.js +10 -2
  149. package/lib/src/embed/search.js.map +1 -1
  150. package/lib/src/embed/ts-embed.d.ts +9 -3
  151. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  152. package/lib/src/embed/ts-embed.js +50 -20
  153. package/lib/src/embed/ts-embed.js.map +1 -1
  154. package/lib/src/embed/ts-embed.spec.js +47 -0
  155. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  156. package/lib/src/index.d.ts +3 -2
  157. package/lib/src/index.d.ts.map +1 -1
  158. package/lib/src/index.js +2 -1
  159. package/lib/src/index.js.map +1 -1
  160. package/lib/src/mixpanel-service.d.ts.map +1 -1
  161. package/lib/src/mixpanel-service.js +2 -0
  162. package/lib/src/mixpanel-service.js.map +1 -1
  163. package/lib/src/mixpanel-service.spec.js +1 -0
  164. package/lib/src/mixpanel-service.spec.js.map +1 -1
  165. package/lib/src/react/index.d.ts +5 -1
  166. package/lib/src/react/index.d.ts.map +1 -1
  167. package/lib/src/react/index.js +7 -7
  168. package/lib/src/react/index.js.map +1 -1
  169. package/lib/src/types.d.ts +46 -18
  170. package/lib/src/types.d.ts.map +1 -1
  171. package/lib/src/types.js +6 -12
  172. package/lib/src/types.js.map +1 -1
  173. package/lib/src/utils/graphql/answerService/answer-queries.d.ts +5 -0
  174. package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -0
  175. package/lib/src/utils/graphql/answerService/answer-queries.js +77 -0
  176. package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -0
  177. package/lib/src/utils/graphql/answerService/answerService.d.ts +61 -0
  178. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -0
  179. package/lib/src/utils/graphql/answerService/answerService.js +177 -0
  180. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -0
  181. package/lib/src/utils/graphql/answerService/answerService.spec.d.ts +2 -0
  182. package/lib/src/utils/graphql/answerService/answerService.spec.d.ts.map +1 -0
  183. package/lib/src/utils/graphql/answerService/answerService.spec.js +199 -0
  184. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -0
  185. package/lib/src/utils/graphql/graphql-request.d.ts +15 -0
  186. package/lib/src/utils/graphql/graphql-request.d.ts.map +1 -0
  187. package/lib/src/utils/graphql/graphql-request.js +36 -0
  188. package/lib/src/utils/graphql/graphql-request.js.map +1 -0
  189. package/lib/src/utils/graphql/sourceService.d.ts +8 -0
  190. package/lib/src/utils/graphql/sourceService.d.ts.map +1 -0
  191. package/lib/src/utils/graphql/sourceService.js +65 -0
  192. package/lib/src/utils/graphql/sourceService.js.map +1 -0
  193. package/lib/src/utils/graphql/sourceService.spec.d.ts +2 -0
  194. package/lib/src/utils/graphql/sourceService.spec.d.ts.map +1 -0
  195. package/lib/src/utils/graphql/sourceService.spec.js +10 -0
  196. package/lib/src/utils/graphql/sourceService.spec.js.map +1 -0
  197. package/lib/src/utils/processData.d.ts.map +1 -1
  198. package/lib/src/utils/processData.js +8 -12
  199. package/lib/src/utils/processData.js.map +1 -1
  200. package/lib/src/utils/processData.spec.js +14 -18
  201. package/lib/src/utils/processData.spec.js.map +1 -1
  202. package/lib/src/utils.d.ts +6 -0
  203. package/lib/src/utils.d.ts.map +1 -1
  204. package/lib/src/utils.js +23 -0
  205. package/lib/src/utils.js.map +1 -1
  206. package/lib/src/visual-embed-sdk.d.ts +133 -28
  207. package/package.json +2 -3
  208. package/src/embed/app.ts +12 -2
  209. package/src/embed/base.ts +2 -0
  210. package/src/embed/liveboard.ts +7 -5
  211. package/src/embed/sage.ts +13 -2
  212. package/src/embed/search-bar.tsx +2 -0
  213. package/src/embed/search.ts +14 -2
  214. package/src/embed/ts-embed.spec.ts +49 -0
  215. package/src/embed/ts-embed.ts +61 -22
  216. package/src/index.ts +5 -0
  217. package/src/mixpanel-service.spec.ts +1 -0
  218. package/src/mixpanel-service.ts +1 -0
  219. package/src/react/index.tsx +40 -37
  220. package/src/types.ts +50 -19
  221. package/src/utils/graphql/answerService/answer-queries.ts +80 -0
  222. package/src/utils/graphql/answerService/answerService.spec.ts +231 -0
  223. package/src/utils/graphql/answerService/answerService.ts +234 -0
  224. package/src/utils/graphql/graphql-request.ts +45 -0
  225. package/src/utils/graphql/sourceService.spec.ts +10 -0
  226. package/src/utils/graphql/sourceService.ts +71 -0
  227. package/src/utils/processData.spec.ts +15 -25
  228. package/src/utils/processData.ts +13 -15
  229. package/src/utils.ts +25 -0
  230. package/src/utils/answerService.spec.ts +0 -41
  231. package/src/utils/answerService.ts +0 -63
@@ -1,8 +1,8 @@
1
1
  import * as processDataInstance from './processData';
2
- import * as answerServiceInstance from './answerService';
2
+ import * as answerServiceInstance from './graphql/answerService/answerService';
3
3
  import * as auth from '../auth';
4
4
  import * as base from '../embed/base';
5
- import { EmbedEvent, OperationType, AuthType } from '../types';
5
+ import { EmbedEvent, AuthType } from '../types';
6
6
 
7
7
  describe('Unit test for process data', () => {
8
8
  beforeAll(() => {
@@ -16,26 +16,12 @@ describe('Unit test for process data', () => {
16
16
  });
17
17
 
18
18
  const thoughtSpotHost = 'http://localhost';
19
- test('processDataInstance, when operation is GetChartWithData', () => {
20
- const answerService = {};
21
- const processChartData = {
22
- answerService,
23
- data: {
24
- session: 'session',
25
- query: 'query',
26
- operation: OperationType.GetChartWithData,
27
- },
28
- };
29
- jest.spyOn(answerServiceInstance, 'getAnswerServiceInstance').mockReturnValue(
30
- answerService,
31
- );
32
- expect(
33
- processDataInstance.processCustomAction(processChartData, thoughtSpotHost),
34
- ).toStrictEqual(processChartData);
35
- });
36
19
 
37
20
  test('ProcessData, when Action is CustomAction', async () => {
38
- const processedData = { type: EmbedEvent.CustomAction };
21
+ const processedData = {
22
+ type: EmbedEvent.CustomAction,
23
+ data: {},
24
+ };
39
25
  jest.spyOn(processDataInstance, 'processCustomAction').mockImplementation(async () => ({}));
40
26
  expect(
41
27
  processDataInstance.processEventData(
@@ -44,16 +30,20 @@ describe('Unit test for process data', () => {
44
30
  thoughtSpotHost,
45
31
  null,
46
32
  ),
47
- ).toStrictEqual(processedData);
33
+ ).toEqual(expect.objectContaining({
34
+ ...processedData,
35
+ answerService: {
36
+ answer: undefined,
37
+ selectedPoints: undefined,
38
+ session: undefined,
39
+ thoughtSpotHost: 'http://localhost',
40
+ },
41
+ }));
48
42
  });
49
43
 
50
44
  test('ProcessData, when Action is non CustomAction', () => {
51
45
  const processedData = { type: EmbedEvent.Data };
52
46
  jest.spyOn(processDataInstance, 'processCustomAction').mockImplementation(async () => ({}));
53
- jest.spyOn(
54
- answerServiceInstance,
55
- 'getAnswerServiceInstance',
56
- ).mockImplementation(async () => ({}));
57
47
  processDataInstance.processEventData(EmbedEvent.Data, processedData, thoughtSpotHost, null);
58
48
  expect(processDataInstance.processCustomAction).not.toBeCalled();
59
49
  });
@@ -6,8 +6,8 @@ import {
6
6
  notifyLogout,
7
7
  } from '../embed/base';
8
8
  import { AuthFailureType, initSession } from '../auth';
9
- import { AuthType, EmbedEvent, OperationType } from '../types';
10
- import { getAnswerServiceInstance } from './answerService';
9
+ import { AuthType, CustomActionPayload, EmbedEvent } from '../types';
10
+ import { AnswerService } from './graphql/answerService/answerService';
11
11
 
12
12
  /**
13
13
  *
@@ -15,19 +15,17 @@ import { getAnswerServiceInstance } from './answerService';
15
15
  * @param thoughtSpotHost
16
16
  */
17
17
  export function processCustomAction(e: any, thoughtSpotHost: string) {
18
- if (
19
- [OperationType.GetChartWithData, OperationType.GetTableWithHeadlineData].includes(
20
- e.data?.operation,
21
- )
22
- ) {
23
- const { session, query, operation } = e.data;
24
- const answerService = getAnswerServiceInstance(session, query, operation, thoughtSpotHost);
25
- return {
26
- ...e,
27
- answerService,
28
- };
29
- }
30
- return e;
18
+ const { session, embedAnswerData, contextMenuPoints } = e.data as CustomActionPayload;
19
+ const answerService = new AnswerService(
20
+ session,
21
+ embedAnswerData,
22
+ thoughtSpotHost,
23
+ contextMenuPoints?.selectedPoints,
24
+ );
25
+ return {
26
+ ...e,
27
+ answerService,
28
+ };
31
29
  }
32
30
 
33
31
  /**
package/src/utils.ts CHANGED
@@ -249,6 +249,24 @@ export function getDOMNode(domSelector: DOMSelector): HTMLElement {
249
249
 
250
250
  export const deepMerge = (target: any, source: any) => merge(target, source);
251
251
 
252
+ /**
253
+ *
254
+ * @param obj
255
+ */
256
+ export function removeTypename(obj: any) {
257
+ if (!obj || typeof obj !== 'object') return obj;
258
+
259
+ // eslint-disable-next-line no-restricted-syntax
260
+ for (const key in obj) {
261
+ if (key === '__typename') {
262
+ delete obj[key];
263
+ } else if (typeof obj[key] === 'object') {
264
+ removeTypename(obj[key]);
265
+ }
266
+ }
267
+ return obj;
268
+ }
269
+
252
270
  export const setStyleProperties = (
253
271
  element: HTMLElement,
254
272
  styleProperties: Partial<CSSStyleDeclaration>,
@@ -268,3 +286,10 @@ export const removeStyleProperties = (
268
286
  element.style.removeProperty(styleProperty);
269
287
  });
270
288
  };
289
+
290
+ export const getOperationNameFromQuery = (query: string) => {
291
+ const regex = /(?:query|mutation)\s+(\w+)/;
292
+ const matches = query.match(regex);
293
+ return matches?.[1];
294
+ };
295
+
@@ -1,41 +0,0 @@
1
- import { getAnswerServiceInstance } from './answerService';
2
-
3
- describe('Unit test for getAnswerServiceInstance', () => {
4
- const session = {
5
- sessionId: '',
6
- genNo: 2,
7
- acSession: { sessionId: '', genNo: 1 },
8
- };
9
- const query = '';
10
- const thoughtSpotHost = 'http://10.79.135.124:3000';
11
-
12
- test('fetchData, when api giving answer data', async () => {
13
- const mockAnswerResponse = { data: {} };
14
- global.fetch = jest.fn(() => Promise.resolve({
15
- json: () => mockAnswerResponse,
16
- }));
17
- const answerService = getAnswerServiceInstance(
18
- session,
19
- query,
20
- 'GetTableWithHeadlineData',
21
- thoughtSpotHost,
22
- );
23
- const answerData = await answerService.fetchData(1, 500);
24
- expect(answerData).toStrictEqual(mockAnswerResponse.data);
25
- expect(answerData).not.toBeInstanceOf(Error);
26
- expect(fetch).toHaveBeenCalledTimes(1);
27
- });
28
-
29
- test('fetchData, when api giving error', async () => {
30
- global.fetch = jest.fn(() => Promise.reject(new Error('failure')));
31
- const answerService = getAnswerServiceInstance(
32
- session,
33
- query,
34
- 'GetChartWithData',
35
- thoughtSpotHost,
36
- );
37
- const answerData = await answerService.fetchData(1, 500);
38
- expect(answerData).toBeInstanceOf(Error);
39
- expect(fetch).toHaveBeenCalledTimes(1);
40
- });
41
- });
@@ -1,63 +0,0 @@
1
- import { SessionInterface, OperationType } from '../types';
2
-
3
- /**
4
- *
5
- * @param session
6
- * @param query
7
- * @param operation
8
- * @param thoughtSpotHost
9
- */
10
- export function getAnswerServiceInstance(
11
- session: SessionInterface,
12
- query: string,
13
- operation: string,
14
- thoughtSpotHost: string,
15
- ): any {
16
- let variable: any;
17
-
18
- const fetchQuery = async (variables: any) => {
19
- try {
20
- const response = await fetch(`${thoughtSpotHost}/prism/?op=${operation}`, {
21
- method: 'POST',
22
- headers: {
23
- 'content-type': 'application/json;charset=UTF-8',
24
- 'x-requested-by': 'ThoughtSpot',
25
- accept: '*/*',
26
- 'accept-language': 'en-us',
27
- },
28
- body: JSON.stringify({
29
- operationName: operation,
30
- query,
31
- variables,
32
- }),
33
- credentials: 'include',
34
- });
35
- const result = await response.json();
36
- return result.data;
37
- } catch (error) {
38
- return error;
39
- }
40
- };
41
-
42
- const fetchData = (offset: number, batchSize: number) => {
43
- if (operation === OperationType.GetChartWithData) {
44
- variable = { batchSize, offset: offset * batchSize };
45
- } else {
46
- variable = {
47
- dataPaginationParams: {
48
- isClientPaginated: true,
49
- offset: offset * batchSize,
50
- size: batchSize,
51
- },
52
- };
53
- }
54
- return fetchQuery({
55
- session,
56
- ...variable,
57
- });
58
- };
59
-
60
- return {
61
- fetchData,
62
- };
63
- }