@saasquatch/squatch-js 2.4.3-3 → 2.4.3
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 +291 -278
- package/LICENSE +20 -20
- package/README.md +1 -0
- package/demo/sandbox.ts +5 -7
- package/demo/toolbar.tsx +1 -1
- package/dist/api/AnalyticsApi.d.ts +1 -1
- package/dist/api/WidgetApi.d.ts +17 -4
- package/dist/squatch.d.ts +1 -11
- package/dist/squatch.esm.js +158 -258
- package/dist/squatch.esm.js.map +1 -1
- package/dist/squatch.js +157 -259
- 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 +8 -9
- package/dist/utils/cookieUtils.d.ts +0 -1
- package/dist/utils/io.d.ts +1 -2
- package/dist/utils/validate.d.ts +0 -1
- package/dist/widgets/Widgets.d.ts +17 -3
- package/package.json +105 -104
- package/dist/utils/utmUtils.d.ts +0 -14
package/dist/squatch.js
CHANGED
|
@@ -49,45 +49,6 @@ 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
|
-
}
|
|
91
52
|
function doGet(url, jwt = "") {
|
|
92
53
|
const headers = {
|
|
93
54
|
Accept: "application/json",
|
|
@@ -230,10 +191,6 @@ function validateWidgetConfig(raw) {
|
|
|
230
191
|
|
|
231
192
|
return raw;
|
|
232
193
|
}
|
|
233
|
-
function validatePasswordlessConfig(raw) {
|
|
234
|
-
if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
|
|
235
|
-
return raw;
|
|
236
|
-
}
|
|
237
194
|
|
|
238
195
|
/**
|
|
239
196
|
*
|
|
@@ -266,6 +223,39 @@ class WidgetApi {
|
|
|
266
223
|
this.domain = clean.domain;
|
|
267
224
|
this.npmCdn = clean.npmCdn;
|
|
268
225
|
}
|
|
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
|
+
}
|
|
269
259
|
/**
|
|
270
260
|
* Creates/upserts user.
|
|
271
261
|
*
|
|
@@ -323,7 +313,7 @@ class WidgetApi {
|
|
|
323
313
|
|
|
324
314
|
render(params) {
|
|
325
315
|
const raw = params;
|
|
326
|
-
const clean =
|
|
316
|
+
const clean = validateWidgetConfig(raw);
|
|
327
317
|
const {
|
|
328
318
|
widgetType,
|
|
329
319
|
engagementMedium = "POPUP",
|
|
@@ -331,43 +321,17 @@ class WidgetApi {
|
|
|
331
321
|
user
|
|
332
322
|
} = clean;
|
|
333
323
|
const tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
334
|
-
const accountId =
|
|
335
|
-
const userId =
|
|
336
|
-
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
template
|
|
341
|
-
user {
|
|
342
|
-
id
|
|
343
|
-
accountId
|
|
344
|
-
}
|
|
345
|
-
jsOptions
|
|
346
|
-
widgetConfig {
|
|
347
|
-
values
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
`;
|
|
352
|
-
const path = `/api/v1/${tenantAlias}/graphql`;
|
|
353
|
-
const url = this.domain + path;
|
|
354
|
-
return new Promise(async (resolve, reject) => {
|
|
355
|
-
try {
|
|
356
|
-
var _res$body, _res$body$data;
|
|
357
|
-
|
|
358
|
-
const res = await doQuery(url, query, {
|
|
359
|
-
user: userId && accountId ? {
|
|
360
|
-
id: userId,
|
|
361
|
-
accountId
|
|
362
|
-
} : null,
|
|
363
|
-
engagementMedium,
|
|
364
|
-
widgetType
|
|
365
|
-
}, jwt);
|
|
366
|
-
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);
|
|
367
|
-
} catch (e) {
|
|
368
|
-
reject(e);
|
|
369
|
-
}
|
|
324
|
+
const accountId = encodeURIComponent(user.accountId);
|
|
325
|
+
const userId = encodeURIComponent(user.id);
|
|
326
|
+
|
|
327
|
+
const optionalParams = _buildParams({
|
|
328
|
+
widgetType,
|
|
329
|
+
engagementMedium
|
|
370
330
|
});
|
|
331
|
+
|
|
332
|
+
const path = `/api/v1/${tenantAlias}/widget/account/${accountId}/user/${userId}/render${optionalParams}`;
|
|
333
|
+
const url = this.domain + path;
|
|
334
|
+
return doGet(url, jwt);
|
|
371
335
|
}
|
|
372
336
|
/**
|
|
373
337
|
* An API call to send out referral invites to contacts
|
|
@@ -401,18 +365,21 @@ class WidgetApi {
|
|
|
401
365
|
/**
|
|
402
366
|
* Looks up the referral code of the current user, if there is any.
|
|
403
367
|
*
|
|
404
|
-
* @return {Promise<
|
|
368
|
+
* @return {Promise<ReferralCookie>} code referral code if true.
|
|
405
369
|
*/
|
|
406
370
|
|
|
407
371
|
|
|
408
|
-
squatchReferralCookie() {
|
|
372
|
+
async squatchReferralCookie() {
|
|
409
373
|
const tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
410
374
|
|
|
411
|
-
const _saasquatch = Cookies__default['default'].get("_saasquatch");
|
|
375
|
+
const _saasquatch = Cookies__default['default'].get("_saasquatch") || "";
|
|
412
376
|
|
|
413
377
|
const cookie = _saasquatch ? `?cookies=${encodeURIComponent(_saasquatch)}` : ``;
|
|
414
378
|
const url = `${this.domain}/a/${tenantAlias}/widgets/squatchcookiejson${cookie}`;
|
|
415
|
-
|
|
379
|
+
const response = await doGet(url);
|
|
380
|
+
return Promise.resolve(_extends({}, response, {
|
|
381
|
+
encodedCookie: _saasquatch
|
|
382
|
+
}));
|
|
416
383
|
}
|
|
417
384
|
|
|
418
385
|
} // builds a param string for widgets
|
|
@@ -455,7 +422,6 @@ class AnalyticsApi {
|
|
|
455
422
|
}
|
|
456
423
|
|
|
457
424
|
pushAnalyticsLoadEvent(params) {
|
|
458
|
-
if (!params.externalUserId || !params.externalAccountId) return;
|
|
459
425
|
const tenantAlias = encodeURIComponent(params.tenantAlias);
|
|
460
426
|
const accountId = encodeURIComponent(params.externalAccountId);
|
|
461
427
|
const userId = encodeURIComponent(params.externalUserId);
|
|
@@ -482,7 +448,7 @@ class AnalyticsApi {
|
|
|
482
448
|
// @ts-check
|
|
483
449
|
/** @hidden */
|
|
484
450
|
|
|
485
|
-
const _log$
|
|
451
|
+
const _log$6 = debug__default['default']("squatch-js:widget");
|
|
486
452
|
/*
|
|
487
453
|
* The Widget class is the base class for the different widget types available
|
|
488
454
|
*
|
|
@@ -495,7 +461,7 @@ const _log$7 = debug__default['default']("squatch-js:widget");
|
|
|
495
461
|
|
|
496
462
|
class Widget {
|
|
497
463
|
constructor(params) {
|
|
498
|
-
_log$
|
|
464
|
+
_log$6("widget initializing ...");
|
|
499
465
|
|
|
500
466
|
this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
|
|
501
467
|
this.type = params.type;
|
|
@@ -513,8 +479,6 @@ class Widget {
|
|
|
513
479
|
}
|
|
514
480
|
|
|
515
481
|
_loadEvent(sqh) {
|
|
516
|
-
var _this$analyticsApi$pu;
|
|
517
|
-
|
|
518
482
|
if (!sqh) return; // No non-truthy value
|
|
519
483
|
|
|
520
484
|
if (!isObject$1(sqh)) {
|
|
@@ -548,10 +512,10 @@ class Widget {
|
|
|
548
512
|
};
|
|
549
513
|
}
|
|
550
514
|
|
|
551
|
-
|
|
552
|
-
_log$
|
|
515
|
+
this.analyticsApi.pushAnalyticsLoadEvent(params).then(response => {
|
|
516
|
+
_log$6(`${params.engagementMedium} loaded event recorded.`);
|
|
553
517
|
}).catch(ex => {
|
|
554
|
-
_log$
|
|
518
|
+
_log$6(new Error(`pushAnalyticsLoadEvent() ${ex}`));
|
|
555
519
|
});
|
|
556
520
|
}
|
|
557
521
|
|
|
@@ -564,9 +528,9 @@ class Widget {
|
|
|
564
528
|
engagementMedium: sqh.mode.widgetMode,
|
|
565
529
|
shareMedium: medium
|
|
566
530
|
}).then(response => {
|
|
567
|
-
_log$
|
|
531
|
+
_log$6(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
|
|
568
532
|
}).catch(ex => {
|
|
569
|
-
_log$
|
|
533
|
+
_log$6(new Error(`pushAnalyticsLoadEvent() ${ex}`));
|
|
570
534
|
});
|
|
571
535
|
}
|
|
572
536
|
}
|
|
@@ -579,9 +543,9 @@ class Widget {
|
|
|
579
543
|
userId: sqh.analytics.attributes.userId,
|
|
580
544
|
emailList
|
|
581
545
|
}).then(response => {
|
|
582
|
-
_log$
|
|
546
|
+
_log$6(`Sent email invites to share ${emailList}. ${response}`);
|
|
583
547
|
}).catch(ex => {
|
|
584
|
-
_log$
|
|
548
|
+
_log$6(new Error(`invite() ${ex}`));
|
|
585
549
|
});
|
|
586
550
|
}
|
|
587
551
|
}
|
|
@@ -670,7 +634,6 @@ class Widget {
|
|
|
670
634
|
email: email || null,
|
|
671
635
|
firstName: firstName || null,
|
|
672
636
|
lastName: lastName || null,
|
|
673
|
-
// FIXME: Double check this
|
|
674
637
|
id: this.context.user.id,
|
|
675
638
|
accountId: this.context.user.accountId
|
|
676
639
|
};
|
|
@@ -680,12 +643,17 @@ class Widget {
|
|
|
680
643
|
widgetType: this.type,
|
|
681
644
|
jwt
|
|
682
645
|
});
|
|
683
|
-
} else if (this.context.type === "
|
|
684
|
-
|
|
685
|
-
|
|
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,
|
|
686
654
|
engagementMedium,
|
|
687
655
|
widgetType: this.type,
|
|
688
|
-
jwt
|
|
656
|
+
jwt
|
|
689
657
|
});
|
|
690
658
|
} else {
|
|
691
659
|
throw new Error("can't reload an error widget");
|
|
@@ -721,7 +689,7 @@ class Widget {
|
|
|
721
689
|
}).catch(({
|
|
722
690
|
message
|
|
723
691
|
}) => {
|
|
724
|
-
_log$
|
|
692
|
+
_log$6(`${message}`);
|
|
725
693
|
});
|
|
726
694
|
}
|
|
727
695
|
|
|
@@ -758,7 +726,7 @@ function domready(targetDoc, fn) {
|
|
|
758
726
|
|
|
759
727
|
// @ts-check
|
|
760
728
|
|
|
761
|
-
const _log$
|
|
729
|
+
const _log$5 = debug__default['default']("squatch-js:EMBEDwidget");
|
|
762
730
|
/**
|
|
763
731
|
* An EmbedWidget is displayed inline in part of your page.
|
|
764
732
|
*
|
|
@@ -776,22 +744,22 @@ class EmbedWidget extends Widget {
|
|
|
776
744
|
// selector is a string
|
|
777
745
|
element = document.querySelector(container);
|
|
778
746
|
|
|
779
|
-
_log$
|
|
747
|
+
_log$5("loading widget with selector", element); // selector is an HTML element
|
|
780
748
|
|
|
781
749
|
} else if (container instanceof HTMLElement) {
|
|
782
750
|
element = container;
|
|
783
751
|
|
|
784
|
-
_log$
|
|
752
|
+
_log$5("loading widget with container", element); // garbage container found
|
|
785
753
|
|
|
786
754
|
} else if (container) {
|
|
787
755
|
element = null;
|
|
788
756
|
|
|
789
|
-
_log$
|
|
757
|
+
_log$5("container must be an HTMLElement or string", container); // find element on page
|
|
790
758
|
|
|
791
759
|
} else {
|
|
792
760
|
element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed");
|
|
793
761
|
|
|
794
|
-
_log$
|
|
762
|
+
_log$5("loading widget with default selector", element);
|
|
795
763
|
}
|
|
796
764
|
|
|
797
765
|
if (!(element instanceof HTMLElement)) throw new Error(`element with selector '${container}' not found.'`);
|
|
@@ -857,7 +825,7 @@ class EmbedWidget extends Widget {
|
|
|
857
825
|
if (!this.context.container) {
|
|
858
826
|
this._loadEvent(_sqh);
|
|
859
827
|
|
|
860
|
-
_log$
|
|
828
|
+
_log$5("loaded");
|
|
861
829
|
}
|
|
862
830
|
});
|
|
863
831
|
} // Un-hide if element is available and refresh data
|
|
@@ -866,7 +834,7 @@ class EmbedWidget extends Widget {
|
|
|
866
834
|
open() {
|
|
867
835
|
var _this$frame, _this$frame$contentDo, _this$frame2, _this$frame2$contentW, _this$frame3, _this$frame3$contentW;
|
|
868
836
|
|
|
869
|
-
if (!this.frame) return _log$
|
|
837
|
+
if (!this.frame) return _log$5("no target element to open");
|
|
870
838
|
this.element.style.visibility = "unset";
|
|
871
839
|
this.element.style.height = "auto";
|
|
872
840
|
this.element.style["overflow-y"] = "auto";
|
|
@@ -876,16 +844,16 @@ class EmbedWidget extends Widget {
|
|
|
876
844
|
|
|
877
845
|
this._loadEvent(_sqh);
|
|
878
846
|
|
|
879
|
-
_log$
|
|
847
|
+
_log$5("loaded");
|
|
880
848
|
}
|
|
881
849
|
|
|
882
850
|
close() {
|
|
883
|
-
if (!this.frame) return _log$
|
|
851
|
+
if (!this.frame) return _log$5("no target element to close");
|
|
884
852
|
this.element.style.visibility = "hidden";
|
|
885
853
|
this.element.style.height = "0";
|
|
886
854
|
this.element.style["overflow-y"] = "hidden";
|
|
887
855
|
|
|
888
|
-
_log$
|
|
856
|
+
_log$5("Embed widget closed");
|
|
889
857
|
}
|
|
890
858
|
|
|
891
859
|
_error(rs, mode = "embed", style = "") {
|
|
@@ -896,7 +864,7 @@ class EmbedWidget extends Widget {
|
|
|
896
864
|
|
|
897
865
|
// @ts-check
|
|
898
866
|
|
|
899
|
-
const _log$
|
|
867
|
+
const _log$4 = debug__default['default']("squatch-js:POPUPwidget");
|
|
900
868
|
/**
|
|
901
869
|
* The PopupWidget is used to display popups (also known as "Modals").
|
|
902
870
|
* Popups widgets are rendered on top of other elements in a page.
|
|
@@ -914,9 +882,9 @@ class PopupWidget extends Widget {
|
|
|
914
882
|
this.triggerElement
|
|
915
883
|
/* HTMLButton */
|
|
916
884
|
= document.querySelector(trigger);
|
|
917
|
-
if (trigger && !this.triggerElement) _log$
|
|
885
|
+
if (trigger && !this.triggerElement) _log$4("No element found with trigger selector", trigger);
|
|
918
886
|
} catch (_unused) {
|
|
919
|
-
_log$
|
|
887
|
+
_log$4("Not a valid selector", trigger);
|
|
920
888
|
} // Trigger is optional
|
|
921
889
|
|
|
922
890
|
|
|
@@ -958,7 +926,7 @@ class PopupWidget extends Widget {
|
|
|
958
926
|
frameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
|
|
959
927
|
frameDoc.close();
|
|
960
928
|
|
|
961
|
-
_log$
|
|
929
|
+
_log$4("Popup template loaded into iframe");
|
|
962
930
|
|
|
963
931
|
this._setupResizeHandler();
|
|
964
932
|
}
|
|
@@ -1031,7 +999,7 @@ class PopupWidget extends Widget {
|
|
|
1031
999
|
|
|
1032
1000
|
this._loadEvent(_sqh);
|
|
1033
1001
|
|
|
1034
|
-
_log$
|
|
1002
|
+
_log$4("Popup opened");
|
|
1035
1003
|
});
|
|
1036
1004
|
}
|
|
1037
1005
|
|
|
@@ -1039,7 +1007,7 @@ class PopupWidget extends Widget {
|
|
|
1039
1007
|
this.popupdiv.style.visibility = "hidden";
|
|
1040
1008
|
this.popupdiv.style.top = "-2000px";
|
|
1041
1009
|
|
|
1042
|
-
_log$
|
|
1010
|
+
_log$4("Popup closed");
|
|
1043
1011
|
}
|
|
1044
1012
|
|
|
1045
1013
|
_clickedOutside({
|
|
@@ -1057,7 +1025,7 @@ class PopupWidget extends Widget {
|
|
|
1057
1025
|
|
|
1058
1026
|
}
|
|
1059
1027
|
|
|
1060
|
-
const _log$
|
|
1028
|
+
const _log$3 = debug__namespace("squatch-js:CTAwidget");
|
|
1061
1029
|
/**
|
|
1062
1030
|
* A CtaWidget is displayed on top of your page
|
|
1063
1031
|
*
|
|
@@ -1068,7 +1036,7 @@ const _log$4 = debug__namespace("squatch-js:CTAwidget");
|
|
|
1068
1036
|
|
|
1069
1037
|
class CtaWidget extends PopupWidget {
|
|
1070
1038
|
constructor(params, opts) {
|
|
1071
|
-
_log$
|
|
1039
|
+
_log$3("CTA constructor");
|
|
1072
1040
|
|
|
1073
1041
|
const ctaElement = document.createElement("div");
|
|
1074
1042
|
ctaElement.id = "cta";
|
|
@@ -1096,7 +1064,7 @@ class CtaWidget extends PopupWidget {
|
|
|
1096
1064
|
this.ctaFrame.setAttribute("style", `border:0; background-color:transparent; position:fixed; display:none;${this.side}${this.position}`);
|
|
1097
1065
|
document.body.appendChild(this.ctaFrame);
|
|
1098
1066
|
|
|
1099
|
-
_log$
|
|
1067
|
+
_log$3("ctaframe appended to body");
|
|
1100
1068
|
}
|
|
1101
1069
|
|
|
1102
1070
|
load() {
|
|
@@ -1160,10 +1128,10 @@ class CtaWidget extends PopupWidget {
|
|
|
1160
1128
|
});
|
|
1161
1129
|
ro.observe(ctaContainer);
|
|
1162
1130
|
|
|
1163
|
-
_log$
|
|
1131
|
+
_log$3("CTA template loaded into iframe");
|
|
1164
1132
|
});
|
|
1165
1133
|
} else {
|
|
1166
|
-
_log$
|
|
1134
|
+
_log$3(new Error("CTA element not found in theme"));
|
|
1167
1135
|
}
|
|
1168
1136
|
});
|
|
1169
1137
|
}
|
|
@@ -1186,7 +1154,7 @@ class CtaWidget extends PopupWidget {
|
|
|
1186
1154
|
|
|
1187
1155
|
}
|
|
1188
1156
|
|
|
1189
|
-
const _log$
|
|
1157
|
+
const _log$2 = debug__default['default']("squatch-js:widgets");
|
|
1190
1158
|
/**
|
|
1191
1159
|
*
|
|
1192
1160
|
* `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
|
|
@@ -1224,6 +1192,41 @@ class Widgets {
|
|
|
1224
1192
|
|
|
1225
1193
|
EventBus__namespace.addEventListener("submit_email", Widgets._cb);
|
|
1226
1194
|
}
|
|
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
|
+
}
|
|
1227
1230
|
/**
|
|
1228
1231
|
* This function calls the {@link WidgetApi.upsertUser} method, and it renders
|
|
1229
1232
|
* the widget if it is successful. Otherwise it shows the "error" widget.
|
|
@@ -1251,7 +1254,7 @@ class Widgets {
|
|
|
1251
1254
|
return {
|
|
1252
1255
|
widget: this._renderWidget(response, clean, {
|
|
1253
1256
|
type: "upsert",
|
|
1254
|
-
user: clean.user
|
|
1257
|
+
user: clean.user,
|
|
1255
1258
|
engagementMedium: config.engagementMedium,
|
|
1256
1259
|
container: config.container,
|
|
1257
1260
|
trigger: config.trigger
|
|
@@ -1259,7 +1262,7 @@ class Widgets {
|
|
|
1259
1262
|
user: response.user
|
|
1260
1263
|
};
|
|
1261
1264
|
} catch (err) {
|
|
1262
|
-
_log$
|
|
1265
|
+
_log$2(err);
|
|
1263
1266
|
|
|
1264
1267
|
if (err.apiErrorCode) {
|
|
1265
1268
|
this._renderErrorWidget(err, config.engagementMedium);
|
|
@@ -1287,13 +1290,15 @@ class Widgets {
|
|
|
1287
1290
|
|
|
1288
1291
|
async render(config) {
|
|
1289
1292
|
const raw = config;
|
|
1290
|
-
const clean =
|
|
1293
|
+
const clean = validateWidgetConfig(raw);
|
|
1291
1294
|
|
|
1292
1295
|
try {
|
|
1293
|
-
const response = await this.api.
|
|
1296
|
+
const response = await this.api.cookieUser(clean);
|
|
1294
1297
|
return {
|
|
1295
|
-
widget: this._renderWidget(
|
|
1296
|
-
|
|
1298
|
+
widget: this._renderWidget({
|
|
1299
|
+
template: response
|
|
1300
|
+
}, clean, {
|
|
1301
|
+
type: "cookie",
|
|
1297
1302
|
engagementMedium: clean.engagementMedium
|
|
1298
1303
|
}),
|
|
1299
1304
|
user: response.user
|
|
@@ -1320,7 +1325,7 @@ class Widgets {
|
|
|
1320
1325
|
|
|
1321
1326
|
if (typeof input === "function") {
|
|
1322
1327
|
this.api.squatchReferralCookie().then((...args) => input(...args)).catch(ex => {
|
|
1323
|
-
_log$
|
|
1328
|
+
_log$2("Autofill error", ex);
|
|
1324
1329
|
|
|
1325
1330
|
throw ex;
|
|
1326
1331
|
});
|
|
@@ -1335,7 +1340,7 @@ class Widgets {
|
|
|
1335
1340
|
// Only use the first element found
|
|
1336
1341
|
elem = elems[0];
|
|
1337
1342
|
} else {
|
|
1338
|
-
_log$
|
|
1343
|
+
_log$2("Element id/class or function missing");
|
|
1339
1344
|
|
|
1340
1345
|
throw new Error("Element id/class or function missing");
|
|
1341
1346
|
}
|
|
@@ -1373,11 +1378,11 @@ class Widgets {
|
|
|
1373
1378
|
|
|
1374
1379
|
|
|
1375
1380
|
_renderWidget(response, config, context) {
|
|
1376
|
-
_log$
|
|
1381
|
+
_log$2("Rendering Widget...");
|
|
1377
1382
|
|
|
1378
1383
|
if (!response) throw new Error("Unable to get a response");
|
|
1379
1384
|
let widget;
|
|
1380
|
-
let displayOnLoad =
|
|
1385
|
+
let displayOnLoad = false;
|
|
1381
1386
|
let displayCTA = false;
|
|
1382
1387
|
const opts = response.jsOptions || "";
|
|
1383
1388
|
const params = {
|
|
@@ -1396,9 +1401,9 @@ class Widgets {
|
|
|
1396
1401
|
displayOnLoad = rule.displayOnLoad;
|
|
1397
1402
|
displayCTA = rule.showAsCTA;
|
|
1398
1403
|
|
|
1399
|
-
_log$
|
|
1404
|
+
_log$2(`Display ${rule.widgetType} on ${rule.url}`);
|
|
1400
1405
|
} else {
|
|
1401
|
-
_log$
|
|
1406
|
+
_log$2(`Don't display ${rule.widgetType} when no referral on widget rule match ${rule.url}`);
|
|
1402
1407
|
}
|
|
1403
1408
|
}
|
|
1404
1409
|
});
|
|
@@ -1407,20 +1412,20 @@ class Widgets {
|
|
|
1407
1412
|
if (opts.conversionUrls) {
|
|
1408
1413
|
opts.conversionUrls.forEach(rule => {
|
|
1409
1414
|
if (response.user.referredBy && Widgets._matchesUrl(rule)) {
|
|
1410
|
-
_log$
|
|
1415
|
+
_log$2("This is a conversion URL", rule);
|
|
1411
1416
|
}
|
|
1412
1417
|
});
|
|
1413
1418
|
}
|
|
1414
1419
|
|
|
1415
1420
|
if (opts.fuelTankAutofillUrls) {
|
|
1416
|
-
_log$
|
|
1421
|
+
_log$2("We found a fuel tank autofill!");
|
|
1417
1422
|
|
|
1418
1423
|
opts.fuelTankAutofillUrls.forEach(({
|
|
1419
1424
|
url,
|
|
1420
1425
|
formSelector
|
|
1421
1426
|
}) => {
|
|
1422
1427
|
if (Widgets._matchesUrl(url)) {
|
|
1423
|
-
_log$
|
|
1428
|
+
_log$2("Fuel Tank URL matches");
|
|
1424
1429
|
|
|
1425
1430
|
if (response.user.referredBy && response.user.referredBy.code) {
|
|
1426
1431
|
const formAutofill = document.querySelector(formSelector);
|
|
@@ -1428,7 +1433,7 @@ class Widgets {
|
|
|
1428
1433
|
if (formAutofill) {
|
|
1429
1434
|
formAutofill.value = response.user.referredBy.referredReward.fuelTankCode || "";
|
|
1430
1435
|
} else {
|
|
1431
|
-
_log$
|
|
1436
|
+
_log$2(new Error(`Element with id/class ${formSelector} was not found.`));
|
|
1432
1437
|
}
|
|
1433
1438
|
}
|
|
1434
1439
|
}
|
|
@@ -1443,7 +1448,7 @@ class Widgets {
|
|
|
1443
1448
|
widget.load();
|
|
1444
1449
|
if (displayOnLoad) widget.open();
|
|
1445
1450
|
} else if (displayCTA) {
|
|
1446
|
-
_log$
|
|
1451
|
+
_log$2("display CTA");
|
|
1447
1452
|
|
|
1448
1453
|
const side = opts.cta.content.buttonSide;
|
|
1449
1454
|
const position = opts.cta.content.buttonPosition;
|
|
@@ -1454,7 +1459,7 @@ class Widgets {
|
|
|
1454
1459
|
widget.load();
|
|
1455
1460
|
if (displayOnLoad) widget.open();
|
|
1456
1461
|
} else {
|
|
1457
|
-
_log$
|
|
1462
|
+
_log$2("display popup on load");
|
|
1458
1463
|
|
|
1459
1464
|
widget = new PopupWidget(params);
|
|
1460
1465
|
widget.load();
|
|
@@ -1478,7 +1483,7 @@ class Widgets {
|
|
|
1478
1483
|
message
|
|
1479
1484
|
} = props;
|
|
1480
1485
|
|
|
1481
|
-
_log$
|
|
1486
|
+
_log$2(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
|
|
1482
1487
|
|
|
1483
1488
|
const params = {
|
|
1484
1489
|
content: "error",
|
|
@@ -1618,8 +1623,7 @@ function asyncLoad() {
|
|
|
1618
1623
|
|
|
1619
1624
|
if (loaded && cached) {
|
|
1620
1625
|
const ready = cached.ready || [];
|
|
1621
|
-
ready.forEach(cb => setTimeout(() => cb(), 0));
|
|
1622
|
-
setTimeout(() => window.squatch.auto(), 0); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
|
|
1626
|
+
ready.forEach(cb => setTimeout(() => cb(), 0)); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
|
|
1623
1627
|
|
|
1624
1628
|
window._squatch = undefined;
|
|
1625
1629
|
|
|
@@ -2009,7 +2013,7 @@ var URLSearchParams$1 = self.URLSearchParams;
|
|
|
2009
2013
|
|
|
2010
2014
|
/** @hidden */
|
|
2011
2015
|
|
|
2012
|
-
const _log$
|
|
2016
|
+
const _log$1 = debug__default['default']("squatch-js");
|
|
2013
2017
|
|
|
2014
2018
|
const isObject = item => typeof item === "object" && !Array.isArray(item);
|
|
2015
2019
|
|
|
@@ -2062,7 +2066,7 @@ function _pushCookie() {
|
|
|
2062
2066
|
try {
|
|
2063
2067
|
paramsJSON = JSON.parse(b64decode(refParam));
|
|
2064
2068
|
} catch (error) {
|
|
2065
|
-
_log$
|
|
2069
|
+
_log$1("Unable to decode params", error); // don't merge invalid params
|
|
2066
2070
|
|
|
2067
2071
|
|
|
2068
2072
|
return;
|
|
@@ -2071,26 +2075,26 @@ function _pushCookie() {
|
|
|
2071
2075
|
try {
|
|
2072
2076
|
existingCookie = JSON.parse(b64decode(Cookies__default['default'].get("_saasquatch")));
|
|
2073
2077
|
|
|
2074
|
-
_log$
|
|
2078
|
+
_log$1("existing cookie", existingCookie);
|
|
2075
2079
|
} catch (error) {
|
|
2076
|
-
_log$
|
|
2080
|
+
_log$1("Unable to retrieve cookie", error);
|
|
2077
2081
|
} // don't merge if there's no existing object
|
|
2078
2082
|
|
|
2079
2083
|
|
|
2080
2084
|
try {
|
|
2081
2085
|
const domain = getTopDomain();
|
|
2082
2086
|
|
|
2083
|
-
_log$
|
|
2087
|
+
_log$1("domain retrieved:", domain);
|
|
2084
2088
|
|
|
2085
2089
|
if (existingCookie) {
|
|
2086
2090
|
const newCookie = deepMerge(existingCookie, paramsJSON);
|
|
2087
2091
|
reEncodedCookie = b64encode(JSON.stringify(newCookie));
|
|
2088
2092
|
|
|
2089
|
-
_log$
|
|
2093
|
+
_log$1("cookie to store:", newCookie);
|
|
2090
2094
|
} else {
|
|
2091
2095
|
reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
|
|
2092
2096
|
|
|
2093
|
-
_log$
|
|
2097
|
+
_log$1("cookie to store:", paramsJSON);
|
|
2094
2098
|
}
|
|
2095
2099
|
|
|
2096
2100
|
Cookies__default['default'].set("_saasquatch", reEncodedCookie, {
|
|
@@ -2101,86 +2105,11 @@ function _pushCookie() {
|
|
|
2101
2105
|
path: "/"
|
|
2102
2106
|
});
|
|
2103
2107
|
} catch (error) {
|
|
2104
|
-
_log$
|
|
2108
|
+
_log$1("Unable to set cookie", error);
|
|
2105
2109
|
}
|
|
2106
2110
|
}
|
|
2107
2111
|
}
|
|
2108
2112
|
|
|
2109
|
-
/** @hidden */
|
|
2110
|
-
|
|
2111
|
-
const _log$1 = debug__default['default']("squatch-js");
|
|
2112
|
-
|
|
2113
|
-
function _getAutoConfig(configIn) {
|
|
2114
|
-
const queryString = window.location.search;
|
|
2115
|
-
const urlParams = new URLSearchParams(queryString);
|
|
2116
|
-
const refParam = urlParams.get("_saasquatchExtra") || "";
|
|
2117
|
-
|
|
2118
|
-
if (!refParam) {
|
|
2119
|
-
_log$1("No _saasquatchExtra param");
|
|
2120
|
-
|
|
2121
|
-
return;
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
let raw;
|
|
2125
|
-
|
|
2126
|
-
try {
|
|
2127
|
-
raw = JSON.parse(b64decode(refParam));
|
|
2128
|
-
} catch (e) {
|
|
2129
|
-
_log$1("Unable to decode _saasquatchExtra config");
|
|
2130
|
-
|
|
2131
|
-
return;
|
|
2132
|
-
}
|
|
2133
|
-
|
|
2134
|
-
const {
|
|
2135
|
-
domain,
|
|
2136
|
-
tenantAlias,
|
|
2137
|
-
widgetConfig
|
|
2138
|
-
} = convertExtraToConfig(raw);
|
|
2139
|
-
|
|
2140
|
-
if (!domain || !tenantAlias || !widgetConfig) {
|
|
2141
|
-
_log$1("_saasquatchExtra did not have an expected structure");
|
|
2142
|
-
|
|
2143
|
-
return undefined;
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
const {
|
|
2147
|
-
autoPopupWidgetType
|
|
2148
|
-
} = widgetConfig,
|
|
2149
|
-
rest = _objectWithoutPropertiesLoose(widgetConfig, ["autoPopupWidgetType"]);
|
|
2150
|
-
|
|
2151
|
-
return {
|
|
2152
|
-
widgetConfig: _extends({
|
|
2153
|
-
widgetType: autoPopupWidgetType,
|
|
2154
|
-
displayOnLoad: true
|
|
2155
|
-
}, rest),
|
|
2156
|
-
squatchConfig: _extends({}, configIn ? {
|
|
2157
|
-
configIn
|
|
2158
|
-
} : {}, {
|
|
2159
|
-
domain,
|
|
2160
|
-
tenantAlias
|
|
2161
|
-
})
|
|
2162
|
-
};
|
|
2163
|
-
}
|
|
2164
|
-
/**
|
|
2165
|
-
* Converts _saasquatchExtra into
|
|
2166
|
-
* @param obj
|
|
2167
|
-
*/
|
|
2168
|
-
|
|
2169
|
-
function convertExtraToConfig(obj) {
|
|
2170
|
-
var _obj$_domain;
|
|
2171
|
-
|
|
2172
|
-
const _domain = Object.keys(obj || {})[0];
|
|
2173
|
-
const tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
|
|
2174
|
-
const widgetConfig = obj == null ? void 0 : (_obj$_domain = obj[_domain]) == null ? void 0 : _obj$_domain[tenantAlias]; // domain in _saasquatchExtra doesn't contain "https://"
|
|
2175
|
-
|
|
2176
|
-
const domain = _domain ? `https://${_domain}` : undefined;
|
|
2177
|
-
return {
|
|
2178
|
-
domain,
|
|
2179
|
-
tenantAlias,
|
|
2180
|
-
widgetConfig
|
|
2181
|
-
};
|
|
2182
|
-
}
|
|
2183
|
-
|
|
2184
2113
|
// @ts-check
|
|
2185
2114
|
function help() {
|
|
2186
2115
|
console.log(`Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.`);
|
|
@@ -2234,35 +2163,6 @@ function widgets() {
|
|
|
2234
2163
|
function events() {
|
|
2235
2164
|
return _events;
|
|
2236
2165
|
}
|
|
2237
|
-
/**
|
|
2238
|
-
* Entry-point for high level API to render a widget using the instance of {@link Widgets} created when you call {@link #init init}.
|
|
2239
|
-
*/
|
|
2240
|
-
|
|
2241
|
-
function widget(widgetConfig) {
|
|
2242
|
-
var _widgets2;
|
|
2243
|
-
|
|
2244
|
-
return (_widgets2 = widgets()) == null ? void 0 : _widgets2.render(widgetConfig);
|
|
2245
|
-
}
|
|
2246
|
-
/**
|
|
2247
|
-
* Initial concept for automatic widget rendering
|
|
2248
|
-
*
|
|
2249
|
-
* - `saasquatchExtra` utm param carries widgetIdent
|
|
2250
|
-
*/
|
|
2251
|
-
|
|
2252
|
-
function auto(configIn) {
|
|
2253
|
-
const configs = _getAutoConfig(configIn);
|
|
2254
|
-
|
|
2255
|
-
if (configs) {
|
|
2256
|
-
var _widgets3;
|
|
2257
|
-
|
|
2258
|
-
const {
|
|
2259
|
-
squatchConfig,
|
|
2260
|
-
widgetConfig
|
|
2261
|
-
} = configs;
|
|
2262
|
-
init(squatchConfig);
|
|
2263
|
-
return (_widgets3 = widgets()) == null ? void 0 : _widgets3.render(widgetConfig);
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
2166
|
/**
|
|
2267
2167
|
* Initializes the static `squatch` global. This sets up:
|
|
2268
2168
|
*
|
|
@@ -2373,7 +2273,6 @@ exports.PopupWidget = PopupWidget;
|
|
|
2373
2273
|
exports.WidgetApi = WidgetApi;
|
|
2374
2274
|
exports.Widgets = Widgets;
|
|
2375
2275
|
exports.api = api;
|
|
2376
|
-
exports.auto = auto;
|
|
2377
2276
|
exports.autofill = autofill;
|
|
2378
2277
|
exports.events = events;
|
|
2379
2278
|
exports.help = help;
|
|
@@ -2381,6 +2280,5 @@ exports.init = init;
|
|
|
2381
2280
|
exports.pushCookie = pushCookie;
|
|
2382
2281
|
exports.ready = ready;
|
|
2383
2282
|
exports.submitEmail = submitEmail;
|
|
2384
|
-
exports.widget = widget;
|
|
2385
2283
|
exports.widgets = widgets;
|
|
2386
2284
|
//# sourceMappingURL=squatch.js.map
|