@thoughtspot/visual-embed-sdk 1.48.0 → 1.49.1
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.
- package/cjs/package.json +1 -1
- package/cjs/src/css-variables.d.ts +140 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +62 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +57 -6
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +191 -1
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.js +7 -2
- package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.spec.js +385 -6
- package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts +1 -0
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +13 -1
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/base.spec.js +21 -0
- package/cjs/src/embed/base.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +86 -0
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +16 -1
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +5 -1
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +26 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +47 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +47 -6
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +129 -1
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.d.ts +85 -0
- package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -0
- package/cjs/src/embed/spotter-viz-utils.js +17 -0
- package/cjs/src/embed/spotter-viz-utils.js.map +1 -0
- package/cjs/src/embed/spotter-viz-utils.spec.d.ts +2 -0
- package/cjs/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js +31 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -0
- package/cjs/src/embed/ts-embed.d.ts +58 -38
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +247 -151
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +369 -123
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +2 -1
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.js +2 -2
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +3 -0
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/types.d.ts +267 -27
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +223 -19
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js +6 -7
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
- package/cjs/src/utils/logger.js +2 -1
- package/cjs/src/utils/logger.js.map +1 -1
- package/cjs/src/utils/logger.spec.d.ts +1 -0
- package/cjs/src/utils/logger.spec.d.ts.map +1 -1
- package/cjs/src/utils/logger.spec.js +10 -9
- package/cjs/src/utils/logger.spec.js.map +1 -1
- package/cjs/src/utils/sdk-version.d.ts +2 -0
- package/cjs/src/utils/sdk-version.d.ts.map +1 -0
- package/cjs/src/utils/sdk-version.js +7 -0
- package/cjs/src/utils/sdk-version.js.map +1 -0
- package/cjs/src/utils.d.ts +4 -1
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +107 -10
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +163 -4
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-Ck-r09gt.js → index-B6Rn561t.js} +1 -1
- package/dist/src/css-variables.d.ts +140 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +62 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +1 -0
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +16 -1
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +47 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-viz-utils.d.ts +85 -0
- package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -0
- package/dist/src/embed/spotter-viz-utils.spec.d.ts +2 -0
- package/dist/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
- package/dist/src/embed/ts-embed.d.ts +58 -38
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +267 -27
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/logger.spec.d.ts +1 -0
- package/dist/src/utils/logger.spec.d.ts.map +1 -1
- package/dist/src/utils/sdk-version.d.ts +2 -0
- package/dist/src/utils/sdk-version.d.ts.map +1 -0
- package/dist/src/utils.d.ts +4 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +3710 -3226
- package/dist/tsembed-react.js +3360 -2876
- package/dist/tsembed.es.js +3715 -3229
- package/dist/tsembed.js +3710 -3224
- package/dist/visual-embed-sdk-react-full.d.ts +643 -63
- package/dist/visual-embed-sdk-react.d.ts +643 -63
- package/dist/visual-embed-sdk.d.ts +658 -65
- package/lib/package.json +1 -1
- package/lib/src/css-variables.d.ts +140 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +62 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +58 -7
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +192 -2
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/auto-frame-renderer.js +7 -2
- package/lib/src/embed/auto-frame-renderer.js.map +1 -1
- package/lib/src/embed/auto-frame-renderer.spec.js +387 -8
- package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -0
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +11 -0
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +22 -1
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +86 -0
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +16 -1
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +5 -1
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +27 -1
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +47 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +48 -7
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +129 -1
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.d.ts +85 -0
- package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -0
- package/lib/src/embed/spotter-viz-utils.js +13 -0
- package/lib/src/embed/spotter-viz-utils.js.map +1 -0
- package/lib/src/embed/spotter-viz-utils.spec.d.ts +2 -0
- package/lib/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
- package/lib/src/embed/spotter-viz-utils.spec.js +29 -0
- package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -0
- package/lib/src/embed/ts-embed.d.ts +58 -38
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +249 -153
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +369 -123
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +2 -1
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.js +1 -1
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +3 -0
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/types.d.ts +267 -27
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +223 -19
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.spec.js +6 -7
- package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
- package/lib/src/utils/logger.js +2 -1
- package/lib/src/utils/logger.js.map +1 -1
- package/lib/src/utils/logger.spec.d.ts +1 -0
- package/lib/src/utils/logger.spec.d.ts.map +1 -1
- package/lib/src/utils/logger.spec.js +10 -9
- package/lib/src/utils/logger.spec.js.map +1 -1
- package/lib/src/utils/sdk-version.d.ts +2 -0
- package/lib/src/utils/sdk-version.d.ts.map +1 -0
- package/lib/src/utils/sdk-version.js +3 -0
- package/lib/src/utils/sdk-version.js.map +1 -0
- package/lib/src/utils.d.ts +4 -1
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +103 -9
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +164 -5
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +658 -65
- package/package.json +1 -1
- package/src/css-variables.ts +175 -1
- package/src/embed/app.spec.ts +247 -3
- package/src/embed/app.ts +125 -5
- package/src/embed/auto-frame-renderer.spec.ts +457 -58
- package/src/embed/auto-frame-renderer.ts +7 -2
- package/src/embed/base.spec.ts +25 -1
- package/src/embed/base.ts +19 -5
- package/src/embed/bodyless-conversation.spec.ts +93 -0
- package/src/embed/conversation.spec.ts +34 -0
- package/src/embed/conversation.ts +22 -1
- package/src/embed/liveboard.spec.ts +149 -1
- package/src/embed/liveboard.ts +102 -6
- package/src/embed/spotter-viz-utils.spec.ts +30 -0
- package/src/embed/spotter-viz-utils.ts +94 -0
- package/src/embed/ts-embed.spec.ts +532 -234
- package/src/embed/ts-embed.ts +384 -258
- package/src/index.ts +3 -0
- package/src/mixpanel-service.ts +1 -1
- package/src/react/index.tsx +3 -0
- package/src/types.ts +284 -23
- package/src/utils/authService/tokenizedAuthService.spec.ts +6 -6
- package/src/utils/logger.spec.ts +11 -9
- package/src/utils/logger.ts +2 -2
- package/src/utils/sdk-version.ts +3 -0
- package/src/utils.spec.ts +200 -4
- package/src/utils.ts +128 -9
package/src/index.ts
CHANGED
|
@@ -33,6 +33,7 @@ import { SearchEmbed, SearchViewConfig } from './embed/search';
|
|
|
33
33
|
import { SearchBarEmbed, SearchBarViewConfig } from './embed/search-bar';
|
|
34
34
|
import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig, BodylessConversation, BodylessConversationViewConfig} from './embed/bodyless-conversation';
|
|
35
35
|
import { SpotterEmbed, SpotterEmbedViewConfig, SpotterChatViewConfig, SpotterSidebarViewConfig, ConversationEmbed, ConversationViewConfig } from './embed/conversation';
|
|
36
|
+
import { SpotterVizConfig, SpotterVizStarterPrompt } from './embed/spotter-viz-utils';
|
|
36
37
|
import {
|
|
37
38
|
AuthFailureType, AuthStatus, AuthEvent, AuthEventEmitter,
|
|
38
39
|
} from './auth';
|
|
@@ -140,6 +141,8 @@ export {
|
|
|
140
141
|
SearchViewConfig,
|
|
141
142
|
SearchBarViewConfig,
|
|
142
143
|
LiveboardViewConfig,
|
|
144
|
+
SpotterVizConfig,
|
|
145
|
+
SpotterVizStarterPrompt,
|
|
143
146
|
AppViewConfig,
|
|
144
147
|
PrefetchFeatures,
|
|
145
148
|
FrameParams,
|
package/src/mixpanel-service.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as mixpanel from 'mixpanel-browser';
|
|
|
2
2
|
import { logger } from './utils/logger';
|
|
3
3
|
import { SessionInfo } from './utils/sessionInfoService';
|
|
4
4
|
import { ERROR_MESSAGE } from './errors';
|
|
5
|
-
import { version } from '
|
|
5
|
+
import { version } from './utils/sdk-version';
|
|
6
6
|
|
|
7
7
|
export const EndPoints = {
|
|
8
8
|
CONFIG: '/callosum/v1/system/config',
|
package/src/react/index.tsx
CHANGED
|
@@ -95,6 +95,9 @@ const componentFactory = <T extends typeof TsEmbed, U extends EmbedProps, V exte
|
|
|
95
95
|
|
|
96
96
|
const preRenderStyles = isPreRenderedComponent ? { display: 'none' } : {};
|
|
97
97
|
|
|
98
|
+
// We dont add any component for preRenderedComponent
|
|
99
|
+
if (isPreRenderedComponent) return <></>;
|
|
100
|
+
|
|
98
101
|
return viewConfig.insertAsSibling ? (
|
|
99
102
|
<span data-testid="tsEmbed" ref={ref} style={{ position: 'absolute', ...preRenderStyles }}></span>
|
|
100
103
|
) : (
|
package/src/types.ts
CHANGED
|
@@ -1140,6 +1140,14 @@ export interface BaseViewConfig extends ApiInterceptFlags {
|
|
|
1140
1140
|
* This flag can be used to disable links inside the embedded app,
|
|
1141
1141
|
* and disable redirection of links in a new tab.
|
|
1142
1142
|
*
|
|
1143
|
+
* Note: When set to `true`, this flag automatically disables
|
|
1144
|
+
* {@link enableLinkOverridesV2} for the
|
|
1145
|
+
* embed session. The two features are mutually exclusive — link
|
|
1146
|
+
* overrides mutate anchors (delete `href`, attach a JS click handler),
|
|
1147
|
+
* which breaks native browser behavior (Cmd/Ctrl+Click, middle-click,
|
|
1148
|
+
* right-click "Open in new tab") when combined with the disable flag.
|
|
1149
|
+
* The disable flag preserves native anchor semantics instead.
|
|
1150
|
+
*
|
|
1143
1151
|
* Supported embed types: `AppEmbed`, `LiveboardEmbed`, `SearchEmbed`, `SpotterAgentEmbed`, `SpotterEmbed`, `SearchBarEmbed`
|
|
1144
1152
|
* @version SDK: 1.32.1 | ThoughtSpot: 10.3.0.cl
|
|
1145
1153
|
* @example
|
|
@@ -1175,8 +1183,13 @@ export interface BaseViewConfig extends ApiInterceptFlags {
|
|
|
1175
1183
|
* Flag to override the *Open Link in New Tab* context
|
|
1176
1184
|
* menu option.
|
|
1177
1185
|
*
|
|
1178
|
-
*
|
|
1179
|
-
* {@link enableLinkOverridesV2}
|
|
1186
|
+
* Note: Setting this flag implicitly enables
|
|
1187
|
+
* {@link enableLinkOverridesV2}. V1 is auto-upgraded to
|
|
1188
|
+
* V2 to ensure consistent link-override behavior; the
|
|
1189
|
+
* legacy V1-only path is no longer used in isolation.
|
|
1190
|
+
*
|
|
1191
|
+
* Note: This flag is ignored when
|
|
1192
|
+
* {@link disableRedirectionLinksInNewTab} is `true`.
|
|
1180
1193
|
*
|
|
1181
1194
|
* Supported embed types: `AppEmbed`, `LiveboardEmbed`,
|
|
1182
1195
|
* `SearchEmbed`, `SpotterAgentEmbed`,
|
|
@@ -1202,6 +1215,9 @@ export interface BaseViewConfig extends ApiInterceptFlags {
|
|
|
1202
1215
|
* alongside this flag for backward compatibility with
|
|
1203
1216
|
* older ThoughtSpot versions.
|
|
1204
1217
|
*
|
|
1218
|
+
* Note: This flag is ignored when
|
|
1219
|
+
* {@link disableRedirectionLinksInNewTab} is `true`.
|
|
1220
|
+
*
|
|
1205
1221
|
* Supported embed types: `AppEmbed`, `LiveboardEmbed`,
|
|
1206
1222
|
* `SearchEmbed`, `SpotterAgentEmbed`,
|
|
1207
1223
|
* `SpotterEmbed`, `SearchBarEmbed`
|
|
@@ -1477,8 +1493,29 @@ export interface BaseViewConfig extends ApiInterceptFlags {
|
|
|
1477
1493
|
useHostEventsV2?: boolean;
|
|
1478
1494
|
}
|
|
1479
1495
|
|
|
1480
|
-
|
|
1481
|
-
|
|
1496
|
+
/**
|
|
1497
|
+
* Configuration for {@link startAutoMCPFrameRenderer}.
|
|
1498
|
+
*
|
|
1499
|
+
* Extends {@link BaseViewConfig} but omits params that are not applicable
|
|
1500
|
+
* to the auto-frame renderer:
|
|
1501
|
+
* - `preRenderId` / `usePrerenderedIfAvailable` / `doNotTrackPreRenderSize` —
|
|
1502
|
+
* the renderer always replaces a live iframe in-place; prerender pools are not used.
|
|
1503
|
+
* - `insertAsSibling` — insertion is always a same-position `replaceWith`; the
|
|
1504
|
+
* container-append path is never taken.
|
|
1505
|
+
* - `primaryAction` — a Liveboard/AppEmbed-specific feature; the renderer renders
|
|
1506
|
+
* whatever route the MCP server specifies.
|
|
1507
|
+
* - `enableV2Shell_experimental` — the renderer always uses the v2 URL format;
|
|
1508
|
+
* this flag has no effect.
|
|
1509
|
+
*/
|
|
1510
|
+
export type AutoMCPFrameRendererViewConfig = Omit<
|
|
1511
|
+
BaseViewConfig,
|
|
1512
|
+
| 'preRenderId'
|
|
1513
|
+
| 'usePrerenderedIfAvailable'
|
|
1514
|
+
| 'doNotTrackPreRenderSize'
|
|
1515
|
+
| 'insertAsSibling'
|
|
1516
|
+
| 'primaryAction'
|
|
1517
|
+
| 'enableV2Shell_experimental'
|
|
1518
|
+
>;
|
|
1482
1519
|
|
|
1483
1520
|
/**
|
|
1484
1521
|
* The configuration object for Home page embeds configs.
|
|
@@ -2465,38 +2502,54 @@ export enum EmbedEvent {
|
|
|
2465
2502
|
*/
|
|
2466
2503
|
VizPointClick = 'vizPointClick',
|
|
2467
2504
|
/**
|
|
2468
|
-
*
|
|
2505
|
+
* Fired when an error occurs in the embedded component.
|
|
2506
|
+
*
|
|
2507
|
+
* **Important:** This event fires for many reasons — including internal
|
|
2508
|
+
* validation warnings (e.g. `HOST_EVENT_VALIDATION`), configuration issues,
|
|
2509
|
+
* and transient errors that ThoughtSpot already handles gracefully inside the
|
|
2510
|
+
* iframe. **Do not call `embed.destroy()` or unmount the embed component on
|
|
2511
|
+
* every error.** Doing so will tear down the iframe and abort all in-flight
|
|
2512
|
+
* requests, causing the embed to fail entirely.
|
|
2469
2513
|
*
|
|
2514
|
+
* Only treat the following codes as unrecoverable:
|
|
2515
|
+
* - `INIT_ERROR` — SDK was not initialised before render
|
|
2516
|
+
* - `LOGIN_FAILED` — authentication could not be completed
|
|
2517
|
+
*
|
|
2518
|
+
* All other error codes should be logged and inspected, not acted upon
|
|
2519
|
+
* destructively.
|
|
2520
|
+
*
|
|
2521
|
+
* **Note:** There is currently no dedicated event for a true unrecoverable
|
|
2522
|
+
* crash. A future `EmbedEvent.FatalError` event is planned to give customers
|
|
2523
|
+
* a clean signal for when the embed cannot recover and needs to be torn down.
|
|
2524
|
+
*
|
|
2525
|
+
* Error types include:
|
|
2470
2526
|
* `API` - API call failure.
|
|
2471
|
-
* `FULLSCREEN` - Error when presenting a Liveboard
|
|
2472
|
-
*
|
|
2473
|
-
* filter. `NON_EXIST_FILTER` - Error due to a non-existent filter.
|
|
2474
|
-
* `INVALID_DATE_VALUE` - Invalid date value error.
|
|
2475
|
-
* `INVALID_OPERATOR` - Use of invalid operator during filter application.
|
|
2527
|
+
* `FULLSCREEN` - Error when presenting a Liveboard in full screen mode.
|
|
2528
|
+
* `VALIDATION_ERROR` - Internal host event or configuration validation warning.
|
|
2476
2529
|
*
|
|
2477
2530
|
* For more information, see https://developers.thoughtspot.com/docs/events-app-integration#errorType
|
|
2478
2531
|
* @returns error - An error object or message
|
|
2479
2532
|
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
|
|
2480
2533
|
* @example
|
|
2481
2534
|
* ```js
|
|
2482
|
-
* //
|
|
2483
|
-
*
|
|
2484
|
-
*
|
|
2485
|
-
*
|
|
2486
|
-
*
|
|
2535
|
+
* // Recommended pattern — only destroy on truly fatal errors
|
|
2536
|
+
* embed.on(EmbedEvent.Error, (error) => {
|
|
2537
|
+
* const FATAL_CODES = ['INIT_ERROR', 'LOGIN_FAILED'];
|
|
2538
|
+
* if (FATAL_CODES.includes(error.data?.code)) {
|
|
2539
|
+
* embed.destroy();
|
|
2540
|
+
* return;
|
|
2541
|
+
* }
|
|
2542
|
+
* // Log all other errors — do not destroy
|
|
2543
|
+
* console.warn('Embed error (non-fatal):', error);
|
|
2487
2544
|
* });
|
|
2488
2545
|
* ```
|
|
2489
2546
|
* @example
|
|
2490
2547
|
* ```js
|
|
2491
|
-
* //
|
|
2492
|
-
*
|
|
2548
|
+
* // API error
|
|
2549
|
+
* SearchEmbed.on(EmbedEvent.Error, (error) => {
|
|
2493
2550
|
* console.log(error);
|
|
2494
|
-
* // {
|
|
2495
|
-
*
|
|
2496
|
-
* // stack: "..."
|
|
2497
|
-
* // } }}
|
|
2498
|
-
* // { errorType: "FULLSCREEN", message: "Fullscreen API is not enabled", code: '...' } new format
|
|
2499
|
-
* })
|
|
2551
|
+
* // { errorType: "API", message: '...', code: '...' }
|
|
2552
|
+
* });
|
|
2500
2553
|
* ```
|
|
2501
2554
|
*/
|
|
2502
2555
|
Error = 'Error',
|
|
@@ -3704,6 +3757,109 @@ export enum EmbedEvent {
|
|
|
3704
3757
|
* @version SDK: 1.48.0 | ThoughtSpot Cloud: 26.5.0.cl
|
|
3705
3758
|
*/
|
|
3706
3759
|
SendTestScheduleEmail = 'sendTestScheduleEmail',
|
|
3760
|
+
|
|
3761
|
+
/**
|
|
3762
|
+
* Emitted when the SpotterViz panel mounts in embed mode.
|
|
3763
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3764
|
+
* @example
|
|
3765
|
+
* ```js
|
|
3766
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizInit, (payload) => {
|
|
3767
|
+
* console.log('SpotterViz initialized', payload);
|
|
3768
|
+
* // payload: { liveboardId: string }
|
|
3769
|
+
* })
|
|
3770
|
+
* ```
|
|
3771
|
+
*/
|
|
3772
|
+
SpotterVizInit = 'SpotterVizInit',
|
|
3773
|
+
|
|
3774
|
+
/**
|
|
3775
|
+
* Emitted when the user submits a prompt in the SpotterViz panel.
|
|
3776
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3777
|
+
* @example
|
|
3778
|
+
* ```js
|
|
3779
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizQueryTriggered, (payload) => {
|
|
3780
|
+
* console.log('SpotterViz query triggered', payload);
|
|
3781
|
+
* // payload: { query: string, sessionId: string }
|
|
3782
|
+
* })
|
|
3783
|
+
* ```
|
|
3784
|
+
*/
|
|
3785
|
+
SpotterVizQueryTriggered = 'SpotterVizQueryTriggered',
|
|
3786
|
+
|
|
3787
|
+
/**
|
|
3788
|
+
* Emitted when the SpotterViz agent finishes responding.
|
|
3789
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3790
|
+
* @example
|
|
3791
|
+
* ```js
|
|
3792
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizResponseComplete, (payload) => {
|
|
3793
|
+
* console.log('SpotterViz response complete', payload);
|
|
3794
|
+
* // payload: { sessionId: string, messageId: string }
|
|
3795
|
+
* })
|
|
3796
|
+
* ```
|
|
3797
|
+
*/
|
|
3798
|
+
SpotterVizResponseComplete = 'SpotterVizResponseComplete',
|
|
3799
|
+
|
|
3800
|
+
/**
|
|
3801
|
+
* Emitted when a checkpoint is created in the SpotterViz panel.
|
|
3802
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3803
|
+
* @example
|
|
3804
|
+
* ```js
|
|
3805
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizCheckpointCreated, (payload) => {
|
|
3806
|
+
* console.log('SpotterViz checkpoint created', payload);
|
|
3807
|
+
* // payload: { checkpointId: string, source: string, label: string }
|
|
3808
|
+
* })
|
|
3809
|
+
* ```
|
|
3810
|
+
*/
|
|
3811
|
+
SpotterVizCheckpointCreated = 'SpotterVizCheckpointCreated',
|
|
3812
|
+
|
|
3813
|
+
/**
|
|
3814
|
+
* Emitted when a checkpoint is restored in the SpotterViz panel.
|
|
3815
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3816
|
+
* @example
|
|
3817
|
+
* ```js
|
|
3818
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizCheckpointRestored, (payload) => {
|
|
3819
|
+
* console.log('SpotterViz checkpoint restored', payload);
|
|
3820
|
+
* // payload: { checkpointId: string, newGenNumber: number }
|
|
3821
|
+
* })
|
|
3822
|
+
* ```
|
|
3823
|
+
*/
|
|
3824
|
+
SpotterVizCheckpointRestored = 'SpotterVizCheckpointRestored',
|
|
3825
|
+
|
|
3826
|
+
/**
|
|
3827
|
+
* Emitted when an error occurs in the SpotterViz panel.
|
|
3828
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3829
|
+
* @example
|
|
3830
|
+
* ```js
|
|
3831
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizError, (payload) => {
|
|
3832
|
+
* console.log('SpotterViz error', payload);
|
|
3833
|
+
* })
|
|
3834
|
+
* ```
|
|
3835
|
+
*/
|
|
3836
|
+
SpotterVizError = 'SpotterVizError',
|
|
3837
|
+
|
|
3838
|
+
/**
|
|
3839
|
+
* Emitted when the SpotterViz panel is closed.
|
|
3840
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
3841
|
+
* @example
|
|
3842
|
+
* ```js
|
|
3843
|
+
* liveboardEmbed.on(EmbedEvent.SpotterVizClosed, (payload) => {
|
|
3844
|
+
* console.log('SpotterViz panel closed', payload);
|
|
3845
|
+
* })
|
|
3846
|
+
* ```
|
|
3847
|
+
*/
|
|
3848
|
+
SpotterVizClosed = 'SpotterVizClosed',
|
|
3849
|
+
/**
|
|
3850
|
+
* Emitted when a user clicks the **Refresh** button in the
|
|
3851
|
+
* Liveboard header. Requires `enableLiveboardDataCache`
|
|
3852
|
+
* to be enabled.
|
|
3853
|
+
* @example
|
|
3854
|
+
* ```js
|
|
3855
|
+
* liveboardEmbed.on(EmbedEvent.RefreshLiveboardBrowserCache, (payload) => {
|
|
3856
|
+
* console.log('Liveboard browser cache refreshed', payload);
|
|
3857
|
+
* // payload: { liveboardId: string }
|
|
3858
|
+
* })
|
|
3859
|
+
* ```
|
|
3860
|
+
* @version SDK: 1.49.0 | ThoughtSpot Cloud: 26.6.0.cl
|
|
3861
|
+
*/
|
|
3862
|
+
RefreshLiveboardBrowserCache = 'refreshLiveboardBrowserCache',
|
|
3707
3863
|
}
|
|
3708
3864
|
|
|
3709
3865
|
/**
|
|
@@ -5779,6 +5935,39 @@ export enum HostEvent {
|
|
|
5779
5935
|
* @version SDK: 1.48.0 | ThoughtSpot Cloud: 26.5.0.cl
|
|
5780
5936
|
*/
|
|
5781
5937
|
SendTestScheduleEmail = 'sendTestScheduleEmail',
|
|
5938
|
+
|
|
5939
|
+
/**
|
|
5940
|
+
* Sends a user message (prompt) to the SpotterViz panel programmatically.
|
|
5941
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
5942
|
+
* @param query - the prompt text to send.
|
|
5943
|
+
* @example
|
|
5944
|
+
* ```js
|
|
5945
|
+
* liveboardEmbed.trigger(HostEvent.SpotterVizSendUserMessage, {
|
|
5946
|
+
* query: 'Show me revenue by region',
|
|
5947
|
+
* });
|
|
5948
|
+
* ```
|
|
5949
|
+
*/
|
|
5950
|
+
SpotterVizSendUserMessage = 'SpotterVizSendUserMessage',
|
|
5951
|
+
|
|
5952
|
+
/**
|
|
5953
|
+
* Initializes a new SpotterViz conversation.
|
|
5954
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
5955
|
+
* @example
|
|
5956
|
+
* ```js
|
|
5957
|
+
* liveboardEmbed.trigger(HostEvent.InitSpotterVizConversation);
|
|
5958
|
+
* ```
|
|
5959
|
+
*/
|
|
5960
|
+
InitSpotterVizConversation = 'InitSpotterVizConversation',
|
|
5961
|
+
/**
|
|
5962
|
+
* Clears browser cache and fetches new data for liveboard ChartViz Containers.
|
|
5963
|
+
* Requires `enableLiveboardDataCache` to be enabled.
|
|
5964
|
+
* @example
|
|
5965
|
+
* ```js
|
|
5966
|
+
* liveboardEmbed.trigger(HostEvent.RefreshLiveboardBrowserCache);
|
|
5967
|
+
* ```
|
|
5968
|
+
* @version SDK: 1.49.0 | ThoughtSpot Cloud: 26.6.0.cl
|
|
5969
|
+
*/
|
|
5970
|
+
RefreshLiveboardBrowserCache = 'refreshLiveboardBrowserCache',
|
|
5782
5971
|
}
|
|
5783
5972
|
|
|
5784
5973
|
/**
|
|
@@ -5821,6 +6010,7 @@ export enum Param {
|
|
|
5821
6010
|
HostAppUrl = 'hostAppUrl',
|
|
5822
6011
|
EnableVizTransformations = 'enableVizTransform',
|
|
5823
6012
|
EnableSearchAssist = 'enableSearchAssist',
|
|
6013
|
+
EnableConnectionNewExperience = 'newConnectionsExperience',
|
|
5824
6014
|
EnablePendoHelp = 'enablePendoHelp',
|
|
5825
6015
|
HideResult = 'hideResult',
|
|
5826
6016
|
UseLastSelectedDataSource = 'useLastSelectedSources',
|
|
@@ -5957,8 +6147,18 @@ export enum Param {
|
|
|
5957
6147
|
ToolResponseCardBrandingLabel = 'toolResponseCardBrandingLabel',
|
|
5958
6148
|
EnableHomepageAnnouncement = 'enableHomepageAnnouncement',
|
|
5959
6149
|
EnableLiveboardDataCache = 'enableLiveboardDataCache',
|
|
6150
|
+
SpotterFileUploadEnabled = 'spotterFileUploadEnabled',
|
|
6151
|
+
SpotterFileUploadFileTypes = 'spotterFileUploadFileTypes',
|
|
5960
6152
|
}
|
|
5961
6153
|
|
|
6154
|
+
/**
|
|
6155
|
+
* Configuration for allowed file types in Spotter file upload.
|
|
6156
|
+
* @group Embed components
|
|
6157
|
+
*/
|
|
6158
|
+
export type SpotterFileUploadFileTypes = {
|
|
6159
|
+
types?: string[];
|
|
6160
|
+
};
|
|
6161
|
+
|
|
5962
6162
|
/**
|
|
5963
6163
|
* ThoughtSpot application pages include actions and menu commands
|
|
5964
6164
|
* for various user-initiated operations. These actions are represented
|
|
@@ -6296,6 +6496,20 @@ export enum Action {
|
|
|
6296
6496
|
* @version SDK: 1.48.0 | ThoughtSpot: 26.5.0.cl
|
|
6297
6497
|
*/
|
|
6298
6498
|
DownloadLiveboardAsContinuousPDF = 'downloadLiveboardAsContinuousPDF',
|
|
6499
|
+
/**
|
|
6500
|
+
* The Download Liveboard as A4 PDF menu action on a Liveboard.
|
|
6501
|
+
* Allows downloading the entire Liveboard as an A4 PDF.
|
|
6502
|
+
* Requires {@link Action.DownloadLiveboard} as a parent action when
|
|
6503
|
+
* {@link LiveboardViewConfig.isLiveboardXLSXCSVDownloadEnabled} or
|
|
6504
|
+
* {@link LiveboardViewConfig.isContinuousLiveboardPDFEnabled} flags are enabled.
|
|
6505
|
+
* Use this instead of {@link Action.DownloadAsPdf} when either flag is on.
|
|
6506
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
6507
|
+
* @example
|
|
6508
|
+
* ```js
|
|
6509
|
+
* disabledActions: [Action.DownloadLiveboardAsA4Pdf]
|
|
6510
|
+
* ```
|
|
6511
|
+
*/
|
|
6512
|
+
DownloadLiveboardAsA4Pdf = 'downloadLiveboardAsA4Pdf',
|
|
6299
6513
|
/**
|
|
6300
6514
|
* The **Download Liveboard as XLSX** menu action on a Liveboard.
|
|
6301
6515
|
* Allows downloading the entire Liveboard as an XLSX file.
|
|
@@ -7629,6 +7843,53 @@ export enum Action {
|
|
|
7629
7843
|
* @version SDK: 1.48.0 | ThoughtSpot Cloud: 26.5.0.cl
|
|
7630
7844
|
*/
|
|
7631
7845
|
SendTestScheduleEmail = 'sendTestScheduleEmail',
|
|
7846
|
+
|
|
7847
|
+
/**
|
|
7848
|
+
* The thumbs up/down feedback buttons in the SpotterViz panel.
|
|
7849
|
+
* Visible by default.
|
|
7850
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
7851
|
+
* @example
|
|
7852
|
+
* ```js
|
|
7853
|
+
* hiddenActions: [Action.SpotterVizFeedback]
|
|
7854
|
+
* disabledActions: [Action.SpotterVizFeedback]
|
|
7855
|
+
* ```
|
|
7856
|
+
*/
|
|
7857
|
+
SpotterVizFeedback = 'spotterVizFeedback',
|
|
7858
|
+
|
|
7859
|
+
/**
|
|
7860
|
+
* The version restore button on checkpoint cards in the SpotterViz panel.
|
|
7861
|
+
* Visible by default.
|
|
7862
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
7863
|
+
* @example
|
|
7864
|
+
* ```js
|
|
7865
|
+
* hiddenActions: [Action.SpotterVizCheckpointRestore]
|
|
7866
|
+
* disabledActions: [Action.SpotterVizCheckpointRestore]
|
|
7867
|
+
* ```
|
|
7868
|
+
*/
|
|
7869
|
+
SpotterVizCheckpointRestore = 'spotterVizCheckpointRestore',
|
|
7870
|
+
|
|
7871
|
+
/**
|
|
7872
|
+
* The **SpotterViz** button in the top edit header.
|
|
7873
|
+
* Visible by default.
|
|
7874
|
+
* @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
|
|
7875
|
+
* @example
|
|
7876
|
+
* ```js
|
|
7877
|
+
* hiddenActions: [Action.SpotterViz]
|
|
7878
|
+
* disabledActions: [Action.SpotterViz]
|
|
7879
|
+
* ```
|
|
7880
|
+
*/
|
|
7881
|
+
SpotterViz = 'spotterViz',
|
|
7882
|
+
/**
|
|
7883
|
+
* Clears browser cache and fetches new data for liveboard ChartViz Containers.
|
|
7884
|
+
* Requires `enableLiveboardDataCache` to be enabled.
|
|
7885
|
+
* @example
|
|
7886
|
+
* ```js
|
|
7887
|
+
* disabledActions: [Action.RefreshLiveboardBrowserCache]
|
|
7888
|
+
* hiddenActions: [Action.RefreshLiveboardBrowserCache]
|
|
7889
|
+
* ```
|
|
7890
|
+
* @version SDK: 1.49.0 | ThoughtSpot Cloud: 26.6.0.cl
|
|
7891
|
+
*/
|
|
7892
|
+
RefreshLiveboardBrowserCache = 'refreshLiveboardBrowserCache',
|
|
7632
7893
|
}
|
|
7633
7894
|
export interface AnswerServiceType {
|
|
7634
7895
|
getAnswer?: (offset: number, batchSize: number) => any;
|
|
@@ -79,8 +79,9 @@ describe('fetchPreauthInfoService', () => {
|
|
|
79
79
|
});
|
|
80
80
|
it('fetchPreauthInfoService if fetch fails', async () => {
|
|
81
81
|
const mockFetch = jest.spyOn(tokenizedFetchModule, 'tokenizedFetch');
|
|
82
|
+
// Prevent logger.error from reaching console.error (which throws in test env)
|
|
83
|
+
jest.spyOn(logger, 'error').mockImplementation(() => {});
|
|
82
84
|
|
|
83
|
-
// Mock for fetchPreauthInfoService
|
|
84
85
|
mockFetch.mockResolvedValueOnce({
|
|
85
86
|
ok: false,
|
|
86
87
|
status: 500,
|
|
@@ -89,11 +90,10 @@ describe('fetchPreauthInfoService', () => {
|
|
|
89
90
|
text: jest.fn().mockResolvedValue('Internal Server Error'),
|
|
90
91
|
} as any);
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
93
|
+
const response = await fetchPreauthInfoService(thoughtspotHost);
|
|
94
|
+
expect(response.ok).toBe(false);
|
|
95
|
+
expect(response.status).toBe(500);
|
|
96
|
+
expect(logger.error).toHaveBeenCalled();
|
|
97
97
|
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
98
98
|
expect(mockFetch).toHaveBeenCalledWith(`${thoughtspotHost}${EndPoints.PREAUTH_INFO}`, {});
|
|
99
99
|
});
|
package/src/utils/logger.spec.ts
CHANGED
|
@@ -8,6 +8,8 @@ const consoleInfoSpy = jest.spyOn(console, 'info');
|
|
|
8
8
|
const consoleDebugSpy = jest.spyOn(console, 'debug');
|
|
9
9
|
const consoleTraceSpy = jest.spyOn(console, 'trace');
|
|
10
10
|
|
|
11
|
+
const versionPrefix = expect.stringMatching(/^\[vesdk-/);
|
|
12
|
+
|
|
11
13
|
describe('Logger', () => {
|
|
12
14
|
beforeAll(async () => {
|
|
13
15
|
const a = await import('./logger');
|
|
@@ -52,7 +54,7 @@ describe('Logger', () => {
|
|
|
52
54
|
logger.error('Error message');
|
|
53
55
|
logger.warn('Warning message');
|
|
54
56
|
logger.debug('Debug message');
|
|
55
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Error message');
|
|
57
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(versionPrefix, 'Error message');
|
|
56
58
|
expect(consoleWarnSpy).not.toHaveBeenCalled();
|
|
57
59
|
expect(consoleDebugSpy).not.toHaveBeenCalled();
|
|
58
60
|
|
|
@@ -65,17 +67,17 @@ describe('Logger', () => {
|
|
|
65
67
|
logger.error('Warning message');
|
|
66
68
|
logger.warn('Warning message');
|
|
67
69
|
logger.debug('Debug message');
|
|
68
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Warning message');
|
|
69
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith('Warning message');
|
|
70
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(versionPrefix, 'Warning message');
|
|
71
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(versionPrefix, 'Warning message');
|
|
70
72
|
expect(consoleDebugSpy).not.toHaveBeenCalled();
|
|
71
73
|
|
|
72
74
|
logger.setLogLevel(LogLevel.DEBUG);
|
|
73
75
|
logger.error('Warning message');
|
|
74
76
|
logger.warn('Warning message');
|
|
75
77
|
logger.debug('Debug message');
|
|
76
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Warning message');
|
|
77
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith('Warning message');
|
|
78
|
-
expect(consoleDebugSpy).toHaveBeenCalledWith('Debug message');
|
|
78
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(versionPrefix, 'Warning message');
|
|
79
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(versionPrefix, 'Warning message');
|
|
80
|
+
expect(consoleDebugSpy).toHaveBeenCalledWith(versionPrefix, 'Debug message');
|
|
79
81
|
});
|
|
80
82
|
|
|
81
83
|
it('should log messages with the global log level override', () => {
|
|
@@ -85,8 +87,8 @@ describe('Logger', () => {
|
|
|
85
87
|
logger.warn('Warn message');
|
|
86
88
|
logger.info('Info message');
|
|
87
89
|
logger.trace('Trace message');
|
|
88
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Error message');
|
|
89
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith('Warn message');
|
|
90
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(versionPrefix, 'Error message');
|
|
91
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(versionPrefix, 'Warn message');
|
|
90
92
|
expect(consoleInfoSpy).not.toHaveBeenCalled();
|
|
91
93
|
expect(consoleDebugSpy).not.toHaveBeenCalled();
|
|
92
94
|
expect(consoleTraceSpy).not.toHaveBeenCalled();
|
|
@@ -99,7 +101,7 @@ describe('Logger', () => {
|
|
|
99
101
|
logger.warn('Warn message');
|
|
100
102
|
logger.info('Info message');
|
|
101
103
|
logger.trace('Trace message');
|
|
102
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Error message');
|
|
104
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(versionPrefix, 'Error message');
|
|
103
105
|
expect(consoleWarnSpy).not.toHaveBeenCalled();
|
|
104
106
|
expect(consoleInfoSpy).not.toHaveBeenCalled();
|
|
105
107
|
expect(consoleDebugSpy).not.toHaveBeenCalled();
|
package/src/utils/logger.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LogLevel } from '../types';
|
|
2
|
-
|
|
2
|
+
import { version } from './sdk-version';
|
|
3
3
|
const logFunctions: {
|
|
4
4
|
[key: string]: (...args: any[]) => void;
|
|
5
5
|
} = {
|
|
@@ -51,7 +51,7 @@ class Logger {
|
|
|
51
51
|
if (this.canLog(logLevel)) {
|
|
52
52
|
const logFn = logFunctions[logLevel];
|
|
53
53
|
if (logFn) {
|
|
54
|
-
logFn(...args);
|
|
54
|
+
logFn(`[vesdk-${version}]` , ...args);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|