@saasquatch/squatch-js 2.5.0-0 → 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,9 +28,66 @@ 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
+
34
+ function _extends() {
35
+ _extends = Object.assign || function (target) {
36
+ for (var i = 1; i < arguments.length; i++) {
37
+ var source = arguments[i];
38
+
39
+ for (var key in source) {
40
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
41
+ target[key] = source[key];
42
+ }
43
+ }
44
+ }
45
+
46
+ return target;
47
+ };
48
+
49
+ return _extends.apply(this, arguments);
50
+ }
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
+ }
33
87
 
88
+ throw json;
89
+ });
90
+ }
34
91
  function doGet(url, jwt = "") {
35
92
  const headers = {
36
93
  Accept: "application/json",
@@ -167,12 +224,37 @@ function validateConfig(raw) {
167
224
  npmCdn
168
225
  };
169
226
  }
227
+ function validateLocale(locale) {
228
+ if (locale && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(locale)) {
229
+ return locale;
230
+ }
231
+ }
170
232
  function validateWidgetConfig(raw) {
171
233
  if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
172
234
  if (!assertProp(raw, "user")) ; // TODO: This should be better type checked
173
235
 
174
236
  return raw;
175
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
+ `;
176
258
 
177
259
  /**
178
260
  *
@@ -261,8 +343,10 @@ class WidgetApi {
261
343
 
262
344
 
263
345
  render(params) {
346
+ var _clean$locale;
347
+
264
348
  const raw = params;
265
- const clean = validateWidgetConfig(raw);
349
+ const clean = validatePasswordlessConfig(raw);
266
350
  const {
267
351
  widgetType,
268
352
  engagementMedium = "POPUP",
@@ -270,17 +354,29 @@ class WidgetApi {
270
354
  user
271
355
  } = clean;
272
356
  const tenantAlias = encodeURIComponent(this.tenantAlias);
273
- const accountId = encodeURIComponent(user.accountId);
274
- const userId = encodeURIComponent(user.id);
275
-
276
- const optionalParams = _buildParams({
277
- widgetType,
278
- engagementMedium
279
- });
280
-
281
- 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`;
282
361
  const url = this.domain + path;
283
- 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
+ });
284
380
  }
285
381
  /**
286
382
  * An API call to send out referral invites to contacts
@@ -314,18 +410,21 @@ class WidgetApi {
314
410
  /**
315
411
  * Looks up the referral code of the current user, if there is any.
316
412
  *
317
- * @return {Promise<Object>} code referral code if true.
413
+ * @return {Promise<ReferralCookie>} code referral code if true.
318
414
  */
319
415
 
320
416
 
321
- squatchReferralCookie() {
417
+ async squatchReferralCookie() {
322
418
  const tenantAlias = encodeURIComponent(this.tenantAlias);
323
419
 
324
- const _saasquatch = Cookies__default['default'].get("_saasquatch");
420
+ const _saasquatch = Cookies__default['default'].get("_saasquatch") || "";
325
421
 
326
422
  const cookie = _saasquatch ? `?cookies=${encodeURIComponent(_saasquatch)}` : ``;
327
423
  const url = `${this.domain}/a/${tenantAlias}/widgets/squatchcookiejson${cookie}`;
328
- return doGet(url);
424
+ const response = await doGet(url);
425
+ return Promise.resolve(_extends({}, response, {
426
+ encodedCookie: _saasquatch
427
+ }));
329
428
  }
330
429
 
331
430
  } // builds a param string for widgets
@@ -368,6 +467,7 @@ class AnalyticsApi {
368
467
  }
369
468
 
370
469
  pushAnalyticsLoadEvent(params) {
470
+ if (!params.externalUserId || !params.externalAccountId) return;
371
471
  const tenantAlias = encodeURIComponent(params.tenantAlias);
372
472
  const accountId = encodeURIComponent(params.externalAccountId);
373
473
  const userId = encodeURIComponent(params.externalUserId);
@@ -394,7 +494,7 @@ class AnalyticsApi {
394
494
  // @ts-check
395
495
  /** @hidden */
396
496
 
397
- const _log$6 = debug__default['default']("squatch-js:widget");
497
+ const _log$7 = debug__default['default']("squatch-js:widget");
398
498
  /*
399
499
  * The Widget class is the base class for the different widget types available
400
500
  *
@@ -407,7 +507,7 @@ const _log$6 = debug__default['default']("squatch-js:widget");
407
507
 
408
508
  class Widget {
409
509
  constructor(params) {
410
- _log$6("widget initializing ...");
510
+ _log$7("widget initializing ...");
411
511
 
412
512
  this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
413
513
  this.type = params.type;
@@ -425,6 +525,8 @@ class Widget {
425
525
  }
426
526
 
427
527
  _loadEvent(sqh) {
528
+ var _this$analyticsApi$pu;
529
+
428
530
  if (!sqh) return; // No non-truthy value
429
531
 
430
532
  if (!isObject$1(sqh)) {
@@ -458,10 +560,10 @@ class Widget {
458
560
  };
459
561
  }
460
562
 
461
- this.analyticsApi.pushAnalyticsLoadEvent(params).then(response => {
462
- _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.`);
463
565
  }).catch(ex => {
464
- _log$6(new Error(`pushAnalyticsLoadEvent() ${ex}`));
566
+ _log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
465
567
  });
466
568
  }
467
569
 
@@ -474,9 +576,9 @@ class Widget {
474
576
  engagementMedium: sqh.mode.widgetMode,
475
577
  shareMedium: medium
476
578
  }).then(response => {
477
- _log$6(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
579
+ _log$7(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
478
580
  }).catch(ex => {
479
- _log$6(new Error(`pushAnalyticsLoadEvent() ${ex}`));
581
+ _log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
480
582
  });
481
583
  }
482
584
  }
@@ -489,9 +591,9 @@ class Widget {
489
591
  userId: sqh.analytics.attributes.userId,
490
592
  emailList
491
593
  }).then(response => {
492
- _log$6(`Sent email invites to share ${emailList}. ${response}`);
594
+ _log$7(`Sent email invites to share ${emailList}. ${response}`);
493
595
  }).catch(ex => {
494
- _log$6(new Error(`invite() ${ex}`));
596
+ _log$7(new Error(`invite() ${ex}`));
495
597
  });
496
598
  }
497
599
  }
@@ -580,6 +682,7 @@ class Widget {
580
682
  email: email || null,
581
683
  firstName: firstName || null,
582
684
  lastName: lastName || null,
685
+ // FIXME: Double check this
583
686
  id: this.context.user.id,
584
687
  accountId: this.context.user.accountId
585
688
  };
@@ -589,6 +692,13 @@ class Widget {
589
692
  widgetType: this.type,
590
693
  jwt
591
694
  });
695
+ } else if (this.context.type === "passwordless") {
696
+ response = this.widgetApi.render({
697
+ user: undefined,
698
+ engagementMedium,
699
+ widgetType: this.type,
700
+ jwt: undefined
701
+ });
592
702
  } else {
593
703
  throw new Error("can't reload an error widget");
594
704
  }
@@ -623,7 +733,7 @@ class Widget {
623
733
  }).catch(({
624
734
  message
625
735
  }) => {
626
- _log$6(`${message}`);
736
+ _log$7(`${message}`);
627
737
  });
628
738
  }
629
739
 
@@ -660,7 +770,7 @@ function domready(targetDoc, fn) {
660
770
 
661
771
  // @ts-check
662
772
 
663
- const _log$5 = debug__default['default']("squatch-js:EMBEDwidget");
773
+ const _log$6 = debug__default['default']("squatch-js:EMBEDwidget");
664
774
  /**
665
775
  * An EmbedWidget is displayed inline in part of your page.
666
776
  *
@@ -678,22 +788,22 @@ class EmbedWidget extends Widget {
678
788
  // selector is a string
679
789
  element = document.querySelector(container);
680
790
 
681
- _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
682
792
 
683
793
  } else if (container instanceof HTMLElement) {
684
794
  element = container;
685
795
 
686
- _log$5("loading widget with container", element); // garbage container found
796
+ _log$6("loading widget with container", element); // garbage container found
687
797
 
688
798
  } else if (container) {
689
799
  element = null;
690
800
 
691
- _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
692
802
 
693
803
  } else {
694
804
  element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed");
695
805
 
696
- _log$5("loading widget with default selector", element);
806
+ _log$6("loading widget with default selector", element);
697
807
  }
698
808
 
699
809
  if (!(element instanceof HTMLElement)) throw new Error(`element with selector '${container}' not found.'`);
@@ -759,7 +869,7 @@ class EmbedWidget extends Widget {
759
869
  if (!this.context.container) {
760
870
  this._loadEvent(_sqh);
761
871
 
762
- _log$5("loaded");
872
+ _log$6("loaded");
763
873
  }
764
874
  });
765
875
  } // Un-hide if element is available and refresh data
@@ -768,7 +878,7 @@ class EmbedWidget extends Widget {
768
878
  open() {
769
879
  var _this$frame, _this$frame$contentDo, _this$frame2, _this$frame2$contentW, _this$frame3, _this$frame3$contentW;
770
880
 
771
- if (!this.frame) return _log$5("no target element to open");
881
+ if (!this.frame) return _log$6("no target element to open");
772
882
  this.element.style.visibility = "unset";
773
883
  this.element.style.height = "auto";
774
884
  this.element.style["overflow-y"] = "auto";
@@ -778,16 +888,16 @@ class EmbedWidget extends Widget {
778
888
 
779
889
  this._loadEvent(_sqh);
780
890
 
781
- _log$5("loaded");
891
+ _log$6("loaded");
782
892
  }
783
893
 
784
894
  close() {
785
- if (!this.frame) return _log$5("no target element to close");
895
+ if (!this.frame) return _log$6("no target element to close");
786
896
  this.element.style.visibility = "hidden";
787
897
  this.element.style.height = "0";
788
898
  this.element.style["overflow-y"] = "hidden";
789
899
 
790
- _log$5("Embed widget closed");
900
+ _log$6("Embed widget closed");
791
901
  }
792
902
 
793
903
  _error(rs, mode = "embed", style = "") {
@@ -798,7 +908,7 @@ class EmbedWidget extends Widget {
798
908
 
799
909
  // @ts-check
800
910
 
801
- const _log$4 = debug__default['default']("squatch-js:POPUPwidget");
911
+ const _log$5 = debug__default['default']("squatch-js:POPUPwidget");
802
912
  /**
803
913
  * The PopupWidget is used to display popups (also known as "Modals").
804
914
  * Popups widgets are rendered on top of other elements in a page.
@@ -816,9 +926,9 @@ class PopupWidget extends Widget {
816
926
  this.triggerElement
817
927
  /* HTMLButton */
818
928
  = document.querySelector(trigger);
819
- 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);
820
930
  } catch (_unused) {
821
- _log$4("Not a valid selector", trigger);
931
+ _log$5("Not a valid selector", trigger);
822
932
  } // Trigger is optional
823
933
 
824
934
 
@@ -841,6 +951,7 @@ class PopupWidget extends Widget {
841
951
  this.popupdiv = document.createElement("div");
842
952
  this.popupdiv.id = "squatchModal";
843
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>`);
844
955
  this.popupcontent = document.createElement("div");
845
956
  this.popupcontent.setAttribute("style", "margin: auto; width: 80%; max-width: 500px; position: relative;");
846
957
 
@@ -860,7 +971,7 @@ class PopupWidget extends Widget {
860
971
  frameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
861
972
  frameDoc.close();
862
973
 
863
- _log$4("Popup template loaded into iframe");
974
+ _log$5("Popup template loaded into iframe");
864
975
 
865
976
  this._setupResizeHandler();
866
977
  }
@@ -933,7 +1044,7 @@ class PopupWidget extends Widget {
933
1044
 
934
1045
  this._loadEvent(_sqh);
935
1046
 
936
- _log$4("Popup opened");
1047
+ _log$5("Popup opened");
937
1048
  });
938
1049
  }
939
1050
 
@@ -941,7 +1052,7 @@ class PopupWidget extends Widget {
941
1052
  this.popupdiv.style.visibility = "hidden";
942
1053
  this.popupdiv.style.top = "-2000px";
943
1054
 
944
- _log$4("Popup closed");
1055
+ _log$5("Popup closed");
945
1056
  }
946
1057
 
947
1058
  _clickedOutside({
@@ -959,7 +1070,7 @@ class PopupWidget extends Widget {
959
1070
 
960
1071
  }
961
1072
 
962
- const _log$3 = debug__namespace("squatch-js:CTAwidget");
1073
+ const _log$4 = debug__namespace("squatch-js:CTAwidget");
963
1074
  /**
964
1075
  * A CtaWidget is displayed on top of your page
965
1076
  *
@@ -970,7 +1081,7 @@ const _log$3 = debug__namespace("squatch-js:CTAwidget");
970
1081
 
971
1082
  class CtaWidget extends PopupWidget {
972
1083
  constructor(params, opts) {
973
- _log$3("CTA constructor");
1084
+ _log$4("CTA constructor");
974
1085
 
975
1086
  const ctaElement = document.createElement("div");
976
1087
  ctaElement.id = "cta";
@@ -998,7 +1109,7 @@ class CtaWidget extends PopupWidget {
998
1109
  this.ctaFrame.setAttribute("style", `border:0; background-color:transparent; position:fixed; display:none;${this.side}${this.position}`);
999
1110
  document.body.appendChild(this.ctaFrame);
1000
1111
 
1001
- _log$3("ctaframe appended to body");
1112
+ _log$4("ctaframe appended to body");
1002
1113
  }
1003
1114
 
1004
1115
  load() {
@@ -1062,10 +1173,10 @@ class CtaWidget extends PopupWidget {
1062
1173
  });
1063
1174
  ro.observe(ctaContainer);
1064
1175
 
1065
- _log$3("CTA template loaded into iframe");
1176
+ _log$4("CTA template loaded into iframe");
1066
1177
  });
1067
1178
  } else {
1068
- _log$3(new Error("CTA element not found in theme"));
1179
+ _log$4(new Error("CTA element not found in theme"));
1069
1180
  }
1070
1181
  });
1071
1182
  }
@@ -1088,7 +1199,7 @@ class CtaWidget extends PopupWidget {
1088
1199
 
1089
1200
  }
1090
1201
 
1091
- const _log$2 = debug__default['default']("squatch-js:widgets");
1202
+ const _log$3 = debug__default['default']("squatch-js:widgets");
1092
1203
  /**
1093
1204
  *
1094
1205
  * `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
@@ -1153,7 +1264,7 @@ class Widgets {
1153
1264
  return {
1154
1265
  widget: this._renderWidget(response, clean, {
1155
1266
  type: "upsert",
1156
- user: clean.user,
1267
+ user: clean.user || null,
1157
1268
  engagementMedium: config.engagementMedium,
1158
1269
  container: config.container,
1159
1270
  trigger: config.trigger
@@ -1161,7 +1272,7 @@ class Widgets {
1161
1272
  user: response.user
1162
1273
  };
1163
1274
  } catch (err) {
1164
- _log$2(err);
1275
+ _log$3(err);
1165
1276
 
1166
1277
  if (err.apiErrorCode) {
1167
1278
  this._renderErrorWidget(err, config.engagementMedium);
@@ -1189,15 +1300,13 @@ class Widgets {
1189
1300
 
1190
1301
  async render(config) {
1191
1302
  const raw = config;
1192
- const clean = validateWidgetConfig(raw);
1303
+ const clean = validatePasswordlessConfig(raw);
1193
1304
 
1194
1305
  try {
1195
- const response = await this.api.upsertUser(clean);
1306
+ const response = await this.api.render(clean);
1196
1307
  return {
1197
- widget: this._renderWidget({
1198
- template: response
1199
- }, clean, {
1200
- type: "cookie",
1308
+ widget: this._renderWidget(response, clean, {
1309
+ type: "passwordless",
1201
1310
  engagementMedium: clean.engagementMedium
1202
1311
  }),
1203
1312
  user: response.user
@@ -1224,7 +1333,7 @@ class Widgets {
1224
1333
 
1225
1334
  if (typeof input === "function") {
1226
1335
  this.api.squatchReferralCookie().then((...args) => input(...args)).catch(ex => {
1227
- _log$2("Autofill error", ex);
1336
+ _log$3("Autofill error", ex);
1228
1337
 
1229
1338
  throw ex;
1230
1339
  });
@@ -1239,7 +1348,7 @@ class Widgets {
1239
1348
  // Only use the first element found
1240
1349
  elem = elems[0];
1241
1350
  } else {
1242
- _log$2("Element id/class or function missing");
1351
+ _log$3("Element id/class or function missing");
1243
1352
 
1244
1353
  throw new Error("Element id/class or function missing");
1245
1354
  }
@@ -1277,11 +1386,11 @@ class Widgets {
1277
1386
 
1278
1387
 
1279
1388
  _renderWidget(response, config, context) {
1280
- _log$2("Rendering Widget...");
1389
+ _log$3("Rendering Widget...");
1281
1390
 
1282
1391
  if (!response) throw new Error("Unable to get a response");
1283
1392
  let widget;
1284
- let displayOnLoad = false;
1393
+ let displayOnLoad = !!config.displayOnLoad;
1285
1394
  let displayCTA = false;
1286
1395
  const opts = response.jsOptions || "";
1287
1396
  const params = {
@@ -1300,9 +1409,9 @@ class Widgets {
1300
1409
  displayOnLoad = rule.displayOnLoad;
1301
1410
  displayCTA = rule.showAsCTA;
1302
1411
 
1303
- _log$2(`Display ${rule.widgetType} on ${rule.url}`);
1412
+ _log$3(`Display ${rule.widgetType} on ${rule.url}`);
1304
1413
  } else {
1305
- _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}`);
1306
1415
  }
1307
1416
  }
1308
1417
  });
@@ -1311,20 +1420,20 @@ class Widgets {
1311
1420
  if (opts.conversionUrls) {
1312
1421
  opts.conversionUrls.forEach(rule => {
1313
1422
  if (response.user.referredBy && Widgets._matchesUrl(rule)) {
1314
- _log$2("This is a conversion URL", rule);
1423
+ _log$3("This is a conversion URL", rule);
1315
1424
  }
1316
1425
  });
1317
1426
  }
1318
1427
 
1319
1428
  if (opts.fuelTankAutofillUrls) {
1320
- _log$2("We found a fuel tank autofill!");
1429
+ _log$3("We found a fuel tank autofill!");
1321
1430
 
1322
1431
  opts.fuelTankAutofillUrls.forEach(({
1323
1432
  url,
1324
1433
  formSelector
1325
1434
  }) => {
1326
1435
  if (Widgets._matchesUrl(url)) {
1327
- _log$2("Fuel Tank URL matches");
1436
+ _log$3("Fuel Tank URL matches");
1328
1437
 
1329
1438
  if (response.user.referredBy && response.user.referredBy.code) {
1330
1439
  const formAutofill = document.querySelector(formSelector);
@@ -1332,7 +1441,7 @@ class Widgets {
1332
1441
  if (formAutofill) {
1333
1442
  formAutofill.value = response.user.referredBy.referredReward.fuelTankCode || "";
1334
1443
  } else {
1335
- _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.`));
1336
1445
  }
1337
1446
  }
1338
1447
  }
@@ -1347,7 +1456,7 @@ class Widgets {
1347
1456
  widget.load();
1348
1457
  if (displayOnLoad) widget.open();
1349
1458
  } else if (displayCTA) {
1350
- _log$2("display CTA");
1459
+ _log$3("display CTA");
1351
1460
 
1352
1461
  const side = opts.cta.content.buttonSide;
1353
1462
  const position = opts.cta.content.buttonPosition;
@@ -1358,7 +1467,7 @@ class Widgets {
1358
1467
  widget.load();
1359
1468
  if (displayOnLoad) widget.open();
1360
1469
  } else {
1361
- _log$2("display popup on load");
1470
+ _log$3("display popup on load");
1362
1471
 
1363
1472
  widget = new PopupWidget(params);
1364
1473
  widget.load();
@@ -1382,7 +1491,7 @@ class Widgets {
1382
1491
  message
1383
1492
  } = props;
1384
1493
 
1385
- _log$2(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
1494
+ _log$3(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
1386
1495
 
1387
1496
  const params = {
1388
1497
  content: "error",
@@ -1522,7 +1631,8 @@ function asyncLoad() {
1522
1631
 
1523
1632
  if (loaded && cached) {
1524
1633
  const ready = cached.ready || [];
1525
- 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
1526
1636
 
1527
1637
  window._squatch = undefined;
1528
1638
 
@@ -1534,24 +1644,6 @@ function asyncLoad() {
1534
1644
  }
1535
1645
  }
1536
1646
 
1537
- function _extends() {
1538
- _extends = Object.assign || function (target) {
1539
- for (var i = 1; i < arguments.length; i++) {
1540
- var source = arguments[i];
1541
-
1542
- for (var key in source) {
1543
- if (Object.prototype.hasOwnProperty.call(source, key)) {
1544
- target[key] = source[key];
1545
- }
1546
- }
1547
- }
1548
-
1549
- return target;
1550
- };
1551
-
1552
- return _extends.apply(this, arguments);
1553
- }
1554
-
1555
1647
  /*! (c) Andrea Giammarchi - ISC */
1556
1648
  var self = undefined || /* istanbul ignore next */ {};
1557
1649
  try {
@@ -1930,7 +2022,7 @@ var URLSearchParams$1 = self.URLSearchParams;
1930
2022
 
1931
2023
  /** @hidden */
1932
2024
 
1933
- const _log$1 = debug__default['default']("squatch-js");
2025
+ const _log$2 = debug__default['default']("squatch-js");
1934
2026
 
1935
2027
  const isObject = item => typeof item === "object" && !Array.isArray(item);
1936
2028
 
@@ -1983,7 +2075,7 @@ function _pushCookie() {
1983
2075
  try {
1984
2076
  paramsJSON = JSON.parse(b64decode(refParam));
1985
2077
  } catch (error) {
1986
- _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
1987
2079
 
1988
2080
 
1989
2081
  return;
@@ -1992,26 +2084,26 @@ function _pushCookie() {
1992
2084
  try {
1993
2085
  existingCookie = JSON.parse(b64decode(Cookies__default['default'].get("_saasquatch")));
1994
2086
 
1995
- _log$1("existing cookie", existingCookie);
2087
+ _log$2("existing cookie", existingCookie);
1996
2088
  } catch (error) {
1997
- _log$1("Unable to retrieve cookie", error);
2089
+ _log$2("Unable to retrieve cookie", error);
1998
2090
  } // don't merge if there's no existing object
1999
2091
 
2000
2092
 
2001
2093
  try {
2002
2094
  const domain = getTopDomain();
2003
2095
 
2004
- _log$1("domain retrieved:", domain);
2096
+ _log$2("domain retrieved:", domain);
2005
2097
 
2006
2098
  if (existingCookie) {
2007
2099
  const newCookie = deepMerge(existingCookie, paramsJSON);
2008
2100
  reEncodedCookie = b64encode(JSON.stringify(newCookie));
2009
2101
 
2010
- _log$1("cookie to store:", newCookie);
2102
+ _log$2("cookie to store:", newCookie);
2011
2103
  } else {
2012
2104
  reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
2013
2105
 
2014
- _log$1("cookie to store:", paramsJSON);
2106
+ _log$2("cookie to store:", paramsJSON);
2015
2107
  }
2016
2108
 
2017
2109
  Cookies__default['default'].set("_saasquatch", reEncodedCookie, {
@@ -2022,11 +2114,86 @@ function _pushCookie() {
2022
2114
  path: "/"
2023
2115
  });
2024
2116
  } catch (error) {
2025
- _log$1("Unable to set cookie", error);
2117
+ _log$2("Unable to set cookie", error);
2026
2118
  }
2027
2119
  }
2028
2120
  }
2029
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
+
2030
2197
  // @ts-check
2031
2198
  function help() {
2032
2199
  console.log(`Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.`);
@@ -2080,6 +2247,33 @@ function widgets() {
2080
2247
  function events() {
2081
2248
  return _events;
2082
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
+ }
2083
2277
  /**
2084
2278
  * Initializes the static `squatch` global. This sets up:
2085
2279
  *
@@ -2122,7 +2316,7 @@ function init(configIn) {
2122
2316
  * @example
2123
2317
  * squatch.ready(function() {
2124
2318
  * console.log("ready!");
2125
- * squatch.api().cookieUser();
2319
+ * squatch.api().upsertUser();
2126
2320
  * });
2127
2321
  */
2128
2322
 
@@ -2189,6 +2383,7 @@ exports.EmbedWidget = EmbedWidget;
2189
2383
  exports.PopupWidget = PopupWidget;
2190
2384
  exports.WidgetApi = WidgetApi;
2191
2385
  exports.Widgets = Widgets;
2386
+ exports._auto = _auto;
2192
2387
  exports.api = api;
2193
2388
  exports.autofill = autofill;
2194
2389
  exports.events = events;
@@ -2197,5 +2392,6 @@ exports.init = init;
2197
2392
  exports.pushCookie = pushCookie;
2198
2393
  exports.ready = ready;
2199
2394
  exports.submitEmail = submitEmail;
2395
+ exports.widget = widget;
2200
2396
  exports.widgets = widgets;
2201
2397
  //# sourceMappingURL=squatch.js.map