@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/CHANGELOG.md +326 -291
- package/LICENSE +20 -20
- package/demo/sandbox.ts +7 -5
- package/demo/toolbar.tsx +1 -1
- package/dist/api/AnalyticsApi.d.ts +1 -1
- package/dist/api/WidgetApi.d.ts +2 -15
- package/dist/api/graphql.d.ts +1 -0
- package/dist/squatch.d.ts +10 -2
- package/dist/squatch.esm.js +264 -153
- package/dist/squatch.esm.js.map +1 -1
- package/dist/squatch.js +266 -153
- package/dist/squatch.js.map +1 -1
- package/dist/squatch.min.js +3 -3
- package/dist/squatch.min.js.map +1 -1
- package/dist/squatch.modern.js +1 -1
- package/dist/squatch.modern.js.map +1 -1
- package/dist/stats.html +1 -1
- package/dist/types.d.ts +10 -4
- package/dist/utils/cookieUtils.d.ts +1 -0
- package/dist/utils/io.d.ts +1 -0
- package/dist/utils/utmUtils.d.ts +14 -0
- package/dist/utils/validate.d.ts +2 -0
- package/dist/widgets/Widgets.d.ts +3 -17
- package/package.json +104 -104
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 =
|
|
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
|
|
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
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
579
|
+
_log$7(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
|
|
532
580
|
}).catch(ex => {
|
|
533
|
-
_log$
|
|
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$
|
|
594
|
+
_log$7(`Sent email invites to share ${emailList}. ${response}`);
|
|
547
595
|
}).catch(ex => {
|
|
548
|
-
_log$
|
|
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 === "
|
|
647
|
-
|
|
648
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
891
|
+
_log$6("loaded");
|
|
848
892
|
}
|
|
849
893
|
|
|
850
894
|
close() {
|
|
851
|
-
if (!this.frame) return _log$
|
|
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$
|
|
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$
|
|
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$
|
|
929
|
+
if (trigger && !this.triggerElement) _log$5("No element found with trigger selector", trigger);
|
|
886
930
|
} catch (_unused) {
|
|
887
|
-
_log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
1176
|
+
_log$4("CTA template loaded into iframe");
|
|
1132
1177
|
});
|
|
1133
1178
|
} else {
|
|
1134
|
-
_log$
|
|
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$
|
|
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$
|
|
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 =
|
|
1303
|
+
const clean = validatePasswordlessConfig(raw);
|
|
1294
1304
|
|
|
1295
1305
|
try {
|
|
1296
|
-
const response = await this.api.
|
|
1306
|
+
const response = await this.api.render(clean);
|
|
1297
1307
|
return {
|
|
1298
|
-
widget: this._renderWidget({
|
|
1299
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
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 =
|
|
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$
|
|
1412
|
+
_log$3(`Display ${rule.widgetType} on ${rule.url}`);
|
|
1405
1413
|
} else {
|
|
1406
|
-
_log$
|
|
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$
|
|
1423
|
+
_log$3("This is a conversion URL", rule);
|
|
1416
1424
|
}
|
|
1417
1425
|
});
|
|
1418
1426
|
}
|
|
1419
1427
|
|
|
1420
1428
|
if (opts.fuelTankAutofillUrls) {
|
|
1421
|
-
_log$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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));
|
|
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$
|
|
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$
|
|
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$
|
|
2087
|
+
_log$2("existing cookie", existingCookie);
|
|
2079
2088
|
} catch (error) {
|
|
2080
|
-
_log$
|
|
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$
|
|
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$
|
|
2102
|
+
_log$2("cookie to store:", newCookie);
|
|
2094
2103
|
} else {
|
|
2095
2104
|
reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
|
|
2096
2105
|
|
|
2097
|
-
_log$
|
|
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$
|
|
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().
|
|
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
|