@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/CHANGELOG.md +50 -2
- package/LICENSE +1 -1
- package/README.md +1 -0
- 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 +4 -4
- package/dist/api/graphql.d.ts +1 -0
- package/dist/squatch.d.ts +10 -2
- package/dist/squatch.esm.js +292 -98
- package/dist/squatch.esm.js.map +1 -1
- package/dist/squatch.js +294 -98
- package/dist/squatch.js.map +1 -1
- package/dist/squatch.min.js +3 -3
- package/dist/squatch.min.js.map +1 -0
- package/dist/squatch.modern.js +2 -0
- package/dist/squatch.modern.js.map +1 -0
- package/dist/stats.html +1 -1
- package/dist/types.d.ts +14 -4
- package/dist/utils/cookieUtils.d.ts +1 -0
- package/dist/utils/io.d.ts +2 -1
- package/dist/utils/utmUtils.d.ts +14 -0
- package/dist/utils/validate.d.ts +2 -0
- package/dist/widgets/Widgets.d.ts +3 -3
- package/package.json +7 -6
package/dist/squatch.esm.js
CHANGED
|
@@ -1,9 +1,66 @@
|
|
|
1
1
|
import * as debug from 'debug';
|
|
2
2
|
import debug__default from 'debug';
|
|
3
3
|
import * as EventBus from 'eventbusjs';
|
|
4
|
-
import * as superagent from 'superagent';
|
|
5
4
|
import Cookies from 'js-cookie';
|
|
5
|
+
import * as superagent from 'superagent';
|
|
6
|
+
|
|
7
|
+
function _extends() {
|
|
8
|
+
_extends = Object.assign || function (target) {
|
|
9
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
10
|
+
var source = arguments[i];
|
|
11
|
+
|
|
12
|
+
for (var key in source) {
|
|
13
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
14
|
+
target[key] = source[key];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
6
21
|
|
|
22
|
+
return _extends.apply(this, arguments);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
26
|
+
if (source == null) return {};
|
|
27
|
+
var target = {};
|
|
28
|
+
var sourceKeys = Object.keys(source);
|
|
29
|
+
var key, i;
|
|
30
|
+
|
|
31
|
+
for (i = 0; i < sourceKeys.length; i++) {
|
|
32
|
+
key = sourceKeys[i];
|
|
33
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
34
|
+
target[key] = source[key];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return target;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function doQuery(url, query, variables, token) {
|
|
41
|
+
const headers = _extends({
|
|
42
|
+
Accept: "application/json"
|
|
43
|
+
}, token ? {
|
|
44
|
+
Authorization: `Bearer ${token}`
|
|
45
|
+
} : {}, {
|
|
46
|
+
"X-SaaSquatch-Referrer": window ? window.location.href : ""
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const request = superagent.post(url).send({
|
|
50
|
+
query,
|
|
51
|
+
variables
|
|
52
|
+
}).set(headers);
|
|
53
|
+
return thenableSuperagent(request).then(response => response, error => {
|
|
54
|
+
let json;
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
json = JSON.parse(error.response.text);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw json;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
7
64
|
function doGet(url, jwt = "") {
|
|
8
65
|
const headers = {
|
|
9
66
|
Accept: "application/json",
|
|
@@ -140,12 +197,37 @@ function validateConfig(raw) {
|
|
|
140
197
|
npmCdn
|
|
141
198
|
};
|
|
142
199
|
}
|
|
200
|
+
function validateLocale(locale) {
|
|
201
|
+
if (locale && /^[a-z]{2}_(?:[A-Z]{2}|[0-9]{3})$/.test(locale)) {
|
|
202
|
+
return locale;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
143
205
|
function validateWidgetConfig(raw) {
|
|
144
206
|
if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
|
|
145
207
|
if (!assertProp(raw, "user")) ; // TODO: This should be better type checked
|
|
146
208
|
|
|
147
209
|
return raw;
|
|
148
210
|
}
|
|
211
|
+
function validatePasswordlessConfig(raw) {
|
|
212
|
+
if (!isObject$1(raw)) throw new Error("Widget properties must be an object");
|
|
213
|
+
return raw;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const RENDER_WIDGET_QUERY = `
|
|
217
|
+
query renderWidget ($user: UserIdInput, $engagementMedium: UserEngagementMedium, $widgetType: WidgetType, $locale: RSLocale) {
|
|
218
|
+
renderWidget(user: $user, engagementMedium: $engagementMedium, widgetType: $widgetType, locale: $locale) {
|
|
219
|
+
template
|
|
220
|
+
user {
|
|
221
|
+
id
|
|
222
|
+
accountId
|
|
223
|
+
}
|
|
224
|
+
jsOptions
|
|
225
|
+
widgetConfig {
|
|
226
|
+
values
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
`;
|
|
149
231
|
|
|
150
232
|
/**
|
|
151
233
|
*
|
|
@@ -234,8 +316,10 @@ class WidgetApi {
|
|
|
234
316
|
|
|
235
317
|
|
|
236
318
|
render(params) {
|
|
319
|
+
var _clean$locale;
|
|
320
|
+
|
|
237
321
|
const raw = params;
|
|
238
|
-
const clean =
|
|
322
|
+
const clean = validatePasswordlessConfig(raw);
|
|
239
323
|
const {
|
|
240
324
|
widgetType,
|
|
241
325
|
engagementMedium = "POPUP",
|
|
@@ -243,17 +327,29 @@ class WidgetApi {
|
|
|
243
327
|
user
|
|
244
328
|
} = clean;
|
|
245
329
|
const tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
246
|
-
const accountId = encodeURIComponent(user.accountId);
|
|
247
|
-
const userId = encodeURIComponent(user.id);
|
|
248
|
-
|
|
249
|
-
const
|
|
250
|
-
widgetType,
|
|
251
|
-
engagementMedium
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
const path = `/api/v1/${tenantAlias}/widget/account/${accountId}/user/${userId}/render${optionalParams}`;
|
|
330
|
+
const accountId = user ? encodeURIComponent(user.accountId) : null;
|
|
331
|
+
const userId = user ? encodeURIComponent(user.id) : null;
|
|
332
|
+
const locale = (_clean$locale = clean.locale) != null ? _clean$locale : validateLocale(navigator.language.replace(/\-/g, "_"));
|
|
333
|
+
const path = `/api/v1/${tenantAlias}/graphql`;
|
|
255
334
|
const url = this.domain + path;
|
|
256
|
-
return
|
|
335
|
+
return new Promise(async (resolve, reject) => {
|
|
336
|
+
try {
|
|
337
|
+
var _res$body, _res$body$data;
|
|
338
|
+
|
|
339
|
+
const res = await doQuery(url, RENDER_WIDGET_QUERY, {
|
|
340
|
+
user: userId && accountId ? {
|
|
341
|
+
id: userId,
|
|
342
|
+
accountId
|
|
343
|
+
} : null,
|
|
344
|
+
engagementMedium,
|
|
345
|
+
widgetType,
|
|
346
|
+
locale
|
|
347
|
+
}, jwt);
|
|
348
|
+
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);
|
|
349
|
+
} catch (e) {
|
|
350
|
+
reject(e);
|
|
351
|
+
}
|
|
352
|
+
});
|
|
257
353
|
}
|
|
258
354
|
/**
|
|
259
355
|
* An API call to send out referral invites to contacts
|
|
@@ -287,18 +383,21 @@ class WidgetApi {
|
|
|
287
383
|
/**
|
|
288
384
|
* Looks up the referral code of the current user, if there is any.
|
|
289
385
|
*
|
|
290
|
-
* @return {Promise<
|
|
386
|
+
* @return {Promise<ReferralCookie>} code referral code if true.
|
|
291
387
|
*/
|
|
292
388
|
|
|
293
389
|
|
|
294
|
-
squatchReferralCookie() {
|
|
390
|
+
async squatchReferralCookie() {
|
|
295
391
|
const tenantAlias = encodeURIComponent(this.tenantAlias);
|
|
296
392
|
|
|
297
|
-
const _saasquatch = Cookies.get("_saasquatch");
|
|
393
|
+
const _saasquatch = Cookies.get("_saasquatch") || "";
|
|
298
394
|
|
|
299
395
|
const cookie = _saasquatch ? `?cookies=${encodeURIComponent(_saasquatch)}` : ``;
|
|
300
396
|
const url = `${this.domain}/a/${tenantAlias}/widgets/squatchcookiejson${cookie}`;
|
|
301
|
-
|
|
397
|
+
const response = await doGet(url);
|
|
398
|
+
return Promise.resolve(_extends({}, response, {
|
|
399
|
+
encodedCookie: _saasquatch
|
|
400
|
+
}));
|
|
302
401
|
}
|
|
303
402
|
|
|
304
403
|
} // builds a param string for widgets
|
|
@@ -341,6 +440,7 @@ class AnalyticsApi {
|
|
|
341
440
|
}
|
|
342
441
|
|
|
343
442
|
pushAnalyticsLoadEvent(params) {
|
|
443
|
+
if (!params.externalUserId || !params.externalAccountId) return;
|
|
344
444
|
const tenantAlias = encodeURIComponent(params.tenantAlias);
|
|
345
445
|
const accountId = encodeURIComponent(params.externalAccountId);
|
|
346
446
|
const userId = encodeURIComponent(params.externalUserId);
|
|
@@ -367,7 +467,7 @@ class AnalyticsApi {
|
|
|
367
467
|
// @ts-check
|
|
368
468
|
/** @hidden */
|
|
369
469
|
|
|
370
|
-
const _log$
|
|
470
|
+
const _log$7 = debug__default("squatch-js:widget");
|
|
371
471
|
/*
|
|
372
472
|
* The Widget class is the base class for the different widget types available
|
|
373
473
|
*
|
|
@@ -380,7 +480,7 @@ const _log$6 = debug__default("squatch-js:widget");
|
|
|
380
480
|
|
|
381
481
|
class Widget {
|
|
382
482
|
constructor(params) {
|
|
383
|
-
_log$
|
|
483
|
+
_log$7("widget initializing ...");
|
|
384
484
|
|
|
385
485
|
this.content = params.content === "error" ? this._error(params.rsCode) : params.content;
|
|
386
486
|
this.type = params.type;
|
|
@@ -398,6 +498,8 @@ class Widget {
|
|
|
398
498
|
}
|
|
399
499
|
|
|
400
500
|
_loadEvent(sqh) {
|
|
501
|
+
var _this$analyticsApi$pu;
|
|
502
|
+
|
|
401
503
|
if (!sqh) return; // No non-truthy value
|
|
402
504
|
|
|
403
505
|
if (!isObject$1(sqh)) {
|
|
@@ -431,10 +533,10 @@ class Widget {
|
|
|
431
533
|
};
|
|
432
534
|
}
|
|
433
535
|
|
|
434
|
-
this.analyticsApi.pushAnalyticsLoadEvent(params).then(response => {
|
|
435
|
-
_log$
|
|
536
|
+
(_this$analyticsApi$pu = this.analyticsApi.pushAnalyticsLoadEvent(params)) == null ? void 0 : _this$analyticsApi$pu.then(response => {
|
|
537
|
+
_log$7(`${params.engagementMedium} loaded event recorded.`);
|
|
436
538
|
}).catch(ex => {
|
|
437
|
-
_log$
|
|
539
|
+
_log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
|
|
438
540
|
});
|
|
439
541
|
}
|
|
440
542
|
|
|
@@ -447,9 +549,9 @@ class Widget {
|
|
|
447
549
|
engagementMedium: sqh.mode.widgetMode,
|
|
448
550
|
shareMedium: medium
|
|
449
551
|
}).then(response => {
|
|
450
|
-
_log$
|
|
552
|
+
_log$7(`${sqh.mode.widgetMode} share ${medium} event recorded. ${response}`);
|
|
451
553
|
}).catch(ex => {
|
|
452
|
-
_log$
|
|
554
|
+
_log$7(new Error(`pushAnalyticsLoadEvent() ${ex}`));
|
|
453
555
|
});
|
|
454
556
|
}
|
|
455
557
|
}
|
|
@@ -462,9 +564,9 @@ class Widget {
|
|
|
462
564
|
userId: sqh.analytics.attributes.userId,
|
|
463
565
|
emailList
|
|
464
566
|
}).then(response => {
|
|
465
|
-
_log$
|
|
567
|
+
_log$7(`Sent email invites to share ${emailList}. ${response}`);
|
|
466
568
|
}).catch(ex => {
|
|
467
|
-
_log$
|
|
569
|
+
_log$7(new Error(`invite() ${ex}`));
|
|
468
570
|
});
|
|
469
571
|
}
|
|
470
572
|
}
|
|
@@ -553,6 +655,7 @@ class Widget {
|
|
|
553
655
|
email: email || null,
|
|
554
656
|
firstName: firstName || null,
|
|
555
657
|
lastName: lastName || null,
|
|
658
|
+
// FIXME: Double check this
|
|
556
659
|
id: this.context.user.id,
|
|
557
660
|
accountId: this.context.user.accountId
|
|
558
661
|
};
|
|
@@ -562,6 +665,13 @@ class Widget {
|
|
|
562
665
|
widgetType: this.type,
|
|
563
666
|
jwt
|
|
564
667
|
});
|
|
668
|
+
} else if (this.context.type === "passwordless") {
|
|
669
|
+
response = this.widgetApi.render({
|
|
670
|
+
user: undefined,
|
|
671
|
+
engagementMedium,
|
|
672
|
+
widgetType: this.type,
|
|
673
|
+
jwt: undefined
|
|
674
|
+
});
|
|
565
675
|
} else {
|
|
566
676
|
throw new Error("can't reload an error widget");
|
|
567
677
|
}
|
|
@@ -596,7 +706,7 @@ class Widget {
|
|
|
596
706
|
}).catch(({
|
|
597
707
|
message
|
|
598
708
|
}) => {
|
|
599
|
-
_log$
|
|
709
|
+
_log$7(`${message}`);
|
|
600
710
|
});
|
|
601
711
|
}
|
|
602
712
|
|
|
@@ -633,7 +743,7 @@ function domready(targetDoc, fn) {
|
|
|
633
743
|
|
|
634
744
|
// @ts-check
|
|
635
745
|
|
|
636
|
-
const _log$
|
|
746
|
+
const _log$6 = debug__default("squatch-js:EMBEDwidget");
|
|
637
747
|
/**
|
|
638
748
|
* An EmbedWidget is displayed inline in part of your page.
|
|
639
749
|
*
|
|
@@ -651,22 +761,22 @@ class EmbedWidget extends Widget {
|
|
|
651
761
|
// selector is a string
|
|
652
762
|
element = document.querySelector(container);
|
|
653
763
|
|
|
654
|
-
_log$
|
|
764
|
+
_log$6("loading widget with selector", element); // selector is an HTML element
|
|
655
765
|
|
|
656
766
|
} else if (container instanceof HTMLElement) {
|
|
657
767
|
element = container;
|
|
658
768
|
|
|
659
|
-
_log$
|
|
769
|
+
_log$6("loading widget with container", element); // garbage container found
|
|
660
770
|
|
|
661
771
|
} else if (container) {
|
|
662
772
|
element = null;
|
|
663
773
|
|
|
664
|
-
_log$
|
|
774
|
+
_log$6("container must be an HTMLElement or string", container); // find element on page
|
|
665
775
|
|
|
666
776
|
} else {
|
|
667
777
|
element = document.querySelector("#squatchembed") || document.querySelector(".squatchembed");
|
|
668
778
|
|
|
669
|
-
_log$
|
|
779
|
+
_log$6("loading widget with default selector", element);
|
|
670
780
|
}
|
|
671
781
|
|
|
672
782
|
if (!(element instanceof HTMLElement)) throw new Error(`element with selector '${container}' not found.'`);
|
|
@@ -732,7 +842,7 @@ class EmbedWidget extends Widget {
|
|
|
732
842
|
if (!this.context.container) {
|
|
733
843
|
this._loadEvent(_sqh);
|
|
734
844
|
|
|
735
|
-
_log$
|
|
845
|
+
_log$6("loaded");
|
|
736
846
|
}
|
|
737
847
|
});
|
|
738
848
|
} // Un-hide if element is available and refresh data
|
|
@@ -741,7 +851,7 @@ class EmbedWidget extends Widget {
|
|
|
741
851
|
open() {
|
|
742
852
|
var _this$frame, _this$frame$contentDo, _this$frame2, _this$frame2$contentW, _this$frame3, _this$frame3$contentW;
|
|
743
853
|
|
|
744
|
-
if (!this.frame) return _log$
|
|
854
|
+
if (!this.frame) return _log$6("no target element to open");
|
|
745
855
|
this.element.style.visibility = "unset";
|
|
746
856
|
this.element.style.height = "auto";
|
|
747
857
|
this.element.style["overflow-y"] = "auto";
|
|
@@ -751,16 +861,16 @@ class EmbedWidget extends Widget {
|
|
|
751
861
|
|
|
752
862
|
this._loadEvent(_sqh);
|
|
753
863
|
|
|
754
|
-
_log$
|
|
864
|
+
_log$6("loaded");
|
|
755
865
|
}
|
|
756
866
|
|
|
757
867
|
close() {
|
|
758
|
-
if (!this.frame) return _log$
|
|
868
|
+
if (!this.frame) return _log$6("no target element to close");
|
|
759
869
|
this.element.style.visibility = "hidden";
|
|
760
870
|
this.element.style.height = "0";
|
|
761
871
|
this.element.style["overflow-y"] = "hidden";
|
|
762
872
|
|
|
763
|
-
_log$
|
|
873
|
+
_log$6("Embed widget closed");
|
|
764
874
|
}
|
|
765
875
|
|
|
766
876
|
_error(rs, mode = "embed", style = "") {
|
|
@@ -771,7 +881,7 @@ class EmbedWidget extends Widget {
|
|
|
771
881
|
|
|
772
882
|
// @ts-check
|
|
773
883
|
|
|
774
|
-
const _log$
|
|
884
|
+
const _log$5 = debug__default("squatch-js:POPUPwidget");
|
|
775
885
|
/**
|
|
776
886
|
* The PopupWidget is used to display popups (also known as "Modals").
|
|
777
887
|
* Popups widgets are rendered on top of other elements in a page.
|
|
@@ -789,9 +899,9 @@ class PopupWidget extends Widget {
|
|
|
789
899
|
this.triggerElement
|
|
790
900
|
/* HTMLButton */
|
|
791
901
|
= document.querySelector(trigger);
|
|
792
|
-
if (trigger && !this.triggerElement) _log$
|
|
902
|
+
if (trigger && !this.triggerElement) _log$5("No element found with trigger selector", trigger);
|
|
793
903
|
} catch (_unused) {
|
|
794
|
-
_log$
|
|
904
|
+
_log$5("Not a valid selector", trigger);
|
|
795
905
|
} // Trigger is optional
|
|
796
906
|
|
|
797
907
|
|
|
@@ -814,6 +924,7 @@ class PopupWidget extends Widget {
|
|
|
814
924
|
this.popupdiv = document.createElement("div");
|
|
815
925
|
this.popupdiv.id = "squatchModal";
|
|
816
926
|
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);");
|
|
927
|
+
document.head.insertAdjacentHTML("beforeend", `<style>#squatchModal::-webkit-scrollbar { display: none; }</style>`);
|
|
817
928
|
this.popupcontent = document.createElement("div");
|
|
818
929
|
this.popupcontent.setAttribute("style", "margin: auto; width: 80%; max-width: 500px; position: relative;");
|
|
819
930
|
|
|
@@ -833,7 +944,7 @@ class PopupWidget extends Widget {
|
|
|
833
944
|
frameDoc.write(`<script src="${this.npmCdn}/resize-observer-polyfill@1.5.x"></script>`);
|
|
834
945
|
frameDoc.close();
|
|
835
946
|
|
|
836
|
-
_log$
|
|
947
|
+
_log$5("Popup template loaded into iframe");
|
|
837
948
|
|
|
838
949
|
this._setupResizeHandler();
|
|
839
950
|
}
|
|
@@ -906,7 +1017,7 @@ class PopupWidget extends Widget {
|
|
|
906
1017
|
|
|
907
1018
|
this._loadEvent(_sqh);
|
|
908
1019
|
|
|
909
|
-
_log$
|
|
1020
|
+
_log$5("Popup opened");
|
|
910
1021
|
});
|
|
911
1022
|
}
|
|
912
1023
|
|
|
@@ -914,7 +1025,7 @@ class PopupWidget extends Widget {
|
|
|
914
1025
|
this.popupdiv.style.visibility = "hidden";
|
|
915
1026
|
this.popupdiv.style.top = "-2000px";
|
|
916
1027
|
|
|
917
|
-
_log$
|
|
1028
|
+
_log$5("Popup closed");
|
|
918
1029
|
}
|
|
919
1030
|
|
|
920
1031
|
_clickedOutside({
|
|
@@ -932,7 +1043,7 @@ class PopupWidget extends Widget {
|
|
|
932
1043
|
|
|
933
1044
|
}
|
|
934
1045
|
|
|
935
|
-
const _log$
|
|
1046
|
+
const _log$4 = debug("squatch-js:CTAwidget");
|
|
936
1047
|
/**
|
|
937
1048
|
* A CtaWidget is displayed on top of your page
|
|
938
1049
|
*
|
|
@@ -943,7 +1054,7 @@ const _log$3 = debug("squatch-js:CTAwidget");
|
|
|
943
1054
|
|
|
944
1055
|
class CtaWidget extends PopupWidget {
|
|
945
1056
|
constructor(params, opts) {
|
|
946
|
-
_log$
|
|
1057
|
+
_log$4("CTA constructor");
|
|
947
1058
|
|
|
948
1059
|
const ctaElement = document.createElement("div");
|
|
949
1060
|
ctaElement.id = "cta";
|
|
@@ -971,7 +1082,7 @@ class CtaWidget extends PopupWidget {
|
|
|
971
1082
|
this.ctaFrame.setAttribute("style", `border:0; background-color:transparent; position:fixed; display:none;${this.side}${this.position}`);
|
|
972
1083
|
document.body.appendChild(this.ctaFrame);
|
|
973
1084
|
|
|
974
|
-
_log$
|
|
1085
|
+
_log$4("ctaframe appended to body");
|
|
975
1086
|
}
|
|
976
1087
|
|
|
977
1088
|
load() {
|
|
@@ -1035,10 +1146,10 @@ class CtaWidget extends PopupWidget {
|
|
|
1035
1146
|
});
|
|
1036
1147
|
ro.observe(ctaContainer);
|
|
1037
1148
|
|
|
1038
|
-
_log$
|
|
1149
|
+
_log$4("CTA template loaded into iframe");
|
|
1039
1150
|
});
|
|
1040
1151
|
} else {
|
|
1041
|
-
_log$
|
|
1152
|
+
_log$4(new Error("CTA element not found in theme"));
|
|
1042
1153
|
}
|
|
1043
1154
|
});
|
|
1044
1155
|
}
|
|
@@ -1061,7 +1172,7 @@ class CtaWidget extends PopupWidget {
|
|
|
1061
1172
|
|
|
1062
1173
|
}
|
|
1063
1174
|
|
|
1064
|
-
const _log$
|
|
1175
|
+
const _log$3 = debug__default("squatch-js:widgets");
|
|
1065
1176
|
/**
|
|
1066
1177
|
*
|
|
1067
1178
|
* `Widgets` is a factory for creating widgets. It's possible to build your own widgets using the
|
|
@@ -1126,7 +1237,7 @@ class Widgets {
|
|
|
1126
1237
|
return {
|
|
1127
1238
|
widget: this._renderWidget(response, clean, {
|
|
1128
1239
|
type: "upsert",
|
|
1129
|
-
user: clean.user,
|
|
1240
|
+
user: clean.user || null,
|
|
1130
1241
|
engagementMedium: config.engagementMedium,
|
|
1131
1242
|
container: config.container,
|
|
1132
1243
|
trigger: config.trigger
|
|
@@ -1134,7 +1245,7 @@ class Widgets {
|
|
|
1134
1245
|
user: response.user
|
|
1135
1246
|
};
|
|
1136
1247
|
} catch (err) {
|
|
1137
|
-
_log$
|
|
1248
|
+
_log$3(err);
|
|
1138
1249
|
|
|
1139
1250
|
if (err.apiErrorCode) {
|
|
1140
1251
|
this._renderErrorWidget(err, config.engagementMedium);
|
|
@@ -1162,15 +1273,13 @@ class Widgets {
|
|
|
1162
1273
|
|
|
1163
1274
|
async render(config) {
|
|
1164
1275
|
const raw = config;
|
|
1165
|
-
const clean =
|
|
1276
|
+
const clean = validatePasswordlessConfig(raw);
|
|
1166
1277
|
|
|
1167
1278
|
try {
|
|
1168
|
-
const response = await this.api.
|
|
1279
|
+
const response = await this.api.render(clean);
|
|
1169
1280
|
return {
|
|
1170
|
-
widget: this._renderWidget({
|
|
1171
|
-
|
|
1172
|
-
}, clean, {
|
|
1173
|
-
type: "cookie",
|
|
1281
|
+
widget: this._renderWidget(response, clean, {
|
|
1282
|
+
type: "passwordless",
|
|
1174
1283
|
engagementMedium: clean.engagementMedium
|
|
1175
1284
|
}),
|
|
1176
1285
|
user: response.user
|
|
@@ -1197,7 +1306,7 @@ class Widgets {
|
|
|
1197
1306
|
|
|
1198
1307
|
if (typeof input === "function") {
|
|
1199
1308
|
this.api.squatchReferralCookie().then((...args) => input(...args)).catch(ex => {
|
|
1200
|
-
_log$
|
|
1309
|
+
_log$3("Autofill error", ex);
|
|
1201
1310
|
|
|
1202
1311
|
throw ex;
|
|
1203
1312
|
});
|
|
@@ -1212,7 +1321,7 @@ class Widgets {
|
|
|
1212
1321
|
// Only use the first element found
|
|
1213
1322
|
elem = elems[0];
|
|
1214
1323
|
} else {
|
|
1215
|
-
_log$
|
|
1324
|
+
_log$3("Element id/class or function missing");
|
|
1216
1325
|
|
|
1217
1326
|
throw new Error("Element id/class or function missing");
|
|
1218
1327
|
}
|
|
@@ -1250,11 +1359,11 @@ class Widgets {
|
|
|
1250
1359
|
|
|
1251
1360
|
|
|
1252
1361
|
_renderWidget(response, config, context) {
|
|
1253
|
-
_log$
|
|
1362
|
+
_log$3("Rendering Widget...");
|
|
1254
1363
|
|
|
1255
1364
|
if (!response) throw new Error("Unable to get a response");
|
|
1256
1365
|
let widget;
|
|
1257
|
-
let displayOnLoad =
|
|
1366
|
+
let displayOnLoad = !!config.displayOnLoad;
|
|
1258
1367
|
let displayCTA = false;
|
|
1259
1368
|
const opts = response.jsOptions || "";
|
|
1260
1369
|
const params = {
|
|
@@ -1273,9 +1382,9 @@ class Widgets {
|
|
|
1273
1382
|
displayOnLoad = rule.displayOnLoad;
|
|
1274
1383
|
displayCTA = rule.showAsCTA;
|
|
1275
1384
|
|
|
1276
|
-
_log$
|
|
1385
|
+
_log$3(`Display ${rule.widgetType} on ${rule.url}`);
|
|
1277
1386
|
} else {
|
|
1278
|
-
_log$
|
|
1387
|
+
_log$3(`Don't display ${rule.widgetType} when no referral on widget rule match ${rule.url}`);
|
|
1279
1388
|
}
|
|
1280
1389
|
}
|
|
1281
1390
|
});
|
|
@@ -1284,20 +1393,20 @@ class Widgets {
|
|
|
1284
1393
|
if (opts.conversionUrls) {
|
|
1285
1394
|
opts.conversionUrls.forEach(rule => {
|
|
1286
1395
|
if (response.user.referredBy && Widgets._matchesUrl(rule)) {
|
|
1287
|
-
_log$
|
|
1396
|
+
_log$3("This is a conversion URL", rule);
|
|
1288
1397
|
}
|
|
1289
1398
|
});
|
|
1290
1399
|
}
|
|
1291
1400
|
|
|
1292
1401
|
if (opts.fuelTankAutofillUrls) {
|
|
1293
|
-
_log$
|
|
1402
|
+
_log$3("We found a fuel tank autofill!");
|
|
1294
1403
|
|
|
1295
1404
|
opts.fuelTankAutofillUrls.forEach(({
|
|
1296
1405
|
url,
|
|
1297
1406
|
formSelector
|
|
1298
1407
|
}) => {
|
|
1299
1408
|
if (Widgets._matchesUrl(url)) {
|
|
1300
|
-
_log$
|
|
1409
|
+
_log$3("Fuel Tank URL matches");
|
|
1301
1410
|
|
|
1302
1411
|
if (response.user.referredBy && response.user.referredBy.code) {
|
|
1303
1412
|
const formAutofill = document.querySelector(formSelector);
|
|
@@ -1305,7 +1414,7 @@ class Widgets {
|
|
|
1305
1414
|
if (formAutofill) {
|
|
1306
1415
|
formAutofill.value = response.user.referredBy.referredReward.fuelTankCode || "";
|
|
1307
1416
|
} else {
|
|
1308
|
-
_log$
|
|
1417
|
+
_log$3(new Error(`Element with id/class ${formSelector} was not found.`));
|
|
1309
1418
|
}
|
|
1310
1419
|
}
|
|
1311
1420
|
}
|
|
@@ -1320,7 +1429,7 @@ class Widgets {
|
|
|
1320
1429
|
widget.load();
|
|
1321
1430
|
if (displayOnLoad) widget.open();
|
|
1322
1431
|
} else if (displayCTA) {
|
|
1323
|
-
_log$
|
|
1432
|
+
_log$3("display CTA");
|
|
1324
1433
|
|
|
1325
1434
|
const side = opts.cta.content.buttonSide;
|
|
1326
1435
|
const position = opts.cta.content.buttonPosition;
|
|
@@ -1331,7 +1440,7 @@ class Widgets {
|
|
|
1331
1440
|
widget.load();
|
|
1332
1441
|
if (displayOnLoad) widget.open();
|
|
1333
1442
|
} else {
|
|
1334
|
-
_log$
|
|
1443
|
+
_log$3("display popup on load");
|
|
1335
1444
|
|
|
1336
1445
|
widget = new PopupWidget(params);
|
|
1337
1446
|
widget.load();
|
|
@@ -1355,7 +1464,7 @@ class Widgets {
|
|
|
1355
1464
|
message
|
|
1356
1465
|
} = props;
|
|
1357
1466
|
|
|
1358
|
-
_log$
|
|
1467
|
+
_log$3(new Error(`${apiErrorCode} (${rsCode}) ${message}`));
|
|
1359
1468
|
|
|
1360
1469
|
const params = {
|
|
1361
1470
|
content: "error",
|
|
@@ -1495,7 +1604,8 @@ function asyncLoad() {
|
|
|
1495
1604
|
|
|
1496
1605
|
if (loaded && cached) {
|
|
1497
1606
|
const ready = cached.ready || [];
|
|
1498
|
-
ready.forEach(cb => setTimeout(() => cb(), 0));
|
|
1607
|
+
ready.forEach(cb => setTimeout(() => cb(), 0));
|
|
1608
|
+
setTimeout(() => window.squatch._auto(), 0); // @ts-ignore -- intetionally deletes `_squatch` to cleanup initialization
|
|
1499
1609
|
|
|
1500
1610
|
window._squatch = undefined;
|
|
1501
1611
|
|
|
@@ -1507,24 +1617,6 @@ function asyncLoad() {
|
|
|
1507
1617
|
}
|
|
1508
1618
|
}
|
|
1509
1619
|
|
|
1510
|
-
function _extends() {
|
|
1511
|
-
_extends = Object.assign || function (target) {
|
|
1512
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
1513
|
-
var source = arguments[i];
|
|
1514
|
-
|
|
1515
|
-
for (var key in source) {
|
|
1516
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1517
|
-
target[key] = source[key];
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
return target;
|
|
1523
|
-
};
|
|
1524
|
-
|
|
1525
|
-
return _extends.apply(this, arguments);
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
1620
|
/*! (c) Andrea Giammarchi - ISC */
|
|
1529
1621
|
var self = undefined || /* istanbul ignore next */ {};
|
|
1530
1622
|
try {
|
|
@@ -1903,7 +1995,7 @@ var URLSearchParams$1 = self.URLSearchParams;
|
|
|
1903
1995
|
|
|
1904
1996
|
/** @hidden */
|
|
1905
1997
|
|
|
1906
|
-
const _log$
|
|
1998
|
+
const _log$2 = debug__default("squatch-js");
|
|
1907
1999
|
|
|
1908
2000
|
const isObject = item => typeof item === "object" && !Array.isArray(item);
|
|
1909
2001
|
|
|
@@ -1956,7 +2048,7 @@ function _pushCookie() {
|
|
|
1956
2048
|
try {
|
|
1957
2049
|
paramsJSON = JSON.parse(b64decode(refParam));
|
|
1958
2050
|
} catch (error) {
|
|
1959
|
-
_log$
|
|
2051
|
+
_log$2("Unable to decode params", error); // don't merge invalid params
|
|
1960
2052
|
|
|
1961
2053
|
|
|
1962
2054
|
return;
|
|
@@ -1965,26 +2057,26 @@ function _pushCookie() {
|
|
|
1965
2057
|
try {
|
|
1966
2058
|
existingCookie = JSON.parse(b64decode(Cookies.get("_saasquatch")));
|
|
1967
2059
|
|
|
1968
|
-
_log$
|
|
2060
|
+
_log$2("existing cookie", existingCookie);
|
|
1969
2061
|
} catch (error) {
|
|
1970
|
-
_log$
|
|
2062
|
+
_log$2("Unable to retrieve cookie", error);
|
|
1971
2063
|
} // don't merge if there's no existing object
|
|
1972
2064
|
|
|
1973
2065
|
|
|
1974
2066
|
try {
|
|
1975
2067
|
const domain = getTopDomain();
|
|
1976
2068
|
|
|
1977
|
-
_log$
|
|
2069
|
+
_log$2("domain retrieved:", domain);
|
|
1978
2070
|
|
|
1979
2071
|
if (existingCookie) {
|
|
1980
2072
|
const newCookie = deepMerge(existingCookie, paramsJSON);
|
|
1981
2073
|
reEncodedCookie = b64encode(JSON.stringify(newCookie));
|
|
1982
2074
|
|
|
1983
|
-
_log$
|
|
2075
|
+
_log$2("cookie to store:", newCookie);
|
|
1984
2076
|
} else {
|
|
1985
2077
|
reEncodedCookie = b64encode(JSON.stringify(paramsJSON));
|
|
1986
2078
|
|
|
1987
|
-
_log$
|
|
2079
|
+
_log$2("cookie to store:", paramsJSON);
|
|
1988
2080
|
}
|
|
1989
2081
|
|
|
1990
2082
|
Cookies.set("_saasquatch", reEncodedCookie, {
|
|
@@ -1995,11 +2087,86 @@ function _pushCookie() {
|
|
|
1995
2087
|
path: "/"
|
|
1996
2088
|
});
|
|
1997
2089
|
} catch (error) {
|
|
1998
|
-
_log$
|
|
2090
|
+
_log$2("Unable to set cookie", error);
|
|
1999
2091
|
}
|
|
2000
2092
|
}
|
|
2001
2093
|
}
|
|
2002
2094
|
|
|
2095
|
+
/** @hidden */
|
|
2096
|
+
|
|
2097
|
+
const _log$1 = debug__default("squatch-js");
|
|
2098
|
+
|
|
2099
|
+
function _getAutoConfig(configIn) {
|
|
2100
|
+
const queryString = window.location.search;
|
|
2101
|
+
const urlParams = new URLSearchParams(queryString);
|
|
2102
|
+
const refParam = urlParams.get("_saasquatchExtra") || "";
|
|
2103
|
+
|
|
2104
|
+
if (!refParam) {
|
|
2105
|
+
_log$1("No _saasquatchExtra param");
|
|
2106
|
+
|
|
2107
|
+
return;
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
let raw;
|
|
2111
|
+
|
|
2112
|
+
try {
|
|
2113
|
+
raw = JSON.parse(b64decode(refParam));
|
|
2114
|
+
} catch (e) {
|
|
2115
|
+
_log$1("Unable to decode _saasquatchExtra config");
|
|
2116
|
+
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
const {
|
|
2121
|
+
domain,
|
|
2122
|
+
tenantAlias,
|
|
2123
|
+
widgetConfig
|
|
2124
|
+
} = convertExtraToConfig(raw);
|
|
2125
|
+
|
|
2126
|
+
if (!domain || !tenantAlias || !widgetConfig) {
|
|
2127
|
+
_log$1("_saasquatchExtra did not have an expected structure");
|
|
2128
|
+
|
|
2129
|
+
return undefined;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
const {
|
|
2133
|
+
autoPopupWidgetType
|
|
2134
|
+
} = widgetConfig,
|
|
2135
|
+
rest = _objectWithoutPropertiesLoose(widgetConfig, ["autoPopupWidgetType"]);
|
|
2136
|
+
|
|
2137
|
+
return {
|
|
2138
|
+
widgetConfig: _extends({
|
|
2139
|
+
widgetType: autoPopupWidgetType,
|
|
2140
|
+
displayOnLoad: true
|
|
2141
|
+
}, rest),
|
|
2142
|
+
squatchConfig: _extends({}, configIn ? {
|
|
2143
|
+
configIn
|
|
2144
|
+
} : {}, {
|
|
2145
|
+
domain,
|
|
2146
|
+
tenantAlias
|
|
2147
|
+
})
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
/**
|
|
2151
|
+
* Deconstructs _saasquatchExtra into domain, tenantAlias, and widgetConfig
|
|
2152
|
+
* @param obj {Record<string, any>} Expected to be of the form `{ [appDomain]: { [tenantAlias]: { autoPopupWidgetType: [widgetType], [rest]?: ... } } }`
|
|
2153
|
+
*/
|
|
2154
|
+
|
|
2155
|
+
function convertExtraToConfig(obj) {
|
|
2156
|
+
var _obj$_domain;
|
|
2157
|
+
|
|
2158
|
+
const _domain = Object.keys(obj || {})[0];
|
|
2159
|
+
const tenantAlias = Object.keys((obj == null ? void 0 : obj[_domain]) || {})[0];
|
|
2160
|
+
const widgetConfig = obj == null ? void 0 : (_obj$_domain = obj[_domain]) == null ? void 0 : _obj$_domain[tenantAlias]; // domain in _saasquatchExtra doesn't contain "https://"
|
|
2161
|
+
|
|
2162
|
+
const domain = _domain ? `https://${_domain}` : undefined;
|
|
2163
|
+
return {
|
|
2164
|
+
domain,
|
|
2165
|
+
tenantAlias,
|
|
2166
|
+
widgetConfig
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2003
2170
|
// @ts-check
|
|
2004
2171
|
function help() {
|
|
2005
2172
|
console.log(`Having trouble using Squatch.js? Go to https://docs.referralsaasquatch.com/developer/ for tutorials, references and error codes.`);
|
|
@@ -2053,6 +2220,33 @@ function widgets() {
|
|
|
2053
2220
|
function events() {
|
|
2054
2221
|
return _events;
|
|
2055
2222
|
}
|
|
2223
|
+
/**
|
|
2224
|
+
* Entry-point for high level API to render a widget using the instance of {@link Widgets} created when you call {@link #init init}.
|
|
2225
|
+
*/
|
|
2226
|
+
|
|
2227
|
+
function widget(widgetConfig) {
|
|
2228
|
+
var _widgets2;
|
|
2229
|
+
|
|
2230
|
+
return (_widgets2 = widgets()) == null ? void 0 : _widgets2.render(widgetConfig);
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Extracts widget configuration from `_saasquatchExtra` UTM parameter. Initialises `squatch` and renders the widget as a {@link PopupWidget} via static instanct of {@link Widgets}.
|
|
2234
|
+
*/
|
|
2235
|
+
|
|
2236
|
+
function _auto(configIn) {
|
|
2237
|
+
const configs = _getAutoConfig(configIn);
|
|
2238
|
+
|
|
2239
|
+
if (configs) {
|
|
2240
|
+
var _widgets3;
|
|
2241
|
+
|
|
2242
|
+
const {
|
|
2243
|
+
squatchConfig,
|
|
2244
|
+
widgetConfig
|
|
2245
|
+
} = configs;
|
|
2246
|
+
init(squatchConfig);
|
|
2247
|
+
return (_widgets3 = widgets()) == null ? void 0 : _widgets3.render(widgetConfig);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2056
2250
|
/**
|
|
2057
2251
|
* Initializes the static `squatch` global. This sets up:
|
|
2058
2252
|
*
|
|
@@ -2095,7 +2289,7 @@ function init(configIn) {
|
|
|
2095
2289
|
* @example
|
|
2096
2290
|
* squatch.ready(function() {
|
|
2097
2291
|
* console.log("ready!");
|
|
2098
|
-
* squatch.api().
|
|
2292
|
+
* squatch.api().upsertUser();
|
|
2099
2293
|
* });
|
|
2100
2294
|
*/
|
|
2101
2295
|
|
|
@@ -2157,5 +2351,5 @@ if (typeof document !== "undefined" && !window.SaaSquatchDoNotAutoDrop) {
|
|
|
2157
2351
|
|
|
2158
2352
|
if (typeof document !== "undefined") asyncLoad();
|
|
2159
2353
|
|
|
2160
|
-
export { CtaWidget, EmbedWidget, PopupWidget, WidgetApi, Widgets, api, autofill, events, help, init, pushCookie, ready, submitEmail, widgets };
|
|
2354
|
+
export { CtaWidget, EmbedWidget, PopupWidget, WidgetApi, Widgets, _auto, api, autofill, events, help, init, pushCookie, ready, submitEmail, widget, widgets };
|
|
2161
2355
|
//# sourceMappingURL=squatch.esm.js.map
|