@saasquatch/squatch-js 2.8.2-1 → 2.8.2-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/squatch.d.ts CHANGED
@@ -60,7 +60,7 @@ export declare function widget(widgetConfig: WidgetConfig): Promise<WidgetResult
60
60
  * Called by default on startup via the loader script.
61
61
  * @private
62
62
  */
63
- export declare function _auto(configIn: ConfigOptions): Promise<WidgetResult | undefined> | undefined;
63
+ export declare function _auto(): Promise<WidgetResult | undefined> | undefined;
64
64
  /**
65
65
  * Initializes the static `squatch` global. This sets up:
66
66
  *
@@ -700,6 +700,7 @@ class WidgetApi {
700
700
  const raw = params;
701
701
  const clean = validatePasswordlessConfig(raw);
702
702
  const { widgetType, engagementMedium = "POPUP", jwt, user } = clean;
703
+ console.log({ params });
703
704
  const tenantAlias = encodeURIComponent(this.tenantAlias);
704
705
  const accountId = (user == null ? void 0 : user.accountId) ? encodeURIComponent(user.accountId) : null;
705
706
  const userId = (user == null ? void 0 : user.id) ? encodeURIComponent(user.id) : null;
@@ -1105,6 +1106,351 @@ function delay(duration) {
1105
1106
  setTimeout(resolve, duration);
1106
1107
  });
1107
1108
  }
1109
+ const getSkeleton = ({
1110
+ height = "500px",
1111
+ skeletonBackgroundColor = "#e0e0e0",
1112
+ skeletonShimmerColor = "#f5f5f5",
1113
+ borderColor = "#ccc"
1114
+ }) => {
1115
+ return `
1116
+ <style>
1117
+ * {
1118
+ box-sizing: border-box;
1119
+ padding: 0;
1120
+ margin: 0;
1121
+ }
1122
+
1123
+ .widget-container {
1124
+ background: white;
1125
+ width: 100%;
1126
+ max-width: 900px;
1127
+ padding: 40px;
1128
+ border-radius: 12px;
1129
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
1130
+ box-sizing: border-box;
1131
+ }
1132
+
1133
+ @keyframes shimmer {
1134
+ 0% {
1135
+ background-position: -100% 0;
1136
+ }
1137
+ 100% {
1138
+ background-position: 100% 0;
1139
+ }
1140
+ }
1141
+
1142
+ .skeleton {
1143
+ background: ${skeletonBackgroundColor};
1144
+ background: linear-gradient(
1145
+ 90deg,
1146
+ ${skeletonBackgroundColor} 25%,
1147
+ ${skeletonShimmerColor} 50%,
1148
+ ${skeletonBackgroundColor} 75%
1149
+ );
1150
+ background-size: 200% 100%;
1151
+ animation: shimmer 1.5s infinite linear;
1152
+ border-radius: 6px;
1153
+ margin-bottom: 12px;
1154
+ }
1155
+
1156
+ .sk-title-lg {
1157
+ height: 36px;
1158
+ width: 50%;
1159
+ margin-bottom: 16px;
1160
+ }
1161
+ .sk-title-md {
1162
+ height: 28px;
1163
+ width: 30%;
1164
+ margin-bottom: 20px;
1165
+ margin-top: 40px;
1166
+ }
1167
+ .sk-text {
1168
+ height: 16px;
1169
+ width: 80%;
1170
+ margin-bottom: 8px;
1171
+ }
1172
+ .sk-text-short {
1173
+ width: 40%;
1174
+ }
1175
+ .sk-label {
1176
+ height: 14px;
1177
+ width: 25%;
1178
+ margin-bottom: 10px;
1179
+ }
1180
+
1181
+ .hero-section {
1182
+ display: flex;
1183
+ gap: 40px;
1184
+ margin-bottom: 40px;
1185
+ border-bottom: 1px solid ${borderColor};
1186
+ padding-bottom: 40px;
1187
+ flex-direction: row;
1188
+ }
1189
+ .hero-content {
1190
+ flex: 1;
1191
+ display: flex;
1192
+ flex-direction: column;
1193
+ justify-content: center;
1194
+ }
1195
+ .hero-image {
1196
+ flex: 1;
1197
+ height: 300px;
1198
+ border-radius: 12px;
1199
+ }
1200
+
1201
+ .share-section {
1202
+ margin-bottom: 40px;
1203
+ }
1204
+ .sk-input {
1205
+ height: 50px;
1206
+ width: 100%;
1207
+ border-radius: 8px;
1208
+ margin-bottom: 16px;
1209
+ }
1210
+ .social-buttons {
1211
+ display: flex;
1212
+ gap: 12px;
1213
+ }
1214
+ .sk-btn-social {
1215
+ flex: 1;
1216
+ height: 50px;
1217
+ border-radius: 8px;
1218
+ }
1219
+
1220
+ .stats-section {
1221
+ display: flex;
1222
+ gap: 24px;
1223
+ margin-bottom: 40px;
1224
+ padding: 30px 0;
1225
+ border-top: 1px solid ${borderColor};
1226
+ border-bottom: 1px solid ${borderColor};
1227
+ }
1228
+ .stat-card {
1229
+ flex: 1;
1230
+ display: flex;
1231
+ flex-direction: column;
1232
+ align-items: center;
1233
+ }
1234
+ .stat-divider {
1235
+ padding-left: 24px;
1236
+ }
1237
+
1238
+ .sk-stat-num {
1239
+ height: 48px;
1240
+ width: 120px;
1241
+ margin-bottom: 8px;
1242
+ }
1243
+ .sk-stat-label {
1244
+ height: 18px;
1245
+ width: 80px;
1246
+ }
1247
+
1248
+ .table-header {
1249
+ display: flex;
1250
+ gap: 16px;
1251
+ margin-bottom: 16px;
1252
+ }
1253
+ .sk-th {
1254
+ height: 16px;
1255
+ }
1256
+ .table-row {
1257
+ display: flex;
1258
+ align-items: center;
1259
+ gap: 16px;
1260
+ padding: 16px 0;
1261
+ border-bottom: 1px solid ${borderColor};
1262
+ }
1263
+
1264
+ .col-user {
1265
+ flex: 2;
1266
+ }
1267
+ .col-status {
1268
+ flex: 1;
1269
+ }
1270
+ .col-reward {
1271
+ flex: 2;
1272
+ }
1273
+ .col-date {
1274
+ flex: 1;
1275
+ }
1276
+
1277
+ .sk-badge {
1278
+ height: 28px;
1279
+ width: 90px;
1280
+ border-radius: 14px;
1281
+ }
1282
+ .sk-reward-block {
1283
+ height: 36px;
1284
+ width: 100%;
1285
+ border-radius: 6px;
1286
+ }
1287
+
1288
+ .pagination {
1289
+ display: flex;
1290
+ justify-content: flex-end;
1291
+ gap: 8px;
1292
+ margin-top: 24px;
1293
+ }
1294
+ .sk-btn-page {
1295
+ height: 36px;
1296
+ width: 64px;
1297
+ border-radius: 6px;
1298
+ margin-bottom: 0;
1299
+ }
1300
+
1301
+ @media (max-width: 768px) {
1302
+ body {
1303
+ padding: 20px;
1304
+ }
1305
+ .widget-container {
1306
+ padding: 24px;
1307
+ }
1308
+
1309
+ .hero-section {
1310
+ flex-direction: column-reverse;
1311
+ gap: 24px;
1312
+ }
1313
+ .hero-image {
1314
+ height: 220px;
1315
+ width: 100%;
1316
+ }
1317
+ .sk-title-lg {
1318
+ width: 80%;
1319
+ }
1320
+
1321
+ .col-date {
1322
+ display: none;
1323
+ }
1324
+ }
1325
+
1326
+ @media (max-width: 480px) {
1327
+ body {
1328
+ padding: 10px;
1329
+ }
1330
+ .widget-container {
1331
+ padding: 16px;
1332
+ }
1333
+
1334
+ .sk-stat-num {
1335
+ width: 80px;
1336
+ height: 40px;
1337
+ }
1338
+
1339
+ .col-reward {
1340
+ display: none;
1341
+ }
1342
+
1343
+ .col-user {
1344
+ flex: 3;
1345
+ }
1346
+ .col-status {
1347
+ flex: 2;
1348
+ display: flex;
1349
+ justify-content: flex-end;
1350
+ }
1351
+ }
1352
+ </style>
1353
+
1354
+ <div class="widget-container">
1355
+ <div class="hero-section">
1356
+ <div class="hero-content">
1357
+ <div class="skeleton sk-title-lg"></div>
1358
+ <div class="skeleton sk-text"></div>
1359
+ <div class="skeleton sk-text sk-text-short"></div>
1360
+ </div>
1361
+ <div class="skeleton hero-image"></div>
1362
+ </div>
1363
+
1364
+ <div class="share-section">
1365
+ <div class="skeleton sk-label"></div>
1366
+ <div class="skeleton sk-input"></div>
1367
+ <div class="social-buttons">
1368
+ <div class="skeleton sk-btn-social"></div>
1369
+ <div class="skeleton sk-btn-social"></div>
1370
+ <div class="skeleton sk-btn-social"></div>
1371
+ <div class="skeleton sk-btn-social"></div>
1372
+ </div>
1373
+ </div>
1374
+
1375
+ <div
1376
+ class="skeleton sk-title-md"
1377
+ style="margin-top: 0; width: 30%; margin-left: auto; margin-right: auto"
1378
+ ></div>
1379
+ <div
1380
+ class="skeleton sk-text"
1381
+ style="width: 60%; margin-left: auto; margin-right: auto"
1382
+ ></div>
1383
+
1384
+ <div class="stats-section">
1385
+ <div class="stat-card">
1386
+ <div class="skeleton sk-stat-num"></div>
1387
+ <div class="skeleton sk-stat-label"></div>
1388
+ </div>
1389
+ <div class="stat-card stat-divider">
1390
+ <div class="skeleton sk-stat-num"></div>
1391
+ <div class="skeleton sk-stat-label"></div>
1392
+ </div>
1393
+ </div>
1394
+
1395
+ <div class="skeleton sk-title-md"></div>
1396
+
1397
+ <div class="table-header">
1398
+ <div class="skeleton sk-th col-user"></div>
1399
+ <div class="skeleton sk-th col-status"></div>
1400
+ <div class="skeleton sk-th col-reward"></div>
1401
+ <div class="skeleton sk-th col-date"></div>
1402
+ </div>
1403
+
1404
+ <div class="table-row">
1405
+ <div class="col-user">
1406
+ <div class="skeleton sk-text" style="width: 70%; margin: 0"></div>
1407
+ </div>
1408
+ <div class="col-status">
1409
+ <div class="skeleton sk-badge" style="margin: 0"></div>
1410
+ </div>
1411
+ <div class="col-reward">
1412
+ <div class="skeleton sk-reward-block" style="margin: 0"></div>
1413
+ </div>
1414
+ <div class="col-date">
1415
+ <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
1416
+ </div>
1417
+ </div>
1418
+ <div class="table-row">
1419
+ <div class="col-user">
1420
+ <div class="skeleton sk-text" style="width: 60%; margin: 0"></div>
1421
+ </div>
1422
+ <div class="col-status">
1423
+ <div class="skeleton sk-badge" style="margin: 0"></div>
1424
+ </div>
1425
+ <div class="col-reward">
1426
+ <div class="skeleton sk-reward-block" style="margin: 0"></div>
1427
+ </div>
1428
+ <div class="col-date">
1429
+ <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
1430
+ </div>
1431
+ </div>
1432
+ <div class="table-row">
1433
+ <div class="col-user">
1434
+ <div class="skeleton sk-text" style="width: 75%; margin: 0"></div>
1435
+ </div>
1436
+ <div class="col-status">
1437
+ <div class="skeleton sk-badge" style="margin: 0"></div>
1438
+ </div>
1439
+ <div class="col-reward">
1440
+ <div class="skeleton sk-reward-block" style="margin: 0"></div>
1441
+ </div>
1442
+ <div class="col-date">
1443
+ <div class="skeleton sk-text" style="width: 80%; margin: 0"></div>
1444
+ </div>
1445
+ </div>
1446
+
1447
+ <div class="pagination">
1448
+ <div class="skeleton sk-btn-page"></div>
1449
+ <div class="skeleton sk-btn-page"></div>
1450
+ </div>
1451
+ </div>
1452
+ `;
1453
+ };
1108
1454
  const _log$7 = browserExports.debug("squatch-js:EMBEDwidget");
1109
1455
  class EmbedWidget extends Widget {
1110
1456
  constructor(params, container) {
@@ -1114,10 +1460,13 @@ class EmbedWidget extends Widget {
1114
1460
  if (container) this.container = container;
1115
1461
  }
1116
1462
  async load() {
1117
- var _a2, _b, _c, _d, _e, _f, _g, _h;
1463
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1118
1464
  const brandingConfig = (_b = (_a2 = this.context.widgetConfig) == null ? void 0 : _a2.values) == null ? void 0 : _b.brandingConfig;
1119
- const initialHeight = (_e = (_d = (_c = this.context.widgetConfig) == null ? void 0 : _c.values) == null ? void 0 : _d.brandingConfig) == null ? void 0 : _e.loadingHeight;
1120
- const sizes = (_f = brandingConfig == null ? void 0 : brandingConfig.widgetSize) == null ? void 0 : _f.embeddedWidgets;
1465
+ const initialHeight = brandingConfig == null ? void 0 : brandingConfig.loadingHeight;
1466
+ const skeletonBackgroundColor = (_d = (_c = brandingConfig == null ? void 0 : brandingConfig.color) == null ? void 0 : _c.loadingSkeleton) == null ? void 0 : _d.background;
1467
+ const skeletonShimmerColor = (_f = (_e = brandingConfig == null ? void 0 : brandingConfig.color) == null ? void 0 : _e.loadingSkeleton) == null ? void 0 : _f.animationBackground;
1468
+ const borderColor = (_g = brandingConfig == null ? void 0 : brandingConfig.border) == null ? void 0 : _g.borderColor;
1469
+ const sizes = (_h = brandingConfig == null ? void 0 : brandingConfig.widgetSize) == null ? void 0 : _h.embeddedWidgets;
1121
1470
  const maxWidth = (sizes == null ? void 0 : sizes.maxWidth) ? formatWidth(sizes.maxWidth) : "";
1122
1471
  const minWidth = (sizes == null ? void 0 : sizes.minWidth) ? formatWidth(sizes.minWidth) : "";
1123
1472
  console.log({
@@ -1125,31 +1474,45 @@ class EmbedWidget extends Widget {
1125
1474
  initialHeight,
1126
1475
  widgetConfig: this.context.widgetConfig
1127
1476
  });
1477
+ const skeletonHTML = getSkeleton({
1478
+ height: initialHeight,
1479
+ skeletonBackgroundColor,
1480
+ skeletonShimmerColor,
1481
+ borderColor
1482
+ });
1483
+ const skeletonContainer = document.createElement("div");
1484
+ skeletonContainer.innerHTML = skeletonHTML;
1128
1485
  const frame = this._createFrame({
1129
1486
  minWidth,
1130
1487
  maxWidth,
1131
1488
  initialHeight
1132
1489
  });
1133
1490
  const element = this._findElement();
1134
- if ((_g = this.context) == null ? void 0 : _g.container) {
1491
+ frame.style.display = "none";
1492
+ const injectContents = (target) => {
1493
+ target.appendChild(skeletonContainer);
1494
+ target.appendChild(frame);
1495
+ };
1496
+ if ((_i = this.context) == null ? void 0 : _i.container) {
1135
1497
  element.style.visibility = "hidden";
1136
1498
  element.style.height = "0";
1137
1499
  element.style["overflow-y"] = "hidden";
1138
1500
  }
1139
1501
  if (this.container) {
1140
1502
  if (element.shadowRoot) {
1141
- if (((_h = element.shadowRoot.lastChild) == null ? void 0 : _h.nodeName) === "IFRAME") {
1503
+ if (((_j = element.shadowRoot.lastChild) == null ? void 0 : _j.nodeName) === "IFRAME") {
1142
1504
  element.shadowRoot.replaceChild(frame, element.shadowRoot.lastChild);
1143
1505
  } else {
1144
- element.shadowRoot.appendChild(frame);
1506
+ injectContents(element.shadowRoot);
1145
1507
  }
1146
1508
  } else if (element.firstChild) {
1147
- element.replaceChild(frame, element.firstChild);
1509
+ element.innerHTML = "";
1510
+ injectContents(element);
1148
1511
  } else {
1149
- element.appendChild(frame);
1512
+ injectContents(element);
1150
1513
  }
1151
1514
  } else if (!element.firstChild || element.firstChild.nodeName === "#text") {
1152
- element.appendChild(frame);
1515
+ injectContents(element);
1153
1516
  }
1154
1517
  const { contentWindow } = frame;
1155
1518
  if (!contentWindow) {
@@ -1157,16 +1520,29 @@ class EmbedWidget extends Widget {
1157
1520
  }
1158
1521
  const frameDoc = contentWindow.document;
1159
1522
  frameDoc.open();
1160
- console.log({ content: this.content });
1523
+ console.log({ content: this.content, context: this.context, this: this });
1524
+ const domain = this.widgetApi.domain;
1161
1525
  frameDoc.write(`
1526
+ ${((_k = brandingConfig == null ? void 0 : brandingConfig.main) == null ? void 0 : _k.brandFont) && `
1527
+ <link rel="preconnect" href="https://fast${domain === "https://staging.referralsaasquatch.com" && "-staging"}.ssqt.io">
1528
+ <link rel="preconnect" href="https://fonts.gstatic.com">
1529
+ <link rel="preconnect" href="https://fonts.googleapis.com">
1530
+ <link rel="preload" href="https://fonts.googleapis.com/css2?family=${encodeURIComponent(
1531
+ (_l = brandingConfig == null ? void 0 : brandingConfig.main) == null ? void 0 : _l.brandFont
1532
+ )}">`}
1162
1533
  <script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"><\/script>
1163
- ${this.content}
1164
- <style data-styles>
1165
- html:not(.hydrated) { visibility:hidden; }
1534
+ <style data-styles>
1535
+ html { visibility:hidden;}
1166
1536
  </style>
1537
+ ${this.content}
1538
+
1167
1539
  `);
1168
1540
  frameDoc.close();
1169
1541
  domready(frameDoc, async () => {
1542
+ if (skeletonContainer && skeletonContainer.parentNode) {
1543
+ skeletonContainer.parentNode.removeChild(skeletonContainer);
1544
+ }
1545
+ frame.style.display = "block";
1170
1546
  const _sqh = contentWindow.squatch || contentWindow.widgetIdent;
1171
1547
  frame.height = initialHeight || frameDoc.body.scrollHeight;
1172
1548
  console.log({ height: frameDoc.body.scrollHeight });
@@ -1805,7 +2181,8 @@ function _pushCookie() {
1805
2181
  }
1806
2182
  }
1807
2183
  const _log$3 = browserExports.debug("squatch-js");
1808
- function _getAutoConfig(configIn) {
2184
+ function _getAutoConfig() {
2185
+ var _a2;
1809
2186
  const queryString = window.location.search;
1810
2187
  const urlParams = new URLSearchParams(queryString);
1811
2188
  const refParam = urlParams.get("_saasquatchExtra") || "";
@@ -1813,6 +2190,13 @@ function _getAutoConfig(configIn) {
1813
2190
  _log$3("No _saasquatchExtra param");
1814
2191
  return;
1815
2192
  }
2193
+ const config = validateConfig({
2194
+ tenantAlias: "UNKNOWN"
2195
+ });
2196
+ if (!config.domain) {
2197
+ _log$3("domain must be provided in config to use _saasquatchExtra");
2198
+ return;
2199
+ }
1816
2200
  let raw;
1817
2201
  try {
1818
2202
  raw = JSON.parse(b64decode(refParam));
@@ -1820,8 +2204,13 @@ function _getAutoConfig(configIn) {
1820
2204
  _log$3("Unable to decode _saasquatchExtra config");
1821
2205
  return;
1822
2206
  }
1823
- const { domain, tenantAlias, widgetConfig } = convertExtraToConfig(raw);
1824
- if (!domain || !tenantAlias || !widgetConfig) {
2207
+ function normalizeDomain(domain) {
2208
+ return domain.replace(/^https?:\/\//, "");
2209
+ }
2210
+ const normalizedDomain = normalizeDomain(config.domain);
2211
+ const tenantAlias = Object.keys((raw == null ? void 0 : raw[normalizedDomain]) || {})[0];
2212
+ const widgetConfig = (_a2 = raw == null ? void 0 : raw[normalizedDomain]) == null ? void 0 : _a2[tenantAlias];
2213
+ if (!widgetConfig) {
1825
2214
  _log$3("_saasquatchExtra did not have an expected structure");
1826
2215
  return void 0;
1827
2216
  }
@@ -1833,20 +2222,11 @@ function _getAutoConfig(configIn) {
1833
2222
  ...rest
1834
2223
  },
1835
2224
  squatchConfig: {
1836
- ...configIn ? { configIn } : {},
1837
- domain,
2225
+ ...config,
1838
2226
  tenantAlias
1839
2227
  }
1840
2228
  };
1841
2229
  }
1842
- function convertExtraToConfig(obj) {
1843
- var _a2;
1844
- const _domain = Object.keys(obj || {})[0];
1845
- const tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
1846
- const widgetConfig = (_a2 = obj == null ? void 0 : obj[_domain]) == null ? void 0 : _a2[tenantAlias];
1847
- const domain = _domain ? `https://${_domain}` : void 0;
1848
- return { domain, tenantAlias, widgetConfig };
1849
- }
1850
2230
  const _log$2 = browserExports.debug("squatch-js:decodeUserJwt");
1851
2231
  function decodeUserJwt(tokenStr) {
1852
2232
  var _a2;
@@ -2159,9 +2539,9 @@ function widget(widgetConfig) {
2159
2539
  var _a2;
2160
2540
  return (_a2 = widgets()) == null ? void 0 : _a2.render(widgetConfig);
2161
2541
  }
2162
- function _auto(configIn) {
2542
+ function _auto() {
2163
2543
  var _a2;
2164
- const configs = _getAutoConfig(configIn);
2544
+ const configs = _getAutoConfig();
2165
2545
  if (configs) {
2166
2546
  const { squatchConfig, widgetConfig } = configs;
2167
2547
  init(squatchConfig);