@thoughtspot/visual-embed-sdk 1.17.0-alpha.0 → 1.17.0-alpha.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.
- package/dist/src/embed/base.d.ts +1 -1
- package/dist/src/embed/ts-embed.d.ts +2 -8
- package/dist/src/test/test-utils.d.ts +4 -0
- package/dist/src/types.d.ts +105 -10
- package/dist/src/utils.d.ts +7 -1
- package/dist/tsembed.es.js +1099 -17069
- package/dist/tsembed.js +1099 -17069
- package/lib/package.json +2 -2
- package/lib/src/auth.js +11 -6
- package/lib/src/auth.js.map +1 -1
- package/lib/src/auth.spec.js +11 -3
- package/lib/src/auth.spec.js.map +1 -1
- package/lib/src/embed/app.spec.js +2 -6
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -1
- package/lib/src/embed/base.js +24 -6
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +33 -0
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +3 -6
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/pinboard.spec.js +3 -6
- package/lib/src/embed/pinboard.spec.js.map +1 -1
- package/lib/src/embed/search.spec.js +1 -3
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +2 -8
- package/lib/src/embed/ts-embed.js +12 -18
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +23 -4
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/react/index.spec.js +2 -2
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/test/test-utils.d.ts +4 -0
- package/lib/src/test/test-utils.js +19 -1
- package/lib/src/test/test-utils.js.map +1 -1
- package/lib/src/types.d.ts +105 -10
- package/lib/src/types.js +89 -7
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils.d.ts +7 -1
- package/lib/src/utils.js +10 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +108 -13
- package/package.json +2 -2
- package/src/auth.spec.ts +11 -3
- package/src/auth.ts +20 -10
- package/src/embed/app.spec.ts +4 -4
- package/src/embed/base.spec.ts +38 -0
- package/src/embed/base.ts +33 -6
- package/src/embed/liveboard.spec.ts +4 -4
- package/src/embed/pinboard.spec.ts +4 -4
- package/src/embed/search.spec.ts +1 -1
- package/src/embed/ts-embed.spec.ts +27 -6
- package/src/embed/ts-embed.ts +16 -18
- package/src/react/index.spec.tsx +2 -2
- package/src/test/test-utils.ts +21 -2
- package/src/types.ts +103 -7
- package/src/utils.ts +12 -0
|
@@ -200,7 +200,7 @@ declare module '@thoughtspot/visual-embed-sdk/embed/base' {
|
|
|
200
200
|
* Renders functions in a queue, resolves to next function only after the callback next is called
|
|
201
201
|
* @param fn The function being registered
|
|
202
202
|
*/
|
|
203
|
-
export const renderInQueue: (fn: (next?: (val?: any) => void) =>
|
|
203
|
+
export const renderInQueue: (fn: (next?: (val?: any) => void) => Promise<any>) => Promise<any>;
|
|
204
204
|
export function reset(): void;
|
|
205
205
|
}
|
|
206
206
|
|
|
@@ -526,23 +526,52 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
526
526
|
* No authentication on the SDK. Passthrough to the embedded App. Alias for `Passthrough`.
|
|
527
527
|
*/
|
|
528
528
|
None = "None",
|
|
529
|
+
/**
|
|
530
|
+
* Passthrough SSO to the embedded App within the iframe. Requires least configuration, but may not
|
|
531
|
+
* be supported by all IDPs. This will behave like `None` if SSO is not configured on ThoughtSpot.
|
|
532
|
+
* @version: SDK: 1.15.0 | ThouhgtSpot: 8.8.0.cl
|
|
533
|
+
*/
|
|
534
|
+
EmbeddedSSO = "EmbeddedSSO",
|
|
529
535
|
/**
|
|
530
536
|
* SSO using SAML
|
|
531
|
-
* @deprecated Use {@link
|
|
537
|
+
* @deprecated Use {@link SAMLRedirect} instead
|
|
538
|
+
* @hidden
|
|
532
539
|
*/
|
|
533
540
|
SSO = "SSO_SAML",
|
|
534
541
|
/**
|
|
535
542
|
* SSO using SAML
|
|
543
|
+
* @deprecated Use {@link SAMLRedirect} instead
|
|
544
|
+
* @hidden
|
|
536
545
|
*/
|
|
537
546
|
SAML = "SSO_SAML",
|
|
547
|
+
/**
|
|
548
|
+
* SSO using SAML
|
|
549
|
+
* Will make the host application redirect to the SAML Idp.
|
|
550
|
+
*/
|
|
551
|
+
SAMLRedirect = "SSO_SAML",
|
|
538
552
|
/**
|
|
539
553
|
* SSO using OIDC
|
|
554
|
+
* @hidden
|
|
555
|
+
* @deprecated Use {@link OIDCRedirect} instead
|
|
540
556
|
*/
|
|
541
557
|
OIDC = "SSO_OIDC",
|
|
558
|
+
/**
|
|
559
|
+
* SSO using OIDC
|
|
560
|
+
* Will make the host application redirect to the OIDC Idp.
|
|
561
|
+
*/
|
|
562
|
+
OIDCRedirect = "SSO_OIDC",
|
|
542
563
|
/**
|
|
543
564
|
* Trusted authentication server
|
|
565
|
+
* @hidden
|
|
566
|
+
* @deprecated Use {@link TrustedAuth} instead
|
|
544
567
|
*/
|
|
545
568
|
AuthServer = "AuthServer",
|
|
569
|
+
/**
|
|
570
|
+
* Trusted authentication server, Use you own authentication server
|
|
571
|
+
* which returns a bearer token, generated using the secret_key obtained from
|
|
572
|
+
* ThoughtSpot.
|
|
573
|
+
*/
|
|
574
|
+
TrustedAuthToken = "AuthServer",
|
|
546
575
|
/**
|
|
547
576
|
* Use the ThoughtSpot login API to authenticate to the cluster directly.
|
|
548
577
|
*
|
|
@@ -709,6 +738,20 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
709
738
|
* @version SDK: 1.17.0 | ThoughtSpot: 8.9.0.cl
|
|
710
739
|
*/
|
|
711
740
|
customisations?: CustomisationsInterface;
|
|
741
|
+
/**
|
|
742
|
+
* For noRedirect SSO Auth, we need a button which the user
|
|
743
|
+
* click to trigger the flow. This is the containing element
|
|
744
|
+
* for that button.
|
|
745
|
+
*
|
|
746
|
+
* @version SDK: 1.17.0 | ThoughtSpot: *
|
|
747
|
+
*/
|
|
748
|
+
authTriggerContainer?: string | HTMLElement;
|
|
749
|
+
/**
|
|
750
|
+
* Text to show in the button which triggers the popup auth flow.
|
|
751
|
+
* Default: "Authorize".
|
|
752
|
+
* @version SDK: 1.17.0 | ThoughtSpot: *
|
|
753
|
+
*/
|
|
754
|
+
authTriggerText?: string;
|
|
712
755
|
}
|
|
713
756
|
/**
|
|
714
757
|
* MessagePayload: Embed event payload: message type, data and status (start/end)
|
|
@@ -1135,16 +1178,25 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1135
1178
|
export enum HostEvent {
|
|
1136
1179
|
/**
|
|
1137
1180
|
* Trigger a search
|
|
1138
|
-
* @param dataSourceIds - The list of data source GUIDs
|
|
1139
|
-
* @param searchQuery - The search query
|
|
1181
|
+
* @param - dataSourceIds - The list of data source GUIDs
|
|
1182
|
+
* @param - searchQuery - The search query
|
|
1183
|
+
* @example
|
|
1184
|
+
* searchEmbed.trigger(HostEvent.Search, {
|
|
1185
|
+
* searchQuery: "[sales] by [item type],
|
|
1186
|
+
* "dataSourceIds: ["cd252e5c-b552-49a8-821d-3eadaa049cca"]
|
|
1187
|
+
* })
|
|
1140
1188
|
*/
|
|
1141
1189
|
Search = "search",
|
|
1142
1190
|
/**
|
|
1143
1191
|
* Trigger a drill on certain points by certain column
|
|
1144
|
-
* @param points - an object containing selectedPoints/clickedPoints
|
|
1192
|
+
* @param - points - an object containing selectedPoints/clickedPoints
|
|
1145
1193
|
* eg. { selectedPoints: []}
|
|
1146
|
-
* @param columnGuid - a string guid of the column to drill by. This is optional,
|
|
1194
|
+
* @param - columnGuid - a string guid of the column to drill by. This is optional,
|
|
1147
1195
|
* if not provided it will auto drill by the configured column.
|
|
1196
|
+
* @example searchEmbed.trigger(HostEvent.DrillDown, {
|
|
1197
|
+
* points: clickedPointData,
|
|
1198
|
+
* autoDrillDown: true,
|
|
1199
|
+
* })
|
|
1148
1200
|
* @version SDK: 1.5.0 | ThoughtSpot: ts7.oct.cl, 7.2.1
|
|
1149
1201
|
*/
|
|
1150
1202
|
DrillDown = "triggerDrillDown",
|
|
@@ -1162,6 +1214,8 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1162
1214
|
* Set the visible visualizations on a Liveboard.
|
|
1163
1215
|
* @param - an array of ids of visualizations to show, the ids not passed
|
|
1164
1216
|
* will be hidden.
|
|
1217
|
+
* @example
|
|
1218
|
+
* liveboardEmbed.trigger(HostEvent.SetVisibleVizs, ['730496d6-6903-4601-937e-2c691821af3c', 'd547ec54-2a37-4516-a222-2b06719af726'])
|
|
1165
1219
|
* @version SDK: 1.6.0 | ThoughtSpot: ts8.nov.cl, 8.4.1-sw
|
|
1166
1220
|
*/
|
|
1167
1221
|
SetVisibleVizs = "SetPinboardVisibleVizs",
|
|
@@ -1169,18 +1223,25 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1169
1223
|
* Update the runtime filters. The runtime filters passed here are extended
|
|
1170
1224
|
* on to the existing runtime filters if they exist.
|
|
1171
1225
|
* @param - {@link RuntimeFilter}[] an array of {@link RuntimeFilter} Types.
|
|
1226
|
+
* @example
|
|
1227
|
+
* liveboardEmbed.trigger(HostEvent.UpdateRuntimeFilters, [
|
|
1228
|
+
* {columnName: "state",operator: "EQ",values: ["michigan"]},
|
|
1229
|
+
* {columnName: "item type",operator: "EQ",values: ["Jackets"]}
|
|
1230
|
+
* ])
|
|
1172
1231
|
* @version SDK: 1.9.0 | ThoughtSpot: 8.1.0.cl, 8.4.1-sw
|
|
1173
1232
|
*/
|
|
1174
1233
|
UpdateRuntimeFilters = "UpdateRuntimeFilters",
|
|
1175
1234
|
/**
|
|
1176
1235
|
* Navigate to a specific page in App embed without any reload.
|
|
1177
1236
|
* This is the same as calling `appEmbed.navigateToPage(path, true)`
|
|
1178
|
-
* @param path - the path to navigate to (can be a number[1/-1] to go forward/back)
|
|
1237
|
+
* @param - path - the path to navigate to (can be a number[1/-1] to go forward/back)
|
|
1238
|
+
* @example appEmbed.navigateToPage(-1)
|
|
1179
1239
|
* @version SDK: 1.12.0 | ThoughtSpot 8.4.0.cl, 8.4.1-sw
|
|
1180
1240
|
*/
|
|
1181
1241
|
Navigate = "Navigate",
|
|
1182
1242
|
/**
|
|
1183
1243
|
* Gets the current pinboard content.
|
|
1244
|
+
* @example liveboardEmbed.trigger(HostEvent.getExportRequestForCurrentPinboard)
|
|
1184
1245
|
* @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl, 8.8.1-sw
|
|
1185
1246
|
*/
|
|
1186
1247
|
getExportRequestForCurrentPinboard = "getExportRequestForCurrentPinboard",
|
|
@@ -1188,70 +1249,82 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1188
1249
|
* Triggers the Pin action on an embedded object
|
|
1189
1250
|
* @param - incase of Liveboard embed, takes in an object with vizId as a key
|
|
1190
1251
|
* can be left empty for search and visualization embeds
|
|
1252
|
+
* @example liveboardEmbed.trigger(HostEvent.Pin, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
1191
1253
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1192
1254
|
*/
|
|
1193
1255
|
Pin = "pin",
|
|
1194
1256
|
/**
|
|
1195
1257
|
* Triggers the Show Liveboard details action on a Liveboard
|
|
1258
|
+
* @example liveboardEmbed.trigger(HostEvent.LiveboardInfo)
|
|
1196
1259
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1197
1260
|
*/
|
|
1198
1261
|
LiveboardInfo = "pinboardInfo",
|
|
1199
1262
|
/**
|
|
1200
1263
|
* Triggers the Schedule action on a Liveboard
|
|
1264
|
+
* @example liveboardEmbed.trigger(HostEvent.Schedule)
|
|
1201
1265
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1202
1266
|
*/
|
|
1203
1267
|
Schedule = "subscription",
|
|
1204
1268
|
/**
|
|
1205
1269
|
* Triggers the Manage schedule action on a Liveboard
|
|
1270
|
+
* @example liveboardEmbed.trigger(HostEvent.ScheduleList)
|
|
1206
1271
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1207
1272
|
*/
|
|
1208
1273
|
SchedulesList = "schedule-list",
|
|
1209
1274
|
/**
|
|
1210
1275
|
* Triggers the Export TML action on a Liveboard
|
|
1276
|
+
* @example liveboardEmbed.trigger(HostEvent.ExportTML)
|
|
1211
1277
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1212
1278
|
*/
|
|
1213
1279
|
ExportTML = "exportTSL",
|
|
1214
1280
|
/**
|
|
1215
1281
|
* Triggers the Edit TML action on a Liveboard
|
|
1282
|
+
* @example liveboardEmbed.trigger(HostEvent.EditTML)
|
|
1216
1283
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1217
1284
|
*/
|
|
1218
1285
|
EditTML = "editTSL",
|
|
1219
1286
|
/**
|
|
1220
1287
|
* Triggers the Update TML action on a Liveboard
|
|
1288
|
+
* @example liveboardEmbed.trigger(HostEvent.UpdateTML)
|
|
1221
1289
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1222
1290
|
*/
|
|
1223
1291
|
UpdateTML = "updateTSL",
|
|
1224
1292
|
/**
|
|
1225
1293
|
* Triggers the Download PDF action on a Liveboard
|
|
1294
|
+
* @example liveboardEmbed.trigger(HostEvent.DownloadAsPDF)
|
|
1226
1295
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1227
1296
|
*/
|
|
1228
1297
|
DownloadAsPdf = "downloadAsPdf",
|
|
1229
1298
|
/**
|
|
1230
1299
|
* Triggers the Make a copy action on a Liveboard
|
|
1300
|
+
* @example liveboardEmbed.trigger(HostEvent.MakeACopy)
|
|
1231
1301
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1232
1302
|
*/
|
|
1233
1303
|
MakeACopy = "makeACopy",
|
|
1234
1304
|
/**
|
|
1235
1305
|
* Triggers the Delete action on a Liveboard
|
|
1306
|
+
* @example appEmbed.trigger(HostEvent.Remove)
|
|
1236
1307
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1237
1308
|
*/
|
|
1238
1309
|
Remove = "delete",
|
|
1239
1310
|
/**
|
|
1240
1311
|
* Triggers the Explore action on a visualization
|
|
1241
1312
|
* @param - an object with vizId as a key
|
|
1242
|
-
*
|
|
1313
|
+
* @example liveboardEmbed.trigger(HostEvent.Explore, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
1243
1314
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1244
1315
|
*/
|
|
1245
1316
|
Explore = "explore",
|
|
1246
1317
|
/**
|
|
1247
1318
|
* Triggers the Create alert action on a visualization
|
|
1248
1319
|
* @param - an object with vizId as a key
|
|
1320
|
+
* @example liveboardEmbed.trigger(HostEvent.CreateMonitor {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
1249
1321
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1250
1322
|
*/
|
|
1251
1323
|
CreateMonitor = "createMonitor",
|
|
1252
1324
|
/**
|
|
1253
1325
|
* Triggers the Manage alert action on a visualization
|
|
1254
1326
|
* @param - an object with vizId as a key
|
|
1327
|
+
* @example liveboardEmbed.trigger(HostEvent.ManageMonitor, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
1255
1328
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
|
|
1256
1329
|
*/
|
|
1257
1330
|
ManageMonitor = "manageMonitor",
|
|
@@ -1287,9 +1360,26 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1287
1360
|
Present = "present",
|
|
1288
1361
|
/**
|
|
1289
1362
|
* Get TML for the current search.
|
|
1363
|
+
* @example searchEmbed.trigger(HostEvent.GetTML)
|
|
1290
1364
|
* @version SDK: 1.18.0 | ThoughtSpot: 8.10.0.cl
|
|
1291
1365
|
*/
|
|
1292
|
-
GetTML = "getTML"
|
|
1366
|
+
GetTML = "getTML",
|
|
1367
|
+
/**
|
|
1368
|
+
* Triggers the Share action on a liveboard or answer
|
|
1369
|
+
* @example
|
|
1370
|
+
* liveboardEmbed.trigger(HostEvent.Share)
|
|
1371
|
+
* searchEmbed.trigger(HostEvent.Share)
|
|
1372
|
+
* @version SDK: 1.18.0 | Thoughtspot: 9.0.0.cl
|
|
1373
|
+
*/
|
|
1374
|
+
Share = "share",
|
|
1375
|
+
/**
|
|
1376
|
+
* Trigger the Save action on a liveboard or answer
|
|
1377
|
+
* @example
|
|
1378
|
+
* liveboardEmbed.trigger(HostEvent.Save)
|
|
1379
|
+
* searchEmbed.trigger(HostEvent.Save)
|
|
1380
|
+
* @version SDK: 1.18.0 | Thoughtspot: 9.0.0.cl
|
|
1381
|
+
*/
|
|
1382
|
+
Save = "save"
|
|
1293
1383
|
}
|
|
1294
1384
|
/**
|
|
1295
1385
|
* The different visual modes that the data sources panel within
|
|
@@ -1345,7 +1435,9 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1345
1435
|
LiveboardV2Enabled = "isPinboardV2Enabled",
|
|
1346
1436
|
ShowAlerts = "showAlerts",
|
|
1347
1437
|
Locale = "locale",
|
|
1348
|
-
CustomStyle = "customStyle"
|
|
1438
|
+
CustomStyle = "customStyle",
|
|
1439
|
+
ForceSAMLAutoRedirect = "forceSAMLAutoRedirect",
|
|
1440
|
+
AuthType = "authType"
|
|
1349
1441
|
}
|
|
1350
1442
|
/**
|
|
1351
1443
|
* The list of actions that can be performed on visual ThoughtSpot
|
|
@@ -1489,7 +1581,10 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
1489
1581
|
/**
|
|
1490
1582
|
* @version SDK: 1.11.1 | ThoughtSpot: 8.3.0.cl, 8.4.1-sw
|
|
1491
1583
|
*/
|
|
1492
|
-
ReportError = "reportError"
|
|
1584
|
+
ReportError = "reportError",
|
|
1585
|
+
SyncToSheets = "sync-to-sheets",
|
|
1586
|
+
SyncToOtherApps = "sync-to-other-apps",
|
|
1587
|
+
ManagePipelines = "manage-pipeline"
|
|
1493
1588
|
}
|
|
1494
1589
|
export interface SessionInterface {
|
|
1495
1590
|
sessionId: string;
|
|
@@ -1664,7 +1759,7 @@ declare module '@thoughtspot/visual-embed-sdk/embed/ts-embed' {
|
|
|
1664
1759
|
* @param url
|
|
1665
1760
|
* @param frameOptions
|
|
1666
1761
|
*/
|
|
1667
|
-
protected renderIFrame(url: string, frameOptions?: FrameParams):
|
|
1762
|
+
protected renderIFrame(url: string, frameOptions?: FrameParams): Promise<any>;
|
|
1668
1763
|
/**
|
|
1669
1764
|
* Sets the height of the iframe
|
|
1670
1765
|
* @param height The height in pixels
|
|
@@ -1745,7 +1840,7 @@ declare module '@thoughtspot/visual-embed-sdk/embed/ts-embed' {
|
|
|
1745
1840
|
* Render the app in an iframe and set up event handlers
|
|
1746
1841
|
* @param iframeSrc
|
|
1747
1842
|
*/
|
|
1748
|
-
protected renderV1Embed(iframeSrc: string):
|
|
1843
|
+
protected renderV1Embed(iframeSrc: string): any;
|
|
1749
1844
|
on(messageType: EmbedEvent, callback: MessageCallback, options?: MessageOptions): typeof TsEmbed.prototype;
|
|
1750
1845
|
}
|
|
1751
1846
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thoughtspot/visual-embed-sdk",
|
|
3
|
-
"version": "1.17.0-alpha.
|
|
3
|
+
"version": "1.17.0-alpha.2",
|
|
4
4
|
"description": "ThoughtSpot Embed SDK",
|
|
5
5
|
"module": "lib/src/index.js",
|
|
6
6
|
"main": "dist/tsembed.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"watch": "rollup -cw",
|
|
30
30
|
"docs-cmd": "node scripts/gatsby-commands.js",
|
|
31
31
|
"docgen": "typedoc --tsconfig tsconfig.json --theme typedoc-theme",
|
|
32
|
-
"test-sdk": "jest -c jest.config.sdk.js",
|
|
32
|
+
"test-sdk": "jest -c jest.config.sdk.js --runInBand",
|
|
33
33
|
"test-docs": "jest -c jest.config.docs.js",
|
|
34
34
|
"test": "npm run test-sdk && npm run test-docs",
|
|
35
35
|
"posttest": "cat ./coverage/sdk/lcov.info | coveralls",
|
package/src/auth.spec.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as authInstance from './auth';
|
|
2
2
|
import * as authService from './utils/authService';
|
|
3
3
|
import * as checkReleaseVersionInBetaInstance from './utils';
|
|
4
|
-
import { AuthType, EmbedConfig } from './types';
|
|
4
|
+
import { AuthType, EmbedConfig, EmbedEvent } from './types';
|
|
5
5
|
import { executeAfterWait } from './test/test-utils';
|
|
6
6
|
|
|
7
7
|
const thoughtSpotHost = 'http://localhost:3000';
|
|
@@ -43,6 +43,12 @@ export const embedConfig: any = {
|
|
|
43
43
|
doSamlAuth: {
|
|
44
44
|
thoughtSpotHost,
|
|
45
45
|
},
|
|
46
|
+
doSamlAuthNoRedirect: {
|
|
47
|
+
thoughtSpotHost,
|
|
48
|
+
noRedirect: true,
|
|
49
|
+
authTriggerContainer: document.body,
|
|
50
|
+
authTriggerText: 'auth',
|
|
51
|
+
},
|
|
46
52
|
doOidcAuth: {
|
|
47
53
|
thoughtSpotHost,
|
|
48
54
|
},
|
|
@@ -393,10 +399,12 @@ describe('Unit test for auth', () => {
|
|
|
393
399
|
expect(await authInstance.samlCompletionPromise).not.toBe(null);
|
|
394
400
|
expect(
|
|
395
401
|
await authInstance.doSamlAuth({
|
|
396
|
-
...embedConfig.
|
|
397
|
-
noRedirect: true,
|
|
402
|
+
...embedConfig.doSamlAuthNoRedirect,
|
|
398
403
|
}),
|
|
399
404
|
).toBe(true);
|
|
405
|
+
document.getElementById('ts-auth-btn').click();
|
|
406
|
+
window.postMessage({ type: EmbedEvent.SAMLComplete }, '*');
|
|
407
|
+
await authInstance.samlCompletionPromise;
|
|
400
408
|
expect(authService.fetchSessionInfoService).toBeCalled();
|
|
401
409
|
});
|
|
402
410
|
});
|
package/src/auth.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { initMixpanel } from './mixpanel-service';
|
|
2
|
-
import { AuthType, EmbedConfig, EmbedEvent } from './types';
|
|
3
|
-
import { getRedirectUrl } from './utils';
|
|
2
|
+
import { AuthType, DOMSelector, EmbedConfig, EmbedEvent, Param } from './types';
|
|
3
|
+
import { getDOMNode, getRedirectUrl } from './utils';
|
|
4
4
|
// eslint-disable-next-line import/no-cycle
|
|
5
5
|
import {
|
|
6
6
|
fetchSessionInfoService,
|
|
@@ -208,12 +208,16 @@ export const doBasicAuth = async (
|
|
|
208
208
|
return loggedInStatus;
|
|
209
209
|
};
|
|
210
210
|
|
|
211
|
-
async function samlPopupFlow(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
211
|
+
async function samlPopupFlow(
|
|
212
|
+
ssoURL: string,
|
|
213
|
+
triggerContainer: DOMSelector,
|
|
214
|
+
triggerText: string,
|
|
215
|
+
) {
|
|
216
|
+
const containerEl = getDOMNode(triggerContainer);
|
|
217
|
+
containerEl.innerHTML =
|
|
218
|
+
'<button id="ts-auth-btn" class="ts-auth-btn" style="margin: auto;"></button>';
|
|
219
|
+
const authElem = document.getElementById('ts-auth-btn');
|
|
220
|
+
authElem.textContent = triggerText;
|
|
217
221
|
samlCompletionPromise =
|
|
218
222
|
samlCompletionPromise ||
|
|
219
223
|
new Promise<void>((resolve, reject) => {
|
|
@@ -239,7 +243,6 @@ async function samlPopupFlow(ssoURL: string) {
|
|
|
239
243
|
},
|
|
240
244
|
{ once: true },
|
|
241
245
|
);
|
|
242
|
-
authElem.click();
|
|
243
246
|
return samlCompletionPromise;
|
|
244
247
|
}
|
|
245
248
|
|
|
@@ -271,7 +274,11 @@ const doSSOAuth = async (
|
|
|
271
274
|
|
|
272
275
|
const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
|
|
273
276
|
if (embedConfig.noRedirect) {
|
|
274
|
-
await samlPopupFlow(
|
|
277
|
+
await samlPopupFlow(
|
|
278
|
+
ssoURL,
|
|
279
|
+
embedConfig.authTriggerContainer,
|
|
280
|
+
embedConfig.authTriggerText,
|
|
281
|
+
);
|
|
275
282
|
loggedInStatus = true;
|
|
276
283
|
return;
|
|
277
284
|
}
|
|
@@ -338,11 +345,14 @@ export const authenticate = async (
|
|
|
338
345
|
const { authType } = embedConfig;
|
|
339
346
|
switch (authType) {
|
|
340
347
|
case AuthType.SSO:
|
|
348
|
+
case AuthType.SAMLRedirect:
|
|
341
349
|
case AuthType.SAML:
|
|
342
350
|
return doSamlAuth(embedConfig);
|
|
343
351
|
case AuthType.OIDC:
|
|
352
|
+
case AuthType.OIDCRedirect:
|
|
344
353
|
return doOIDCAuth(embedConfig);
|
|
345
354
|
case AuthType.AuthServer:
|
|
355
|
+
case AuthType.TrustedAuthToken:
|
|
346
356
|
return doTokenAuth(embedConfig);
|
|
347
357
|
case AuthType.Basic:
|
|
348
358
|
return doBasicAuth(embedConfig);
|
package/src/embed/app.spec.ts
CHANGED
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
getRootEl,
|
|
9
9
|
getIFrameEl,
|
|
10
10
|
mockMessageChannel,
|
|
11
|
+
defaultParams,
|
|
12
|
+
defaultParamsForPinboardEmbed,
|
|
13
|
+
defaultParamsWithoutHiddenActions,
|
|
11
14
|
} from '../test/test-utils';
|
|
12
15
|
import { version } from '../../package.json';
|
|
13
16
|
import * as config from '../config';
|
|
@@ -19,9 +22,6 @@ const defaultViewConfig = {
|
|
|
19
22
|
},
|
|
20
23
|
};
|
|
21
24
|
const thoughtSpotHost = 'tshost';
|
|
22
|
-
const defaultParamsWithoutHiddenActions = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
|
|
23
|
-
const defaultParams = `${defaultParamsWithoutHiddenActions}&hideAction=[%22${Action.ReportError}%22]`;
|
|
24
|
-
const defaultParamsForPinboardEmbed = `hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&hideAction=[%22${Action.ReportError}%22]`;
|
|
25
25
|
const defaultParamsPost = '';
|
|
26
26
|
|
|
27
27
|
beforeAll(() => {
|
|
@@ -156,7 +156,7 @@ describe('App embed tests', () => {
|
|
|
156
156
|
appEmbed.render();
|
|
157
157
|
await executeAfterWait(() => {
|
|
158
158
|
expect(getIFrameSrc()).toBe(
|
|
159
|
-
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=false&profileAndHelpInNavBarHidden=false
|
|
159
|
+
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=false&profileAndHelpInNavBarHidden=false&${defaultParamsWithoutHiddenActions}&disableAction=[%22save%22,%22update%22]&disableHint=Access%20denied&hideAction=[%22${Action.ReportError}%22,%22download%22]${defaultParamsPost}#/home`,
|
|
160
160
|
);
|
|
161
161
|
});
|
|
162
162
|
});
|
package/src/embed/base.spec.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import { EmbedConfig } from '../index';
|
|
2
3
|
import * as auth from '../auth';
|
|
3
4
|
import * as index from '../index';
|
|
4
5
|
import * as base from './base';
|
|
@@ -176,6 +177,43 @@ describe('Base TS Embed', () => {
|
|
|
176
177
|
);
|
|
177
178
|
expect(base.getEmbedConfig().autoLogin).toBe(false);
|
|
178
179
|
});
|
|
180
|
+
|
|
181
|
+
test('config sanity, no ts host', () => {
|
|
182
|
+
expect(() => {
|
|
183
|
+
index.init({
|
|
184
|
+
authType: index.AuthType.None,
|
|
185
|
+
} as EmbedConfig);
|
|
186
|
+
}).toThrowError();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
test('config sanity, no username in trusted auth', () => {
|
|
190
|
+
expect(() => {
|
|
191
|
+
index.init({
|
|
192
|
+
authType: index.AuthType.TrustedAuthToken,
|
|
193
|
+
thoughtSpotHost,
|
|
194
|
+
} as EmbedConfig);
|
|
195
|
+
}).toThrowError();
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('config sanity, no authEndpoint and getAuthToken', () => {
|
|
199
|
+
expect(() => {
|
|
200
|
+
index.init({
|
|
201
|
+
authType: index.AuthType.TrustedAuthToken,
|
|
202
|
+
thoughtSpotHost,
|
|
203
|
+
username: 'test',
|
|
204
|
+
});
|
|
205
|
+
}).toThrowError();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
test('config sanity, pass triggerContainer with noRedirect', () => {
|
|
209
|
+
expect(() => {
|
|
210
|
+
index.init({
|
|
211
|
+
thoughtSpotHost,
|
|
212
|
+
authType: index.AuthType.SAMLRedirect,
|
|
213
|
+
noRedirect: true,
|
|
214
|
+
});
|
|
215
|
+
}).toThrowError();
|
|
216
|
+
});
|
|
179
217
|
});
|
|
180
218
|
|
|
181
219
|
describe('Base without init', () => {
|
package/src/embed/base.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
|
|
9
9
|
*/
|
|
10
10
|
import EventEmitter from 'eventemitter3';
|
|
11
|
-
import
|
|
11
|
+
import uniq from 'lodash/uniq';
|
|
12
12
|
import { getThoughtSpotHost } from '../config';
|
|
13
13
|
import { AuthType, EmbedConfig, PrefetchFeatures } from '../types';
|
|
14
14
|
import {
|
|
@@ -22,6 +22,7 @@ import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
|
22
22
|
let config = {} as EmbedConfig;
|
|
23
23
|
const CONFIG_DEFAULTS: Partial<EmbedConfig> = {
|
|
24
24
|
loginFailedMessage: 'Not logged in',
|
|
25
|
+
authTriggerText: 'Authorize',
|
|
25
26
|
authType: AuthType.None,
|
|
26
27
|
};
|
|
27
28
|
|
|
@@ -108,7 +109,7 @@ export const prefetch = (
|
|
|
108
109
|
const features = prefetchFeatures || [PrefetchFeatures.FullApp];
|
|
109
110
|
let hostUrl = url || config.thoughtSpotHost;
|
|
110
111
|
hostUrl = hostUrl[hostUrl.length - 1] === '/' ? hostUrl : `${hostUrl}/`;
|
|
111
|
-
|
|
112
|
+
uniq(
|
|
112
113
|
features.map((feature) => hostUrlToFeatureUrl[feature](hostUrl)),
|
|
113
114
|
).forEach((prefetchUrl, index) => {
|
|
114
115
|
const iFrame = document.createElement('iframe');
|
|
@@ -123,6 +124,29 @@ export const prefetch = (
|
|
|
123
124
|
}
|
|
124
125
|
};
|
|
125
126
|
|
|
127
|
+
function sanity(embedConfig: EmbedConfig) {
|
|
128
|
+
if (embedConfig.thoughtSpotHost === undefined) {
|
|
129
|
+
throw new Error('ThoughtSpot host not provided');
|
|
130
|
+
}
|
|
131
|
+
if (embedConfig.authType === AuthType.TrustedAuthToken) {
|
|
132
|
+
if (!embedConfig.username) {
|
|
133
|
+
throw new Error('Username not provided with Trusted auth');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (
|
|
137
|
+
!embedConfig.authEndpoint ||
|
|
138
|
+
typeof embedConfig.getAuthToken !== 'function'
|
|
139
|
+
) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
'Trusted auth should provide either authEndpoint or getAuthToken',
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (embedConfig.noRedirect && !embedConfig.authTriggerContainer) {
|
|
146
|
+
throw new Error('authTriggerContainer not provided with noRedirect');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
126
150
|
/**
|
|
127
151
|
* Initializes the Visual Embed SDK globally and perform
|
|
128
152
|
* authentication if applicable.
|
|
@@ -134,6 +158,7 @@ export const prefetch = (
|
|
|
134
158
|
* @version SDK: 1.0.0 | ThoughtSpot ts7.april.cl, 7.2.1
|
|
135
159
|
*/
|
|
136
160
|
export const init = (embedConfig: EmbedConfig): EventEmitter => {
|
|
161
|
+
sanity(embedConfig);
|
|
137
162
|
config = {
|
|
138
163
|
...CONFIG_DEFAULTS,
|
|
139
164
|
...embedConfig,
|
|
@@ -191,14 +216,16 @@ let renderQueue: Promise<any> = Promise.resolve();
|
|
|
191
216
|
* Renders functions in a queue, resolves to next function only after the callback next is called
|
|
192
217
|
* @param fn The function being registered
|
|
193
218
|
*/
|
|
194
|
-
export const renderInQueue = (
|
|
219
|
+
export const renderInQueue = (
|
|
220
|
+
fn: (next?: (val?: any) => void) => Promise<any>,
|
|
221
|
+
): Promise<any> => {
|
|
195
222
|
const { queueMultiRenders = false } = config;
|
|
196
223
|
if (queueMultiRenders) {
|
|
197
224
|
renderQueue = renderQueue.then(() => new Promise((res) => fn(res)));
|
|
198
|
-
|
|
199
|
-
// Sending an empty function to keep it consistent with the above usage.
|
|
200
|
-
fn(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
|
|
225
|
+
return renderQueue;
|
|
201
226
|
}
|
|
227
|
+
// Sending an empty function to keep it consistent with the above usage.
|
|
228
|
+
return fn(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
|
|
202
229
|
};
|
|
203
230
|
|
|
204
231
|
// For testing purposes only
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
getDocumentBody,
|
|
13
13
|
getIFrameSrc,
|
|
14
14
|
getRootEl,
|
|
15
|
+
defaultParams,
|
|
16
|
+
defaultParamsWithoutHiddenActions,
|
|
15
17
|
} from '../test/test-utils';
|
|
16
18
|
import { version } from '../../package.json';
|
|
17
19
|
import * as processTriggerInstance from '../utils/processTrigger';
|
|
@@ -26,8 +28,6 @@ const liveboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
|
|
|
26
28
|
const activeTabId = '502693ba-9818-4e71-8ecd-d1a194e46861';
|
|
27
29
|
const vizId = '6e73f724-660e-11eb-ae93-0242ac130002';
|
|
28
30
|
const thoughtSpotHost = 'tshost';
|
|
29
|
-
const defaultParamsSansHideAction = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
|
|
30
|
-
const defaultParams = `${defaultParamsSansHideAction}&hideAction=[%22${Action.ReportError}%22]`;
|
|
31
31
|
const prefixParams = '&isLiveboardEmbed=true';
|
|
32
32
|
const prefixParamsVizEmbed = '&isLiveboardEmbed=true&isVizEmbed=true';
|
|
33
33
|
|
|
@@ -70,7 +70,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
70
70
|
liveboardEmbed.render();
|
|
71
71
|
await executeAfterWait(() => {
|
|
72
72
|
expect(getIFrameSrc()).toBe(
|
|
73
|
-
`http://${thoughtSpotHost}/?embedApp=true
|
|
73
|
+
`http://${thoughtSpotHost}/?embedApp=true&${defaultParamsWithoutHiddenActions}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied&hideAction=[%22${Action.ReportError}%22]${prefixParams}#/embed/viz/${liveboardId}`,
|
|
74
74
|
);
|
|
75
75
|
});
|
|
76
76
|
});
|
|
@@ -88,7 +88,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
88
88
|
liveboardEmbed.render();
|
|
89
89
|
await executeAfterWait(() => {
|
|
90
90
|
expect(getIFrameSrc()).toBe(
|
|
91
|
-
`http://${thoughtSpotHost}/?embedApp=true
|
|
91
|
+
`http://${thoughtSpotHost}/?embedApp=true&${defaultParamsWithoutHiddenActions}&hideAction=[%22${Action.ReportError}%22,%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${liveboardId}`,
|
|
92
92
|
);
|
|
93
93
|
});
|
|
94
94
|
});
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
getDocumentBody,
|
|
7
7
|
getIFrameSrc,
|
|
8
8
|
getRootEl,
|
|
9
|
+
defaultParams,
|
|
10
|
+
defaultParamsWithoutHiddenActions,
|
|
9
11
|
} from '../test/test-utils';
|
|
10
12
|
import { version } from '../../package.json';
|
|
11
13
|
|
|
@@ -18,8 +20,6 @@ const defaultViewConfig = {
|
|
|
18
20
|
const pinboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
|
|
19
21
|
const vizId = '6e73f724-660e-11eb-ae93-0242ac130002';
|
|
20
22
|
const thoughtSpotHost = 'tshost';
|
|
21
|
-
const defaultParamsWithoutHideActions = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
|
|
22
|
-
const defaultParams = `${defaultParamsWithoutHideActions}&hideAction=[%22${Action.ReportError}%22]`;
|
|
23
23
|
const prefixParams = '&isLiveboardEmbed=true';
|
|
24
24
|
const prefixParamsVizEmbed = '&isLiveboardEmbed=true&isVizEmbed=true';
|
|
25
25
|
beforeAll(() => {
|
|
@@ -61,7 +61,7 @@ describe('Pinboard/viz embed tests', () => {
|
|
|
61
61
|
pinboardEmbed.render();
|
|
62
62
|
await executeAfterWait(() => {
|
|
63
63
|
expect(getIFrameSrc()).toBe(
|
|
64
|
-
`http://${thoughtSpotHost}/?embedApp=true
|
|
64
|
+
`http://${thoughtSpotHost}/?embedApp=true&${defaultParamsWithoutHiddenActions}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied&hideAction=[%22${Action.ReportError}%22]${prefixParams}#/embed/viz/${pinboardId}`,
|
|
65
65
|
);
|
|
66
66
|
});
|
|
67
67
|
});
|
|
@@ -79,7 +79,7 @@ describe('Pinboard/viz embed tests', () => {
|
|
|
79
79
|
pinboardEmbed.render();
|
|
80
80
|
await executeAfterWait(() => {
|
|
81
81
|
expect(getIFrameSrc()).toBe(
|
|
82
|
-
`http://${thoughtSpotHost}/?embedApp=true
|
|
82
|
+
`http://${thoughtSpotHost}/?embedApp=true&${defaultParamsWithoutHiddenActions}&hideAction=[%22${Action.ReportError}%22,%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${pinboardId}`,
|
|
83
83
|
);
|
|
84
84
|
});
|
|
85
85
|
});
|