@saasquatch/squatch-js 2.4.3 → 2.5.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.
package/dist/squatch.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var debug = require('debug');
2
2
  var EventBus = require('eventbusjs');
3
- var superagent = require('superagent');
4
3
  var Cookies = require('js-cookie');
4
+ var superagent = require('superagent');
5
5
 
6
6
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
7
 
@@ -28,8 +28,8 @@ function _interopNamespace(e) {
28
28
  var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
29
29
  var debug__namespace = /*#__PURE__*/_interopNamespace(debug);
30
30
  var EventBus__namespace = /*#__PURE__*/_interopNamespace(EventBus);
31
- var superagent__namespace = /*#__PURE__*/_interopNamespace(superagent);
32
31
  var Cookies__default = /*#__PURE__*/_interopDefaultLegacy(Cookies);
32
+ var superagent__namespace = /*#__PURE__*/_interopNamespace(superagent);
33
33
 
34
34
  function _extends() {
35
35
  _extends = Object.assign || function (target) {
@@ -49,6 +49,45 @@ function _extends() {
49
49
  return _extends.apply(this, arguments);
50
50
  }
51
51
 
52
+ function _objectWithoutPropertiesLoose(source, excluded) {
53
+ if (source == null) return {};
54
+ var target = {};
55
+ var sourceKeys = Object.keys(source);
56
+ var key, i;
57
+
58
+ for (i = 0; i < sourceKeys.length; i++) {
59
+ key = sourceKeys[i];
60
+ if (excluded.indexOf(key) >= 0) continue;
61
+ target[key] = source[key];
62
+ }
63
+
64
+ return target;
65
+ }
66
+
67
+ function doQuery(url, query, variables, token) {
68
+ const headers = _extends({
69
+ Accept: "application/json"
70
+ }, token ? {
71
+ Authorization: `Bearer ${token}`
72
+ } : {}, {
73
+ "X-SaaSquatch-Referrer": window ? window.location.href : ""
74
+ });
75
+
76
+ const request = superagent__namespace.post(url).send({
77
+ query,
78
+ variables
79
+ }).set(headers);
80
+ return thenableSuperagent(request).then(response => response, error => {
81
+ let json;
82
+
83
+ try {
84
+ json = JSON.parse(error.response.text);
85
+ } catch (e) {
86
+ }
87
+
88
+ throw json;
89
+ });
90
+ }
52
91
  function doGet(url, jwt = "") {
53
92
  const headers = {
54
93
  Accept: "application/json",
@@ -185,12 +224,37 @@ function validateConfig(raw) {
185
224
  npmCdn
186
225
  };
187
226
  }
227
+ function validateLocale(locale) {
228
+ if (locale && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(locale)) {
229
+ return locale;
230
+ }
231
+ }
188
232
  function validateWidgetConfig(raw) {
189
233
  if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
190
234
  if (!assertProp(raw, "user")) ; // TODO: This should be better type checked
191
235
 
192
236
  return raw;
193
237
  }
238
+ function validatePasswordlessConfig(raw) {
239
+ if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
240
+ return raw;
241
+ }
242
+
243
+ const RENDER_WIDGET_QUERY = `
244
+ query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {
245
+ renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {
246
+ template
247
+ user {
248
+ id
249
+ accountId
250
+ }
251
+ jsOptions
252
+ widgetConfig {
253
+ values
254
+ }
255
+ }
256
+ }
257
+ `;
194
258
 
195
259
  /**
196
260
  *
@@ -223,39 +287,6 @@ class WidgetApi {
223
287
  this.domain = clean.domain;
224
288
  this.npmCdn = clean.npmCdn;
225
289
  }
226
- /**
227
- * Creates/upserts an anonymous user.
228
- *
229
- * @param {Object} params Parameters for request
230
- * @param {WidgetType} params.widgetType The content of the widget.
231
- * @param {EngagementMedium} params.engagementMedium How to display the widget.
232
- * @param {CookieUser} params.user An optional user object
233
- * @param {string} params.jwt the JSON Web Token (JWT) that is used to
234
- * validate the data (can be disabled)
235
- *
236
- * @return {Promise} json object if true, with the widget template, jsOptions and user details.
237
- */
238
-
239
-
240
- cookieUser(params) {
241
- // validateInput(params, CookieUserSchema);
242
- const {
243
- widgetType,
244
- engagementMedium = "POPUP",
245
- jwt,
246
- user
247
- } = params;
248
- const tenantAlias = encodeURIComponent(this.tenantAlias);
249
-
250
- const optionalParams = _buildParams({
251
- widgetType,
252
- engagementMedium
253
- });
254
-
255
- const path = `/api/v1/${tenantAlias}/widget/user/cookie_user${optionalParams}`;
256
- const url = this.domain + path;
257
- return doPut(url, JSON.stringify(user ? user : {}), jwt);
258
- }
259
290
  /**
260
291
  * Creates/upserts user.
261
292
  *
@@ -312,8 +343,10 @@ class WidgetApi {
312
343
 
313
344
 
314
345
  render(params) {
346
+ var _clean$locale;
347
+
315
348
  const raw = params;
316
- const clean = validateWidgetConfig(raw);
349
+ const clean = validatePasswordlessConfig(raw);
317
350
  const {
318
351
  widgetType,
319
352
  engagementMedium = "POPUP",
@@ -321,17 +354,29 @@ class WidgetApi {
321
354
  user
322
355
  } = clean;
323
356
  const tenantAlias = encodeURIComponent(this.tenantAlias);
324
- const accountId = encodeURIComponent(user.accountId);
325
- const userId = encodeURIComponent(user.id);
326
-
327
- const optionalParams = _buildParams({
328
- widgetType,
329
- engagementMedium
330
- });
331
-
332
- const path = `/api/v1/${tenantAlias}/widget/account/${accountId}/user/${userId}/render${optionalParams}`;
357
+ const accountId = user ? encodeURIComponent(user.accountId) : null;
358
+ const userId = user ? encodeURIComponent(user.id) : null;
359
+ const locale = (_clean$locale = clean.locale) != null ? _clean$locale : validateLocale(navigator.language.replace(/\-/g, "_"));
360
+ const path = `/api/v1/${tenantAlias}/graphql`;
333
361
  const url = this.domain + path;
334
- return doGet(url, jwt);
362
+ return new Promise(async (resolve, reject) => {
363
+ try {
364
+ var _res$body, _res$body$data;
365
+
366
+ const res = await doQuery(url, RENDER_WIDGET_QUERY, {
367
+ user: userId && accountId ? {
368
+ id: userId,
369
+ accountId
370
+ } : null,
371
+ engagementMedium,
372
+ widgetType,
373
+ locale
374
+ }, jwt);
375
+ resolve(res == null ? void 0 : (_res$body = res.body) == null ? void 0 : (_res$body$data = _res$body.data) == null ? void 0 : _res$body$data.renderWidget);
376
+ } catch (e) {
377
+ reject(e);
378
+ }
379
+ });
335
380
  }
336
381
  /**
337
382
  * An API call to send out referral invites to contacts
@@ -422,6 +467,7 @@ class AnalyticsApi {
422
467
  }
423
468
 
424
469
  pushAnalyticsLoadEvent(params) {
470
+ if (!params.externalUserId || !params.externalAccountId) return;
425
471
  const tenantAlias = encodeURIComponent(params.tenantAlias);
426
472
  const accountId = encodeURIComponent(params.externalAccountId);
427
473
  const userId = encodeURIComponent(params.externalUserId);
@@ -448,7 +494,7 @@ class AnalyticsApi {
448
494
  // @ts-check
449
495
  /** @hidden */
450
496
 
451
- const _log$6 = debug__default['default']("squatch-js:widget");
497
+ const _log$7 = debug__default['default']("squatch-js:widget");
452
498
  /*
453
499
  * The Widget class is the base class for the different widget types available
454
500
  *
@@ -461,7 +507,7 @@ const _log$6 = debug__default['default']("squatch-js:widget");
461
507
 
462
508
  class Widget {
463
509
  constructor(params) {
464
- _log$6("widget initializing ...");
510
+ _log$7("widget initializing ...");
465
511
 
466
512
  this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
467
513
  this.type = params.type;
@@ -479,6 +525,8 @@ class Widget {
479
525
  }
480
526
 
481
527
  _loadEvent(sqh) {
528
+ var _this$analyticsApi$pu;
529
+
482
530
  if (!sqh) return; // No non-truthy value
483
531
 
484
532
  if (!isObject$1(sqh)) {
@@ -512,10 +560,10 @@ class Widget {
512
560
  };
513
561
  }
514
562
 
515
- this.analyticsApi.pushAnalyticsLoadEvent(params).then(response => {
516
- _log$6(`${params.engagementMedium} loaded event recorded.`);
563
+ (_this$analyticsApi$pu = this.analyticsApi.pushAnalyticsLoadEvent(params)) == null ? void 0 : _this$analyticsApi$pu.then(response => {
564
+ _log$7(`${params.engagementMedium} loaded event recorded.`);
517
565
  }).catch(ex => {
518
- _log$6(new Error(`pushAnalyticsLoadEvent() ${ex}`));
566
+ _log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
519
567
  });
520
568
  }
521
569
 
@@ -528,9 +576,9 @@ class Widget {
528
576
  engagementMedium: sqh.mode.widgetMode,
529
577
  shareMedium: medium
530
578
  }).then(response => {
531
- _log$6(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
579
+ _log$7(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
532
580
  }).catch(ex => {
533
- _log$6(new Error(`pushAnalyticsLoadEvent() ${ex}`));
581
+ _log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
534
582
  });
535
583
  }
536
584
  }
@@ -543,9 +591,9 @@ class Widget {
543
591
  userId: sqh.analytics.attributes.userId,
544
592
  emailList
545
593
  }).then(response => {
546
- _log$6(`Sent email invites to share ${emailList}. ${response}`);
594
+ _log$7(`Sent email invites to share ${emailList}. ${response}`);
547
595
  }).catch(ex => {
548
- _log$6(new Error(`invite() ${ex}`));
596
+ _log$7(new Error(`invite() ${ex}`));
549
597
  });
550
598
  }
551
599
  }
@@ -634,6 +682,7 @@ class Widget {
634
682
  email: email || null,
635
683
  firstName: firstName || null,
636
684
  lastName: lastName || null,
685
+ // FIXME: Double check this
637
686
  id: this.context.user.id,
638
687
  accountId: this.context.user.accountId
639
688
  };
@@ -643,17 +692,12 @@ class Widget {
643
692
  widgetType: this.type,
644
693
  jwt
645
694
  });
646
- } else if (this.context.type === "cookie") {
647
- let userObj = {
648
- email: email || null,
649
- firstName: firstName || null,
650
- lastName: lastName || null
651
- };
652
- response = this.widgetApi.cookieUser({
653
- user: userObj,
695
+ } else if (this.context.type === "passwordless") {
696
+ response = this.widgetApi.render({
697
+ user: undefined,
654
698
  engagementMedium,
655
699
  widgetType: this.type,
656
- jwt
700
+ jwt: undefined
657
701
  });
658
702
  } else {
659
703
  throw new Error("can't reload an error widget");
@@ -689,7 +733,7 @@ class Widget {
689
733
  }).catch(({
690
734
  message
691
735
  }) => {
692
- _log$6(`${message}`);
736
+ _log$7(`${message}`);
693
737
  });
694
738
  }
695
739
 
@@ -726,7 +770,7 @@ function domready(targetDoc, fn) {
726
770
 
727
771
  // @ts-check
728
772
 
729
- const _log$5 = debug__default['default']("squatch-js:EMBEDwidget");
773
+ const _log$6 = debug__default['default']("squatch-js:EMBEDwidget");
730
774
  /**
731
775
  * An EmbedWidget is displayed inline in part of your page.
732
776
  *
@@ -744,22 +788,22 @@ class EmbedWidget extends Widget {
744
788
  // selector is a string
745
789
  element = document.querySelector(container);
746
790
 
747
- _log$5("loading widget with selector", element); // selector is an HTML element
791
+ _log$6("loading widget with selector", element); // selector is an HTML element
748
792
 
749
793
  } else if (container instanceof HTMLElement) {
750
794
  element = container;
751
795
 
752
- _log$5("loading widget with container", element); // garbage container found
796
+ _log$6("loading widget with container", element); // garbage container found
753
797
 
754
798
  } else if (container) {
755
799
  element = null;
756
800
 
757
- _log$5("container must be an HTMLElement or string", container); // find element on page
801
+ _log$6("container must be an HTMLElement or string", container); // find element on page
758
802
 
759
803
  } else {
760
804
  element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed");
761
805
 
762
- _log$5("loading widget with default selector", element);
806
+ _log$6("loading widget with default selector", element);
763
807
  }
764
808
 
765
809
  if (!(element instanceof HTMLElement)) throw new Error(`element with selector '${container}' not found.'`);
@@ -825,7 +869,7 @@ class EmbedWidget extends Widget {
825
869
  if (!this.context.container) {
826
870
  this._loadEvent(_sqh);
827
871
 
828
- _log$5("loaded");
872
+ _log$6("loaded");
829
873
  }
830
874
  });
831
875
  } // Un-hide if element is available and refresh data
@@ -834,7 +878,7 @@ class EmbedWidget extends Widget {
834
878
  open() {
835
879
  var _this$frame, _this$frame$contentDo, _this$frame2, _this$frame2$contentW, _this$frame3, _this$frame3$contentW;
836
880
 
837
- if (!this.frame) return _log$5("no target element to open");
881
+ if (!this.frame) return _log$6("no target element to open");
838
882
  this.element.style.visibility = "unset";
839
883
  this.element.style.height = "auto";
840
884
  this.element.style["overflow-y"] = "auto";
@@ -844,16 +888,16 @@ class EmbedWidget extends Widget {
844
888
 
845
889
  this._loadEvent(_sqh);
846
890
 
847
- _log$5("loaded");
891
+ _log$6("loaded");
848
892
  }
849
893
 
850
894
  close() {
851
- if (!this.frame) return _log$5("no target element to close");
895
+ if (!this.frame) return _log$6("no target element to close");
852
896
  this.element.style.visibility = "hidden";
853
897
  this.element.style.height = "0";
854
898
  this.element.style["overflow-y"] = "hidden";
855
899
 
856
- _log$5("Embed widget closed");
900
+ _log$6("Embed widget closed");
857
901
  }
858
902
 
859
903
  _error(rs, mode = "embed", style = "") {
@@ -864,7 +908,7 @@ class EmbedWidget extends Widget {
864
908
 
865
909
  // @ts-check
866
910
 
867
- const _log$4 = debug__default['default']("squatch-js:POPUPwidget");
911
+ const _log$5 = debug__default['default']("squatch-js:POPUPwidget");
868
912
  /**
869
913
  * The PopupWidget is used to display popups (also known as "Modals").
870
914
  * Popups widgets are rendered on top of other elements in a page.
@@ -882,9 +926,9 @@ class PopupWidget extends Widget {
882
926
  this.triggerElement
883
927
  /* HTMLButton */
884
928
  = document.querySelector(trigger);
885
- if (trigger && !this.triggerElement) _log$4("No element found with trigger selector", trigger);
929
+ if (trigger && !this.triggerElement) _log$5("No element found with trigger selector", trigger);
886
930
  } catch (_unused) {
887
- _log$4("Not a valid selector", trigger);
931
+ _log$5("Not a valid selector", trigger);
888
932
  } // Trigger is optional
889
933
 
890
934
 
@@ -907,6 +951,7 @@ class PopupWidget extends Widget {
907
951
  this.popupdiv = document.createElement("div");
908
952
  this.popupdiv.id = "squatchModal";
909
953
  this.popupdiv.setAttribute("style", "display: none; position: fixed; z-index: 1; padding-top: 5%; left: 0; top: -2000px; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4);");
954
+ document.head.insertAdjacentHTML("beforeend", `<style>#squatchModal::-webkit-scrollbar { display: none; }</style>`);
910
955
  this.popupcontent = document.createElement("div");
911
956
  this.popupcontent.setAttribute("style", "margin: auto; width: 80%; max-width: 500px; position: relative;");
912
957
 
@@ -926,7 +971,7 @@ class PopupWidget extends Widget {
926
971
  frameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
927
972
  frameDoc.close();
928
973
 
929
- _log$4("Popup template loaded into iframe");
974
+ _log$5("Popup template loaded into iframe");
930
975
 
931
976
  this._setupResizeHandler();
932
977
  }
@@ -999,7 +1044,7 @@ class PopupWidget extends Widget {
999
1044
 
1000
1045
  this._loadEvent(_sqh);
1001
1046
 
1002
- _log$4("Popup opened");
1047
+ _log$5("Popup opened");
1003
1048
  });
1004
1049
  }
1005
1050
 
@@ -1007,7 +1052,7 @@ class PopupWidget extends Widget {
1007
1052
  this.popupdiv.style.visibility = "hidden";
1008
1053
  this.popupdiv.style.top = "-2000px";
1009
1054
 
1010
- _log$4("Popup closed");
1055
+ _log$5("Popup closed");
1011
1056
  }
1012
1057
 
1013
1058
  _clickedOutside({
@@ -1025,7 +1070,7 @@ class PopupWidget extends Widget {
1025
1070
 
1026
1071
  }
1027
1072
 
1028
- const _log$3 = debug__namespace("squatch-js:CTAwidget");
1073
+ const _log$4 = debug__namespace("squatch-js:CTAwidget");
1029
1074
  /**
1030
1075
  * A CtaWidget is displayed on top of your page
1031
1076
  *
@@ -1036,7 +1081,7 @@ const _log$3 = debug__namespace("squatch-js:CTAwidget");
1036
1081
 
1037
1082
  class CtaWidget extends PopupWidget {
1038
1083
  constructor(params, opts) {
1039
- _log$3("CTA constructor");
1084
+ _log$4("CTA constructor");
1040
1085
 
1041
1086
  const ctaElement = document.createElement("div");
1042
1087
  ctaElement.id = "cta";
@@ -1064,7 +1109,7 @@ class CtaWidget extends PopupWidget {
1064
1109
  this.ctaFrame.setAttribute("style", `border:0; background-color:transparent; position:fixed; display:none;${this.side}${this.position}`);
1065
1110
  document.body.appendChild(this.ctaFrame);
1066
1111
 
1067
- _log$3("ctaframe appended to body");
1112
+ _log$4("ctaframe appended to body");
1068
1113
  }
1069
1114
 
1070
1115
  load() {
@@ -1128,10 +1173,10 @@ class CtaWidget extends PopupWidget {
1128
1173
  });
1129
1174
  ro.observe(ctaContainer);
1130
1175
 
1131
- _log$3("CTA template loaded into iframe");
1176
+ _log$4("CTA template loaded into iframe");
1132
1177
  });
1133
1178
  } else {
1134
- _log$3(new Error("CTA element not found in theme"));
1179
+ _log$4(new Error("CTA element not found in theme"));
1135
1180
  }
1136
1181
  });
1137
1182
  }
@@ -1154,7 +1199,7 @@ class CtaWidget extends PopupWidget {
1154
1199
 
1155
1200
  }
1156
1201
 
1157
- const _log$2 = debug__default['default']("squatch-js:widgets");
1202
+ const _log$3 = debug__default['default']("squatch-js:widgets");
1158
1203
  /**
1159
1204
  *
1160
1205
  * `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
@@ -1192,41 +1237,6 @@ class Widgets {
1192
1237
 
1193
1238
  EventBus__namespace.addEventListener("submit_email", Widgets._cb);
1194
1239
  }
1195
- /**
1196
- * This function calls the {@link WidgetApi.cookieUser} method, and it renders
1197
- * the widget if it is successful. Otherwise it shows the "error" widget.
1198
- *
1199
- * @param {Object} config Config details
1200
- * @param {WidgetType} config.widgetType The content of the widget.
1201
- * @param {EngagementMedium} config.engagementMedium How to display the widget.
1202
- * @param {User} config.user An optional user to include
1203
- * @param {string} config.jwt the JSON Web Token (JWT) that is used to
1204
- * validate the data (can be disabled)
1205
- *
1206
- * @return {Promise<WidgetResult>} json object if true, with a Widget and user details.
1207
- */
1208
-
1209
-
1210
- async createCookieUser(config) {
1211
- try {
1212
- const response = await this.api.cookieUser(config);
1213
- return {
1214
- widget: this._renderWidget(response, config, {
1215
- type: "cookie",
1216
- engagementMedium: config.engagementMedium
1217
- }),
1218
- user: response.user
1219
- };
1220
- } catch (err) {
1221
- _log$2(err);
1222
-
1223
- if (err.apiErrorCode) {
1224
- this._renderErrorWidget(err, config.engagementMedium);
1225
- }
1226
-
1227
- throw err;
1228
- }
1229
- }
1230
1240
  /**
1231
1241
  * This function calls the {@link WidgetApi.upsertUser} method, and it renders
1232
1242
  * the widget if it is successful. Otherwise it shows the "error" widget.
@@ -1254,7 +1264,7 @@ class Widgets {
1254
1264
  return {
1255
1265
  widget: this._renderWidget(response, clean, {
1256
1266
  type: "upsert",
1257
- user: clean.user,
1267
+ user: clean.user || null,
1258
1268
  engagementMedium: config.engagementMedium,
1259
1269
  container: config.container,
1260
1270
  trigger: config.trigger
@@ -1262,7 +1272,7 @@ class Widgets {
1262
1272
  user: response.user
1263
1273
  };
1264
1274
  } catch (err) {
1265
- _log$2(err);
1275
+ _log$3(err);
1266
1276
 
1267
1277
  if (err.apiErrorCode) {
1268
1278
  this._renderErrorWidget(err, config.engagementMedium);
@@ -1290,15 +1300,13 @@ class Widgets {
1290
1300
 
1291
1301
  async render(config) {
1292
1302
  const raw = config;
1293
- const clean = validateWidgetConfig(raw);
1303
+ const clean = validatePasswordlessConfig(raw);
1294
1304
 
1295
1305
  try {
1296
- const response = await this.api.cookieUser(clean);
1306
+ const response = await this.api.render(clean);
1297
1307
  return {
1298
- widget: this._renderWidget({
1299
- template: response
1300
- }, clean, {
1301
- type: "cookie",
1308
+ widget: this._renderWidget(response, clean, {
1309
+ type: "passwordless",
1302
1310
  engagementMedium: clean.engagementMedium
1303
1311
  }),
1304
1312
  user: response.user
@@ -1325,7 +1333,7 @@ class Widgets {
1325
1333
 
1326
1334
  if (typeof input === "function") {
1327
1335
  this.api.squatchReferralCookie().then((...args) => input(...args)).catch(ex => {
1328
- _log$2("Autofill error", ex);
1336
+ _log$3("Autofill error", ex);
1329
1337
 
1330
1338
  throw ex;
1331
1339
  });
@@ -1340,7 +1348,7 @@ class Widgets {
1340
1348
  // Only use the first element found
1341
1349
  elem = elems[0];
1342
1350
  } else {
1343
- _log$2("Element id/class or function missing");
1351
+ _log$3("Element id/class or function missing");
1344
1352
 
1345
1353
  throw new Error("Element id/class or function missing");
1346
1354
  }
@@ -1378,11 +1386,11 @@ class Widgets {
1378
1386
 
1379
1387
 
1380
1388
  _renderWidget(response, config, context) {
1381
- _log$2("Rendering Widget...");
1389
+ _log$3("Rendering Widget...");
1382
1390
 
1383
1391
  if (!response) throw new Error("Unable to get a response");
1384
1392
  let widget;
1385
- let displayOnLoad = false;
1393
+ let displayOnLoad = !!config.displayOnLoad;
1386
1394
  let displayCTA = false;
1387
1395
  const opts = response.jsOptions || "";
1388
1396
  const params = {
@@ -1401,9 +1409,9 @@ class Widgets {
1401
1409
  displayOnLoad = rule.displayOnLoad;
1402
1410
  displayCTA = rule.showAsCTA;
1403
1411
 
1404
- _log$2(`Display ${rule.widgetType} on ${rule.url}`);
1412
+ _log$3(`Display ${rule.widgetType} on ${rule.url}`);
1405
1413
  } else {
1406
- _log$2(`Don't display ${rule.widgetType} when no referral on widget rule match ${rule.url}`);
1414
+ _log$3(`Don't display ${rule.widgetType} when no referral on widget rule match ${rule.url}`);
1407
1415
  }
1408
1416
  }
1409
1417
  });
@@ -1412,20 +1420,20 @@ class Widgets {
1412
1420
  if (opts.conversionUrls) {
1413
1421
  opts.conversionUrls.forEach(rule => {
1414
1422
  if (response.user.referredBy && Widgets._matchesUrl(rule)) {
1415
- _log$2("This is a conversion URL", rule);
1423
+ _log$3("This is a conversion URL", rule);
1416
1424
  }
1417
1425
  });
1418
1426
  }
1419
1427
 
1420
1428
  if (opts.fuelTankAutofillUrls) {
1421
- _log$2("We found a fuel tank autofill!");
1429
+ _log$3("We found a fuel tank autofill!");
1422
1430
 
1423
1431
  opts.fuelTankAutofillUrls.forEach(({
1424
1432
  url,
1425
1433
  formSelector
1426
1434
  }) => {
1427
1435
  if (Widgets._matchesUrl(url)) {
1428
- _log$2("Fuel Tank URL matches");
1436
+ _log$3("Fuel Tank URL matches");
1429
1437
 
1430
1438
  if (response.user.referredBy && response.user.referredBy.code) {
1431
1439
  const formAutofill = document.querySelector(formSelector);
@@ -1433,7 +1441,7 @@ class Widgets {
1433
1441
  if (formAutofill) {
1434
1442
  formAutofill.value = response.user.referredBy.referredReward.fuelTankCode || "";
1435
1443
  } else {
1436
- _log$2(new Error(`Element with id/class ${formSelector} was not found.`));
1444
+ _log$3(new Error(`Element with id/class ${formSelector} was not found.`));
1437
1445
  }
1438
1446
  }
1439
1447
  }
@@ -1448,7 +1456,7 @@ class Widgets {
1448
1456
  widget.load();
1449
1457
  if (displayOnLoad) widget.open();
1450
1458
  } else if (displayCTA) {
1451
- _log$2("display CTA");
1459
+ _log$3("display CTA");
1452
1460
 
1453
1461
  const side = opts.cta.content.buttonSide;
1454
1462
  const position = opts.cta.content.buttonPosition;
@@ -1459,7 +1467,7 @@ class Widgets {
1459
1467
  widget.load();
1460
1468
  if (displayOnLoad) widget.open();
1461
1469
  } else {
1462
- _log$2("display popup on load");
1470
+ _log$3("display popup on load");
1463
1471
 
1464
1472
  widget = new PopupWidget(params);
1465
1473
  widget.load();
@@ -1483,7 +1491,7 @@ class Widgets {
1483
1491
  message
1484
1492
  } = props;
1485
1493
 
1486
- _log$2(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
1494
+ _log$3(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
1487
1495
 
1488
1496
  const params = {
1489
1497
  content: "error",
@@ -1623,7 +1631,8 @@ function asyncLoad() {
1623
1631
 
1624
1632
  if (loaded && cached) {
1625
1633
  const ready = cached.ready || [];
1626
- ready.forEach(cb => setTimeout(() => cb(), 0)); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
1634
+ ready.forEach(cb => setTimeout(() => cb(), 0));
1635
+ setTimeout(() => window.squatch._auto(), 0); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
1627
1636
 
1628
1637
  window._squatch = undefined;
1629
1638
 
@@ -2013,7 +2022,7 @@ var URLSearchParams$1 = self.URLSearchParams;
2013
2022
 
2014
2023
  /** @hidden */
2015
2024
 
2016
- const _log$1 = debug__default['default']("squatch-js");
2025
+ const _log$2 = debug__default['default']("squatch-js");
2017
2026
 
2018
2027
  const isObject = item => typeof item === "object" && !Array.isArray(item);
2019
2028
 
@@ -2066,7 +2075,7 @@ function _pushCookie() {
2066
2075
  try {
2067
2076
  paramsJSON = JSON.parse(b64decode(refParam));
2068
2077
  } catch (error) {
2069
- _log$1("Unable to decode params", error); // don't merge invalid params
2078
+ _log$2("Unable to decode params", error); // don't merge invalid params
2070
2079
 
2071
2080
 
2072
2081
  return;
@@ -2075,26 +2084,26 @@ function _pushCookie() {
2075
2084
  try {
2076
2085
  existingCookie = JSON.parse(b64decode(Cookies__default['default'].get("_saasquatch")));
2077
2086
 
2078
- _log$1("existing cookie", existingCookie);
2087
+ _log$2("existing cookie", existingCookie);
2079
2088
  } catch (error) {
2080
- _log$1("Unable to retrieve cookie", error);
2089
+ _log$2("Unable to retrieve cookie", error);
2081
2090
  } // don't merge if there's no existing object
2082
2091
 
2083
2092
 
2084
2093
  try {
2085
2094
  const domain = getTopDomain();
2086
2095
 
2087
- _log$1("domain retrieved:", domain);
2096
+ _log$2("domain retrieved:", domain);
2088
2097
 
2089
2098
  if (existingCookie) {
2090
2099
  const newCookie = deepMerge(existingCookie, paramsJSON);
2091
2100
  reEncodedCookie = b64encode(JSON.stringify(newCookie));
2092
2101
 
2093
- _log$1("cookie to store:", newCookie);
2102
+ _log$2("cookie to store:", newCookie);
2094
2103
  } else {
2095
2104
  reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
2096
2105
 
2097
- _log$1("cookie to store:", paramsJSON);
2106
+ _log$2("cookie to store:", paramsJSON);
2098
2107
  }
2099
2108
 
2100
2109
  Cookies__default['default'].set("_saasquatch", reEncodedCookie, {
@@ -2105,11 +2114,86 @@ function _pushCookie() {
2105
2114
  path: "/"
2106
2115
  });
2107
2116
  } catch (error) {
2108
- _log$1("Unable to set cookie", error);
2117
+ _log$2("Unable to set cookie", error);
2109
2118
  }
2110
2119
  }
2111
2120
  }
2112
2121
 
2122
+ /** @hidden */
2123
+
2124
+ const _log$1 = debug__default['default']("squatch-js");
2125
+
2126
+ function _getAutoConfig(configIn) {
2127
+ const queryString = window.location.search;
2128
+ const urlParams = new URLSearchParams(queryString);
2129
+ const refParam = urlParams.get("_saasquatchExtra") || "";
2130
+
2131
+ if (!refParam) {
2132
+ _log$1("No _saasquatchExtra param");
2133
+
2134
+ return;
2135
+ }
2136
+
2137
+ let raw;
2138
+
2139
+ try {
2140
+ raw = JSON.parse(b64decode(refParam));
2141
+ } catch (e) {
2142
+ _log$1("Unable to decode _saasquatchExtra config");
2143
+
2144
+ return;
2145
+ }
2146
+
2147
+ const {
2148
+ domain,
2149
+ tenantAlias,
2150
+ widgetConfig
2151
+ } = convertExtraToConfig(raw);
2152
+
2153
+ if (!domain || !tenantAlias || !widgetConfig) {
2154
+ _log$1("_saasquatchExtra did not have an expected structure");
2155
+
2156
+ return undefined;
2157
+ }
2158
+
2159
+ const {
2160
+ autoPopupWidgetType
2161
+ } = widgetConfig,
2162
+ rest = _objectWithoutPropertiesLoose(widgetConfig, ["autoPopupWidgetType"]);
2163
+
2164
+ return {
2165
+ widgetConfig: _extends({
2166
+ widgetType: autoPopupWidgetType,
2167
+ displayOnLoad: true
2168
+ }, rest),
2169
+ squatchConfig: _extends({}, configIn ? {
2170
+ configIn
2171
+ } : {}, {
2172
+ domain,
2173
+ tenantAlias
2174
+ })
2175
+ };
2176
+ }
2177
+ /**
2178
+ * Deconstructs _saasquatchExtra into domain, tenantAlias, and widgetConfig
2179
+ * @param obj {Record<string, any>} Expected to be of the form `{ [appDomain]: { [tenantAlias]: { autoPopupWidgetType: [widgetType], [rest]?: ... } } }`
2180
+ */
2181
+
2182
+ function convertExtraToConfig(obj) {
2183
+ var _obj$_domain;
2184
+
2185
+ const _domain = Object.keys(obj || {})[0];
2186
+ const tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
2187
+ const widgetConfig = obj == null ? void 0 : (_obj$_domain = obj[_domain]) == null ? void 0 : _obj$_domain[tenantAlias]; // domain in _saasquatchExtra doesn't contain "https://"
2188
+
2189
+ const domain = _domain ? `https://${_domain}` : undefined;
2190
+ return {
2191
+ domain,
2192
+ tenantAlias,
2193
+ widgetConfig
2194
+ };
2195
+ }
2196
+
2113
2197
  // @ts-check
2114
2198
  function help() {
2115
2199
  console.log(`Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.`);
@@ -2163,6 +2247,33 @@ function widgets() {
2163
2247
  function events() {
2164
2248
  return _events;
2165
2249
  }
2250
+ /**
2251
+ * Entry-point for high level API to render a widget using the instance of {@link Widgets} created when you call {@link #init init}.
2252
+ */
2253
+
2254
+ function widget(widgetConfig) {
2255
+ var _widgets2;
2256
+
2257
+ return (_widgets2 = widgets()) == null ? void 0 : _widgets2.render(widgetConfig);
2258
+ }
2259
+ /**
2260
+ * Extracts widget configuration from `_saasquatchExtra` UTM parameter. Initialises `squatch` and renders the widget as a {@link PopupWidget} via static instanct of {@link Widgets}.
2261
+ */
2262
+
2263
+ function _auto(configIn) {
2264
+ const configs = _getAutoConfig(configIn);
2265
+
2266
+ if (configs) {
2267
+ var _widgets3;
2268
+
2269
+ const {
2270
+ squatchConfig,
2271
+ widgetConfig
2272
+ } = configs;
2273
+ init(squatchConfig);
2274
+ return (_widgets3 = widgets()) == null ? void 0 : _widgets3.render(widgetConfig);
2275
+ }
2276
+ }
2166
2277
  /**
2167
2278
  * Initializes the static `squatch` global. This sets up:
2168
2279
  *
@@ -2205,7 +2316,7 @@ function init(configIn) {
2205
2316
  * @example
2206
2317
  * squatch.ready(function() {
2207
2318
  * console.log("ready!");
2208
- * squatch.api().cookieUser();
2319
+ * squatch.api().upsertUser();
2209
2320
  * });
2210
2321
  */
2211
2322
 
@@ -2272,6 +2383,7 @@ exports.EmbedWidget = EmbedWidget;
2272
2383
  exports.PopupWidget = PopupWidget;
2273
2384
  exports.WidgetApi = WidgetApi;
2274
2385
  exports.Widgets = Widgets;
2386
+ exports._auto = _auto;
2275
2387
  exports.api = api;
2276
2388
  exports.autofill = autofill;
2277
2389
  exports.events = events;
@@ -2280,5 +2392,6 @@ exports.init = init;
2280
2392
  exports.pushCookie = pushCookie;
2281
2393
  exports.ready = ready;
2282
2394
  exports.submitEmail = submitEmail;
2395
+ exports.widget = widget;
2283
2396
  exports.widgets = widgets;
2284
2397
  //# sourceMappingURL=squatch.js.map