@blotoutio/providers-blotout-wallet-sdk 0.61.0 → 0.62.1
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/index.cjs.js +136 -107
- package/index.js +136 -107
- package/index.mjs +136 -107
- package/package.json +1 -1
- package/stores/shopify/index.cjs.js +2 -1
- package/stores/shopify/index.js +2 -1
- package/stores/shopify/index.mjs +2 -1
package/index.cjs.js
CHANGED
@@ -34,6 +34,8 @@ new Set([
|
|
34
34
|
...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
|
35
35
|
]);
|
36
36
|
|
37
|
+
const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
|
38
|
+
|
37
39
|
const customAttributes = {
|
38
40
|
'--bw-primary': { type: 'color', defaultValue: '#000000' },
|
39
41
|
'--bw-title-color': { type: 'color', defaultValue: '#000000' },
|
@@ -80,7 +82,8 @@ const parseCookies = (cookie) => {
|
|
80
82
|
return Object.fromEntries(cookie
|
81
83
|
.split(/;\s+/)
|
82
84
|
.map((r) => r.split('=').map((str) => str.trim()))
|
83
|
-
.map(([cookieKey,
|
85
|
+
.map(([cookieKey, ...cookieValues]) => {
|
86
|
+
const cookieValue = cookieValues.join('=');
|
84
87
|
if (!cookieKey) {
|
85
88
|
return [];
|
86
89
|
}
|
@@ -119,7 +122,7 @@ const setCookie = (key, value, options) => {
|
|
119
122
|
if (options === null || options === void 0 ? void 0 : options.secure) {
|
120
123
|
extras.push('secure');
|
121
124
|
}
|
122
|
-
document.cookie = `${key}=${value};${extras.join(';')}`;
|
125
|
+
document.cookie = `${key}=${encodeURIComponent(value)};${extras.join(';')}`;
|
123
126
|
}
|
124
127
|
catch {
|
125
128
|
return;
|
@@ -362,31 +365,43 @@ const cssVars = i$4 `
|
|
362
365
|
}
|
363
366
|
`;
|
364
367
|
|
368
|
+
const isGecko = () => /\bGecko\/\d+/.test(navigator.userAgent);
|
369
|
+
|
365
370
|
const fadeInDialog = (element) => {
|
366
|
-
const
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
371
|
+
const animations = [
|
372
|
+
element.animate([
|
373
|
+
{ transform: 'translateY(-20px)', opacity: 0 },
|
374
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
375
|
+
], { duration: 600, easing: spring, composite: 'add' }),
|
376
|
+
];
|
377
|
+
// Gecko does not support animating ::backdrop pseudo elements
|
378
|
+
if (!isGecko()) {
|
379
|
+
animations.push(element.animate([{ opacity: 0 }, { opacity: 1 }], {
|
380
|
+
duration: 300,
|
381
|
+
easing: 'ease-out',
|
382
|
+
pseudoElement: '::backdrop',
|
383
|
+
fill: 'forwards',
|
384
|
+
}));
|
385
|
+
}
|
386
|
+
return Promise.all(animations.map((anim) => anim.finished));
|
377
387
|
};
|
378
388
|
const fadeOutToBottom = (element) => {
|
379
|
-
const
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
389
|
+
const animations = [
|
390
|
+
element.animate([
|
391
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
392
|
+
{ transform: 'translateY(20px)', opacity: 0 },
|
393
|
+
], { duration: 600, easing: spring }),
|
394
|
+
];
|
395
|
+
// Gecko does not support animating ::backdrop pseudo elements
|
396
|
+
if (!isGecko()) {
|
397
|
+
animations.push(element.animate([{ opacity: 1 }, { opacity: 0 }], {
|
398
|
+
duration: 300,
|
399
|
+
easing: 'ease-out',
|
400
|
+
pseudoElement: '::backdrop',
|
401
|
+
fill: 'forwards',
|
402
|
+
}));
|
403
|
+
}
|
404
|
+
return Promise.all(animations.map((anim) => anim.finished));
|
390
405
|
};
|
391
406
|
const flipOut = (element) => {
|
392
407
|
const animation = element.animate([
|
@@ -449,7 +464,6 @@ const formatString = (str) => {
|
|
449
464
|
const parts = str.split(/<\s*br\s*\/?\s*>/);
|
450
465
|
return o(parts, x `<br />`);
|
451
466
|
};
|
452
|
-
const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
|
453
467
|
let BlotoutWallet = class BlotoutWallet extends s {
|
454
468
|
constructor() {
|
455
469
|
super(...arguments);
|
@@ -462,78 +476,76 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
462
476
|
.then(() => (this.state = newState))
|
463
477
|
.then(() => flipIn(this.dialog));
|
464
478
|
};
|
479
|
+
this.restoreCart = async () => {
|
480
|
+
if (!this.lastExpiredCart) {
|
481
|
+
return;
|
482
|
+
}
|
483
|
+
const email = this.email.value.trim().toLowerCase();
|
484
|
+
if (email) {
|
485
|
+
window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
|
486
|
+
const response = await fetch(this.getUrl('/user/email'), {
|
487
|
+
method: 'POST',
|
488
|
+
body: JSON.stringify({
|
489
|
+
email: email,
|
490
|
+
}),
|
491
|
+
headers: this.getHeaders(true),
|
492
|
+
});
|
493
|
+
if (!response.ok) {
|
494
|
+
throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
|
495
|
+
}
|
496
|
+
this.email.value = '';
|
497
|
+
this.hasEmail = true;
|
498
|
+
this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
|
499
|
+
window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
|
500
|
+
}
|
501
|
+
await this.storeApi.addItems(this.lastExpiredCart.items);
|
502
|
+
const expiredCartId = this.lastExpiredCart.cartId;
|
503
|
+
// this cookie will be cleared once the next event is processed
|
504
|
+
setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
|
505
|
+
// We attempt to mark the cart as restored, but if the request fails,
|
506
|
+
// we log the error in the console and let the user continue. Since the
|
507
|
+
// problem is probably in the `/cart/restore` endpoint, further attempts
|
508
|
+
// would not resolve the problem, which would just increase the number
|
509
|
+
// of failed calls and not solve the problem.
|
510
|
+
const response = await fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
|
511
|
+
method: 'POST',
|
512
|
+
headers: this.getHeaders(),
|
513
|
+
});
|
514
|
+
if (!response.ok) {
|
515
|
+
throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
|
516
|
+
}
|
517
|
+
this.lastExpiredCart = undefined;
|
518
|
+
this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
|
519
|
+
bubbles: true,
|
520
|
+
}));
|
521
|
+
// Send the request as beacon as there could be a immediate redirect in the next step
|
522
|
+
window.edgetag('tag', 'CartRecovery_CartRestored', { isSilent: !!this.silentRestore }, {}, { method: 'beacon' });
|
523
|
+
};
|
465
524
|
this.onSubmit = async (ev) => {
|
466
525
|
ev.preventDefault();
|
467
526
|
ev.stopPropagation();
|
468
|
-
const email = this.email.value.trim().toLowerCase();
|
469
527
|
try {
|
470
528
|
await this.transitionTo('loading');
|
471
|
-
|
472
|
-
window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
|
473
|
-
const response = await fetch(this.getUrl('/user/email'), {
|
474
|
-
method: 'POST',
|
475
|
-
body: JSON.stringify({
|
476
|
-
email: email,
|
477
|
-
}),
|
478
|
-
headers: this.getHeaders(true),
|
479
|
-
});
|
480
|
-
if (!response.ok) {
|
481
|
-
throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
|
482
|
-
}
|
483
|
-
this.email.value = '';
|
484
|
-
this.hasEmail = true;
|
485
|
-
this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
|
486
|
-
window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
|
487
|
-
}
|
488
|
-
if (this.lastExpiredCart) {
|
489
|
-
await this.storeApi.addItems(this.lastExpiredCart.items);
|
490
|
-
this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
|
491
|
-
bubbles: true,
|
492
|
-
}));
|
493
|
-
const expiredCartId = this.lastExpiredCart.cartId;
|
494
|
-
// this cookie will be cleared once the next event is processed
|
495
|
-
setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
|
496
|
-
// We attempt to mark the cart as restored, but if the request fails,
|
497
|
-
// we log the error in the console and let the user continue. Since the
|
498
|
-
// problem is probably in the `/cart/restore` endpoint, further attempts
|
499
|
-
// would not resolve the problem, which would just increase the number
|
500
|
-
// of failed calls and not solve the problem.
|
501
|
-
fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
|
502
|
-
method: 'POST',
|
503
|
-
headers: this.getHeaders(),
|
504
|
-
})
|
505
|
-
.then(async (response) => {
|
506
|
-
if (!response.ok) {
|
507
|
-
throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
|
508
|
-
}
|
509
|
-
// Send the request as beacon as there could be a immediate redirect in the next step
|
510
|
-
window.edgetag('tag', 'CartRecovery_CartRestored', {}, {}, { method: 'beacon' });
|
511
|
-
// Redirect to custom path
|
512
|
-
if (this.restoreRedirect) {
|
513
|
-
try {
|
514
|
-
const redirect = new URL(this.restoreRedirect, window.location.origin);
|
515
|
-
window.location.href = redirect.href;
|
516
|
-
}
|
517
|
-
catch (e) {
|
518
|
-
console.error('Invalid redirect URL', e);
|
519
|
-
}
|
520
|
-
}
|
521
|
-
})
|
522
|
-
.catch((err) => {
|
523
|
-
console.error(err);
|
524
|
-
});
|
525
|
-
this.lastExpiredCart = undefined;
|
526
|
-
}
|
529
|
+
await this.restoreCart();
|
527
530
|
await this.transitionTo('restored');
|
528
|
-
delay(2000)
|
529
|
-
|
530
|
-
|
531
|
+
await delay(2000);
|
532
|
+
if (this.state == 'restored') {
|
533
|
+
this.hideModal('restore');
|
534
|
+
}
|
535
|
+
// Redirect to custom path
|
536
|
+
if (this.restoreRedirect) {
|
537
|
+
try {
|
538
|
+
const redirect = new URL(this.restoreRedirect, window.location.origin);
|
539
|
+
window.location.href = redirect.href;
|
531
540
|
}
|
532
|
-
|
541
|
+
catch (e) {
|
542
|
+
console.error('Invalid redirect URL', e);
|
543
|
+
}
|
544
|
+
}
|
533
545
|
}
|
534
546
|
catch (e) {
|
535
|
-
await this.transitionTo('failed');
|
536
547
|
logger.error(e);
|
548
|
+
await this.transitionTo('failed');
|
537
549
|
}
|
538
550
|
};
|
539
551
|
this.onDialogClick = () => {
|
@@ -643,6 +655,7 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
643
655
|
}
|
644
656
|
}
|
645
657
|
async initialize() {
|
658
|
+
var _a;
|
646
659
|
if (!this.userId) {
|
647
660
|
logger.error('No UserId set');
|
648
661
|
return;
|
@@ -651,11 +664,11 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
651
664
|
return;
|
652
665
|
}
|
653
666
|
await delay(POPUP_IMPRESSION_DELAY);
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
667
|
+
try {
|
668
|
+
const response = await fetch(this.getUrl('/cart/expired'), {
|
669
|
+
method: 'GET',
|
670
|
+
headers: this.getHeaders(),
|
671
|
+
});
|
659
672
|
if (!response.ok) {
|
660
673
|
throw new Error(`Unable to get Expired Cart ${response.status}: ${await response.text()}`);
|
661
674
|
}
|
@@ -663,16 +676,27 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
663
676
|
const result = await response.json();
|
664
677
|
this.hasEmail = result.email;
|
665
678
|
this.lastExpiredCart = result.carts[0];
|
666
|
-
if (
|
667
|
-
this.
|
668
|
-
|
679
|
+
if ((_a = result.carts) === null || _a === void 0 ? void 0 : _a.length) {
|
680
|
+
if (this.silentRestore) {
|
681
|
+
this.restoreCart().catch(logger.error);
|
682
|
+
}
|
683
|
+
else if (!this.isPopUpDismissed) {
|
684
|
+
this.showModal();
|
685
|
+
}
|
686
|
+
if (result.hasJustExpired) {
|
687
|
+
window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
|
688
|
+
}
|
669
689
|
}
|
670
|
-
}
|
671
|
-
|
690
|
+
}
|
691
|
+
catch (err) {
|
692
|
+
logger.error(err);
|
693
|
+
}
|
672
694
|
}
|
673
695
|
showModal() {
|
674
696
|
this.dialog.showModal();
|
675
|
-
new Promise(requestAnimationFrame)
|
697
|
+
new Promise(requestAnimationFrame)
|
698
|
+
.catch(logger.error)
|
699
|
+
.finally(() => fadeInDialog(this.dialog));
|
676
700
|
this.dispatchEvent(new CustomEvent('blotout-wallet-shown', { bubbles: true }));
|
677
701
|
fetch(this.getUrl('/user/event'), {
|
678
702
|
method: 'POST',
|
@@ -681,7 +705,9 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
681
705
|
}).catch(logger.error);
|
682
706
|
}
|
683
707
|
hideModal(action) {
|
684
|
-
fadeOutToBottom(this.dialog)
|
708
|
+
fadeOutToBottom(this.dialog)
|
709
|
+
.catch(logger.error)
|
710
|
+
.finally(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
|
685
711
|
this.dispatchEvent(new CustomEvent('blotout-wallet-hidden', { bubbles: true }));
|
686
712
|
}
|
687
713
|
getHeaders(json = false) {
|
@@ -703,18 +729,20 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
703
729
|
}
|
704
730
|
async skipCarts() {
|
705
731
|
this.hideModal('skip');
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
732
|
+
try {
|
733
|
+
const response = await fetch(this.getUrl('/cart/skip'), {
|
734
|
+
method: 'POST',
|
735
|
+
headers: this.getHeaders(),
|
736
|
+
});
|
711
737
|
if (!response.ok) {
|
712
738
|
throw new Error(`Could not mark cart as skipped - ${response.status}: ${await response.text()}`);
|
713
739
|
}
|
714
740
|
window.edgetag('tag', 'CartRecovery_CartDeclined', {}, {}, { destination: this.edgeURL });
|
715
741
|
this.lastExpiredCart = undefined;
|
716
|
-
}
|
717
|
-
|
742
|
+
}
|
743
|
+
catch (e) {
|
744
|
+
logger.error(e);
|
745
|
+
}
|
718
746
|
}
|
719
747
|
render() {
|
720
748
|
if (this.isPopUpDismissed) {
|
@@ -893,7 +921,7 @@ BlotoutWallet = __decorate([
|
|
893
921
|
], BlotoutWallet);
|
894
922
|
|
895
923
|
const init = (params) => {
|
896
|
-
var _a, _b, _c, _d, _e;
|
924
|
+
var _a, _b, _c, _d, _e, _f;
|
897
925
|
if (
|
898
926
|
// if loaded in non-browser SDKs
|
899
927
|
!window ||
|
@@ -928,6 +956,7 @@ const init = (params) => {
|
|
928
956
|
element.edgeURL = params.baseUrl;
|
929
957
|
element.userId = params.userId;
|
930
958
|
element.restoreRedirect = (_e = params.manifest.variables) === null || _e === void 0 ? void 0 : _e['restoreRedirect'];
|
959
|
+
element.silentRestore = ((_f = params.manifest.variables) === null || _f === void 0 ? void 0 : _f['silentRestore']) === '1';
|
931
960
|
document.body.append(element);
|
932
961
|
}
|
933
962
|
};
|
package/index.js
CHANGED
@@ -35,6 +35,8 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
35
35
|
...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
|
36
36
|
]);
|
37
37
|
|
38
|
+
const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
|
39
|
+
|
38
40
|
const customAttributes = {
|
39
41
|
'--bw-primary': { type: 'color', defaultValue: '#000000' },
|
40
42
|
'--bw-title-color': { type: 'color', defaultValue: '#000000' },
|
@@ -81,7 +83,8 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
81
83
|
return Object.fromEntries(cookie
|
82
84
|
.split(/;\s+/)
|
83
85
|
.map((r) => r.split('=').map((str) => str.trim()))
|
84
|
-
.map(([cookieKey,
|
86
|
+
.map(([cookieKey, ...cookieValues]) => {
|
87
|
+
const cookieValue = cookieValues.join('=');
|
85
88
|
if (!cookieKey) {
|
86
89
|
return [];
|
87
90
|
}
|
@@ -120,7 +123,7 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
120
123
|
if (options === null || options === void 0 ? void 0 : options.secure) {
|
121
124
|
extras.push('secure');
|
122
125
|
}
|
123
|
-
document.cookie = `${key}=${value};${extras.join(';')}`;
|
126
|
+
document.cookie = `${key}=${encodeURIComponent(value)};${extras.join(';')}`;
|
124
127
|
}
|
125
128
|
catch {
|
126
129
|
return;
|
@@ -363,31 +366,43 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
363
366
|
}
|
364
367
|
`;
|
365
368
|
|
369
|
+
const isGecko = () => /\bGecko\/\d+/.test(navigator.userAgent);
|
370
|
+
|
366
371
|
const fadeInDialog = (element) => {
|
367
|
-
const
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
372
|
+
const animations = [
|
373
|
+
element.animate([
|
374
|
+
{ transform: 'translateY(-20px)', opacity: 0 },
|
375
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
376
|
+
], { duration: 600, easing: spring, composite: 'add' }),
|
377
|
+
];
|
378
|
+
// Gecko does not support animating ::backdrop pseudo elements
|
379
|
+
if (!isGecko()) {
|
380
|
+
animations.push(element.animate([{ opacity: 0 }, { opacity: 1 }], {
|
381
|
+
duration: 300,
|
382
|
+
easing: 'ease-out',
|
383
|
+
pseudoElement: '::backdrop',
|
384
|
+
fill: 'forwards',
|
385
|
+
}));
|
386
|
+
}
|
387
|
+
return Promise.all(animations.map((anim) => anim.finished));
|
378
388
|
};
|
379
389
|
const fadeOutToBottom = (element) => {
|
380
|
-
const
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
390
|
+
const animations = [
|
391
|
+
element.animate([
|
392
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
393
|
+
{ transform: 'translateY(20px)', opacity: 0 },
|
394
|
+
], { duration: 600, easing: spring }),
|
395
|
+
];
|
396
|
+
// Gecko does not support animating ::backdrop pseudo elements
|
397
|
+
if (!isGecko()) {
|
398
|
+
animations.push(element.animate([{ opacity: 1 }, { opacity: 0 }], {
|
399
|
+
duration: 300,
|
400
|
+
easing: 'ease-out',
|
401
|
+
pseudoElement: '::backdrop',
|
402
|
+
fill: 'forwards',
|
403
|
+
}));
|
404
|
+
}
|
405
|
+
return Promise.all(animations.map((anim) => anim.finished));
|
391
406
|
};
|
392
407
|
const flipOut = (element) => {
|
393
408
|
const animation = element.animate([
|
@@ -450,7 +465,6 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
450
465
|
const parts = str.split(/<\s*br\s*\/?\s*>/);
|
451
466
|
return o(parts, x `<br />`);
|
452
467
|
};
|
453
|
-
const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
|
454
468
|
let BlotoutWallet = class BlotoutWallet extends s {
|
455
469
|
constructor() {
|
456
470
|
super(...arguments);
|
@@ -463,78 +477,76 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
463
477
|
.then(() => (this.state = newState))
|
464
478
|
.then(() => flipIn(this.dialog));
|
465
479
|
};
|
480
|
+
this.restoreCart = async () => {
|
481
|
+
if (!this.lastExpiredCart) {
|
482
|
+
return;
|
483
|
+
}
|
484
|
+
const email = this.email.value.trim().toLowerCase();
|
485
|
+
if (email) {
|
486
|
+
window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
|
487
|
+
const response = await fetch(this.getUrl('/user/email'), {
|
488
|
+
method: 'POST',
|
489
|
+
body: JSON.stringify({
|
490
|
+
email: email,
|
491
|
+
}),
|
492
|
+
headers: this.getHeaders(true),
|
493
|
+
});
|
494
|
+
if (!response.ok) {
|
495
|
+
throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
|
496
|
+
}
|
497
|
+
this.email.value = '';
|
498
|
+
this.hasEmail = true;
|
499
|
+
this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
|
500
|
+
window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
|
501
|
+
}
|
502
|
+
await this.storeApi.addItems(this.lastExpiredCart.items);
|
503
|
+
const expiredCartId = this.lastExpiredCart.cartId;
|
504
|
+
// this cookie will be cleared once the next event is processed
|
505
|
+
setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
|
506
|
+
// We attempt to mark the cart as restored, but if the request fails,
|
507
|
+
// we log the error in the console and let the user continue. Since the
|
508
|
+
// problem is probably in the `/cart/restore` endpoint, further attempts
|
509
|
+
// would not resolve the problem, which would just increase the number
|
510
|
+
// of failed calls and not solve the problem.
|
511
|
+
const response = await fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
|
512
|
+
method: 'POST',
|
513
|
+
headers: this.getHeaders(),
|
514
|
+
});
|
515
|
+
if (!response.ok) {
|
516
|
+
throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
|
517
|
+
}
|
518
|
+
this.lastExpiredCart = undefined;
|
519
|
+
this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
|
520
|
+
bubbles: true,
|
521
|
+
}));
|
522
|
+
// Send the request as beacon as there could be a immediate redirect in the next step
|
523
|
+
window.edgetag('tag', 'CartRecovery_CartRestored', { isSilent: !!this.silentRestore }, {}, { method: 'beacon' });
|
524
|
+
};
|
466
525
|
this.onSubmit = async (ev) => {
|
467
526
|
ev.preventDefault();
|
468
527
|
ev.stopPropagation();
|
469
|
-
const email = this.email.value.trim().toLowerCase();
|
470
528
|
try {
|
471
529
|
await this.transitionTo('loading');
|
472
|
-
|
473
|
-
window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
|
474
|
-
const response = await fetch(this.getUrl('/user/email'), {
|
475
|
-
method: 'POST',
|
476
|
-
body: JSON.stringify({
|
477
|
-
email: email,
|
478
|
-
}),
|
479
|
-
headers: this.getHeaders(true),
|
480
|
-
});
|
481
|
-
if (!response.ok) {
|
482
|
-
throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
|
483
|
-
}
|
484
|
-
this.email.value = '';
|
485
|
-
this.hasEmail = true;
|
486
|
-
this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
|
487
|
-
window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
|
488
|
-
}
|
489
|
-
if (this.lastExpiredCart) {
|
490
|
-
await this.storeApi.addItems(this.lastExpiredCart.items);
|
491
|
-
this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
|
492
|
-
bubbles: true,
|
493
|
-
}));
|
494
|
-
const expiredCartId = this.lastExpiredCart.cartId;
|
495
|
-
// this cookie will be cleared once the next event is processed
|
496
|
-
setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
|
497
|
-
// We attempt to mark the cart as restored, but if the request fails,
|
498
|
-
// we log the error in the console and let the user continue. Since the
|
499
|
-
// problem is probably in the `/cart/restore` endpoint, further attempts
|
500
|
-
// would not resolve the problem, which would just increase the number
|
501
|
-
// of failed calls and not solve the problem.
|
502
|
-
fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
|
503
|
-
method: 'POST',
|
504
|
-
headers: this.getHeaders(),
|
505
|
-
})
|
506
|
-
.then(async (response) => {
|
507
|
-
if (!response.ok) {
|
508
|
-
throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
|
509
|
-
}
|
510
|
-
// Send the request as beacon as there could be a immediate redirect in the next step
|
511
|
-
window.edgetag('tag', 'CartRecovery_CartRestored', {}, {}, { method: 'beacon' });
|
512
|
-
// Redirect to custom path
|
513
|
-
if (this.restoreRedirect) {
|
514
|
-
try {
|
515
|
-
const redirect = new URL(this.restoreRedirect, window.location.origin);
|
516
|
-
window.location.href = redirect.href;
|
517
|
-
}
|
518
|
-
catch (e) {
|
519
|
-
console.error('Invalid redirect URL', e);
|
520
|
-
}
|
521
|
-
}
|
522
|
-
})
|
523
|
-
.catch((err) => {
|
524
|
-
console.error(err);
|
525
|
-
});
|
526
|
-
this.lastExpiredCart = undefined;
|
527
|
-
}
|
530
|
+
await this.restoreCart();
|
528
531
|
await this.transitionTo('restored');
|
529
|
-
delay(2000)
|
530
|
-
|
531
|
-
|
532
|
+
await delay(2000);
|
533
|
+
if (this.state == 'restored') {
|
534
|
+
this.hideModal('restore');
|
535
|
+
}
|
536
|
+
// Redirect to custom path
|
537
|
+
if (this.restoreRedirect) {
|
538
|
+
try {
|
539
|
+
const redirect = new URL(this.restoreRedirect, window.location.origin);
|
540
|
+
window.location.href = redirect.href;
|
532
541
|
}
|
533
|
-
|
542
|
+
catch (e) {
|
543
|
+
console.error('Invalid redirect URL', e);
|
544
|
+
}
|
545
|
+
}
|
534
546
|
}
|
535
547
|
catch (e) {
|
536
|
-
await this.transitionTo('failed');
|
537
548
|
logger.error(e);
|
549
|
+
await this.transitionTo('failed');
|
538
550
|
}
|
539
551
|
};
|
540
552
|
this.onDialogClick = () => {
|
@@ -644,6 +656,7 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
644
656
|
}
|
645
657
|
}
|
646
658
|
async initialize() {
|
659
|
+
var _a;
|
647
660
|
if (!this.userId) {
|
648
661
|
logger.error('No UserId set');
|
649
662
|
return;
|
@@ -652,11 +665,11 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
652
665
|
return;
|
653
666
|
}
|
654
667
|
await delay(POPUP_IMPRESSION_DELAY);
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
668
|
+
try {
|
669
|
+
const response = await fetch(this.getUrl('/cart/expired'), {
|
670
|
+
method: 'GET',
|
671
|
+
headers: this.getHeaders(),
|
672
|
+
});
|
660
673
|
if (!response.ok) {
|
661
674
|
throw new Error(`Unable to get Expired Cart ${response.status}: ${await response.text()}`);
|
662
675
|
}
|
@@ -664,16 +677,27 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
664
677
|
const result = await response.json();
|
665
678
|
this.hasEmail = result.email;
|
666
679
|
this.lastExpiredCart = result.carts[0];
|
667
|
-
if (
|
668
|
-
this.
|
669
|
-
|
680
|
+
if ((_a = result.carts) === null || _a === void 0 ? void 0 : _a.length) {
|
681
|
+
if (this.silentRestore) {
|
682
|
+
this.restoreCart().catch(logger.error);
|
683
|
+
}
|
684
|
+
else if (!this.isPopUpDismissed) {
|
685
|
+
this.showModal();
|
686
|
+
}
|
687
|
+
if (result.hasJustExpired) {
|
688
|
+
window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
|
689
|
+
}
|
670
690
|
}
|
671
|
-
}
|
672
|
-
|
691
|
+
}
|
692
|
+
catch (err) {
|
693
|
+
logger.error(err);
|
694
|
+
}
|
673
695
|
}
|
674
696
|
showModal() {
|
675
697
|
this.dialog.showModal();
|
676
|
-
new Promise(requestAnimationFrame)
|
698
|
+
new Promise(requestAnimationFrame)
|
699
|
+
.catch(logger.error)
|
700
|
+
.finally(() => fadeInDialog(this.dialog));
|
677
701
|
this.dispatchEvent(new CustomEvent('blotout-wallet-shown', { bubbles: true }));
|
678
702
|
fetch(this.getUrl('/user/event'), {
|
679
703
|
method: 'POST',
|
@@ -682,7 +706,9 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
682
706
|
}).catch(logger.error);
|
683
707
|
}
|
684
708
|
hideModal(action) {
|
685
|
-
fadeOutToBottom(this.dialog)
|
709
|
+
fadeOutToBottom(this.dialog)
|
710
|
+
.catch(logger.error)
|
711
|
+
.finally(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
|
686
712
|
this.dispatchEvent(new CustomEvent('blotout-wallet-hidden', { bubbles: true }));
|
687
713
|
}
|
688
714
|
getHeaders(json = false) {
|
@@ -704,18 +730,20 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
704
730
|
}
|
705
731
|
async skipCarts() {
|
706
732
|
this.hideModal('skip');
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
733
|
+
try {
|
734
|
+
const response = await fetch(this.getUrl('/cart/skip'), {
|
735
|
+
method: 'POST',
|
736
|
+
headers: this.getHeaders(),
|
737
|
+
});
|
712
738
|
if (!response.ok) {
|
713
739
|
throw new Error(`Could not mark cart as skipped - ${response.status}: ${await response.text()}`);
|
714
740
|
}
|
715
741
|
window.edgetag('tag', 'CartRecovery_CartDeclined', {}, {}, { destination: this.edgeURL });
|
716
742
|
this.lastExpiredCart = undefined;
|
717
|
-
}
|
718
|
-
|
743
|
+
}
|
744
|
+
catch (e) {
|
745
|
+
logger.error(e);
|
746
|
+
}
|
719
747
|
}
|
720
748
|
render() {
|
721
749
|
if (this.isPopUpDismissed) {
|
@@ -894,7 +922,7 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
894
922
|
], BlotoutWallet);
|
895
923
|
|
896
924
|
const init = (params) => {
|
897
|
-
var _a, _b, _c, _d, _e;
|
925
|
+
var _a, _b, _c, _d, _e, _f;
|
898
926
|
if (
|
899
927
|
// if loaded in non-browser SDKs
|
900
928
|
!window ||
|
@@ -929,6 +957,7 @@ var ProvidersBlotoutWalletSdk = (function () {
|
|
929
957
|
element.edgeURL = params.baseUrl;
|
930
958
|
element.userId = params.userId;
|
931
959
|
element.restoreRedirect = (_e = params.manifest.variables) === null || _e === void 0 ? void 0 : _e['restoreRedirect'];
|
960
|
+
element.silentRestore = ((_f = params.manifest.variables) === null || _f === void 0 ? void 0 : _f['silentRestore']) === '1';
|
932
961
|
document.body.append(element);
|
933
962
|
}
|
934
963
|
};
|
package/index.mjs
CHANGED
@@ -32,6 +32,8 @@ new Set([
|
|
32
32
|
...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
|
33
33
|
]);
|
34
34
|
|
35
|
+
const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
|
36
|
+
|
35
37
|
const customAttributes = {
|
36
38
|
'--bw-primary': { type: 'color', defaultValue: '#000000' },
|
37
39
|
'--bw-title-color': { type: 'color', defaultValue: '#000000' },
|
@@ -78,7 +80,8 @@ const parseCookies = (cookie) => {
|
|
78
80
|
return Object.fromEntries(cookie
|
79
81
|
.split(/;\s+/)
|
80
82
|
.map((r) => r.split('=').map((str) => str.trim()))
|
81
|
-
.map(([cookieKey,
|
83
|
+
.map(([cookieKey, ...cookieValues]) => {
|
84
|
+
const cookieValue = cookieValues.join('=');
|
82
85
|
if (!cookieKey) {
|
83
86
|
return [];
|
84
87
|
}
|
@@ -117,7 +120,7 @@ const setCookie = (key, value, options) => {
|
|
117
120
|
if (options === null || options === void 0 ? void 0 : options.secure) {
|
118
121
|
extras.push('secure');
|
119
122
|
}
|
120
|
-
document.cookie = `${key}=${value};${extras.join(';')}`;
|
123
|
+
document.cookie = `${key}=${encodeURIComponent(value)};${extras.join(';')}`;
|
121
124
|
}
|
122
125
|
catch {
|
123
126
|
return;
|
@@ -360,31 +363,43 @@ const cssVars = i$4 `
|
|
360
363
|
}
|
361
364
|
`;
|
362
365
|
|
366
|
+
const isGecko = () => /\bGecko\/\d+/.test(navigator.userAgent);
|
367
|
+
|
363
368
|
const fadeInDialog = (element) => {
|
364
|
-
const
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
369
|
+
const animations = [
|
370
|
+
element.animate([
|
371
|
+
{ transform: 'translateY(-20px)', opacity: 0 },
|
372
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
373
|
+
], { duration: 600, easing: spring, composite: 'add' }),
|
374
|
+
];
|
375
|
+
// Gecko does not support animating ::backdrop pseudo elements
|
376
|
+
if (!isGecko()) {
|
377
|
+
animations.push(element.animate([{ opacity: 0 }, { opacity: 1 }], {
|
378
|
+
duration: 300,
|
379
|
+
easing: 'ease-out',
|
380
|
+
pseudoElement: '::backdrop',
|
381
|
+
fill: 'forwards',
|
382
|
+
}));
|
383
|
+
}
|
384
|
+
return Promise.all(animations.map((anim) => anim.finished));
|
375
385
|
};
|
376
386
|
const fadeOutToBottom = (element) => {
|
377
|
-
const
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
387
|
+
const animations = [
|
388
|
+
element.animate([
|
389
|
+
{ transform: 'translateY(0)', opacity: 1 },
|
390
|
+
{ transform: 'translateY(20px)', opacity: 0 },
|
391
|
+
], { duration: 600, easing: spring }),
|
392
|
+
];
|
393
|
+
// Gecko does not support animating ::backdrop pseudo elements
|
394
|
+
if (!isGecko()) {
|
395
|
+
animations.push(element.animate([{ opacity: 1 }, { opacity: 0 }], {
|
396
|
+
duration: 300,
|
397
|
+
easing: 'ease-out',
|
398
|
+
pseudoElement: '::backdrop',
|
399
|
+
fill: 'forwards',
|
400
|
+
}));
|
401
|
+
}
|
402
|
+
return Promise.all(animations.map((anim) => anim.finished));
|
388
403
|
};
|
389
404
|
const flipOut = (element) => {
|
390
405
|
const animation = element.animate([
|
@@ -447,7 +462,6 @@ const formatString = (str) => {
|
|
447
462
|
const parts = str.split(/<\s*br\s*\/?\s*>/);
|
448
463
|
return o(parts, x `<br />`);
|
449
464
|
};
|
450
|
-
const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
|
451
465
|
let BlotoutWallet = class BlotoutWallet extends s {
|
452
466
|
constructor() {
|
453
467
|
super(...arguments);
|
@@ -460,78 +474,76 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
460
474
|
.then(() => (this.state = newState))
|
461
475
|
.then(() => flipIn(this.dialog));
|
462
476
|
};
|
477
|
+
this.restoreCart = async () => {
|
478
|
+
if (!this.lastExpiredCart) {
|
479
|
+
return;
|
480
|
+
}
|
481
|
+
const email = this.email.value.trim().toLowerCase();
|
482
|
+
if (email) {
|
483
|
+
window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
|
484
|
+
const response = await fetch(this.getUrl('/user/email'), {
|
485
|
+
method: 'POST',
|
486
|
+
body: JSON.stringify({
|
487
|
+
email: email,
|
488
|
+
}),
|
489
|
+
headers: this.getHeaders(true),
|
490
|
+
});
|
491
|
+
if (!response.ok) {
|
492
|
+
throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
|
493
|
+
}
|
494
|
+
this.email.value = '';
|
495
|
+
this.hasEmail = true;
|
496
|
+
this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
|
497
|
+
window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
|
498
|
+
}
|
499
|
+
await this.storeApi.addItems(this.lastExpiredCart.items);
|
500
|
+
const expiredCartId = this.lastExpiredCart.cartId;
|
501
|
+
// this cookie will be cleared once the next event is processed
|
502
|
+
setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
|
503
|
+
// We attempt to mark the cart as restored, but if the request fails,
|
504
|
+
// we log the error in the console and let the user continue. Since the
|
505
|
+
// problem is probably in the `/cart/restore` endpoint, further attempts
|
506
|
+
// would not resolve the problem, which would just increase the number
|
507
|
+
// of failed calls and not solve the problem.
|
508
|
+
const response = await fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
|
509
|
+
method: 'POST',
|
510
|
+
headers: this.getHeaders(),
|
511
|
+
});
|
512
|
+
if (!response.ok) {
|
513
|
+
throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
|
514
|
+
}
|
515
|
+
this.lastExpiredCart = undefined;
|
516
|
+
this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
|
517
|
+
bubbles: true,
|
518
|
+
}));
|
519
|
+
// Send the request as beacon as there could be a immediate redirect in the next step
|
520
|
+
window.edgetag('tag', 'CartRecovery_CartRestored', { isSilent: !!this.silentRestore }, {}, { method: 'beacon' });
|
521
|
+
};
|
463
522
|
this.onSubmit = async (ev) => {
|
464
523
|
ev.preventDefault();
|
465
524
|
ev.stopPropagation();
|
466
|
-
const email = this.email.value.trim().toLowerCase();
|
467
525
|
try {
|
468
526
|
await this.transitionTo('loading');
|
469
|
-
|
470
|
-
window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
|
471
|
-
const response = await fetch(this.getUrl('/user/email'), {
|
472
|
-
method: 'POST',
|
473
|
-
body: JSON.stringify({
|
474
|
-
email: email,
|
475
|
-
}),
|
476
|
-
headers: this.getHeaders(true),
|
477
|
-
});
|
478
|
-
if (!response.ok) {
|
479
|
-
throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
|
480
|
-
}
|
481
|
-
this.email.value = '';
|
482
|
-
this.hasEmail = true;
|
483
|
-
this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
|
484
|
-
window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
|
485
|
-
}
|
486
|
-
if (this.lastExpiredCart) {
|
487
|
-
await this.storeApi.addItems(this.lastExpiredCart.items);
|
488
|
-
this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
|
489
|
-
bubbles: true,
|
490
|
-
}));
|
491
|
-
const expiredCartId = this.lastExpiredCart.cartId;
|
492
|
-
// this cookie will be cleared once the next event is processed
|
493
|
-
setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
|
494
|
-
// We attempt to mark the cart as restored, but if the request fails,
|
495
|
-
// we log the error in the console and let the user continue. Since the
|
496
|
-
// problem is probably in the `/cart/restore` endpoint, further attempts
|
497
|
-
// would not resolve the problem, which would just increase the number
|
498
|
-
// of failed calls and not solve the problem.
|
499
|
-
fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
|
500
|
-
method: 'POST',
|
501
|
-
headers: this.getHeaders(),
|
502
|
-
})
|
503
|
-
.then(async (response) => {
|
504
|
-
if (!response.ok) {
|
505
|
-
throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
|
506
|
-
}
|
507
|
-
// Send the request as beacon as there could be a immediate redirect in the next step
|
508
|
-
window.edgetag('tag', 'CartRecovery_CartRestored', {}, {}, { method: 'beacon' });
|
509
|
-
// Redirect to custom path
|
510
|
-
if (this.restoreRedirect) {
|
511
|
-
try {
|
512
|
-
const redirect = new URL(this.restoreRedirect, window.location.origin);
|
513
|
-
window.location.href = redirect.href;
|
514
|
-
}
|
515
|
-
catch (e) {
|
516
|
-
console.error('Invalid redirect URL', e);
|
517
|
-
}
|
518
|
-
}
|
519
|
-
})
|
520
|
-
.catch((err) => {
|
521
|
-
console.error(err);
|
522
|
-
});
|
523
|
-
this.lastExpiredCart = undefined;
|
524
|
-
}
|
527
|
+
await this.restoreCart();
|
525
528
|
await this.transitionTo('restored');
|
526
|
-
delay(2000)
|
527
|
-
|
528
|
-
|
529
|
+
await delay(2000);
|
530
|
+
if (this.state == 'restored') {
|
531
|
+
this.hideModal('restore');
|
532
|
+
}
|
533
|
+
// Redirect to custom path
|
534
|
+
if (this.restoreRedirect) {
|
535
|
+
try {
|
536
|
+
const redirect = new URL(this.restoreRedirect, window.location.origin);
|
537
|
+
window.location.href = redirect.href;
|
529
538
|
}
|
530
|
-
|
539
|
+
catch (e) {
|
540
|
+
console.error('Invalid redirect URL', e);
|
541
|
+
}
|
542
|
+
}
|
531
543
|
}
|
532
544
|
catch (e) {
|
533
|
-
await this.transitionTo('failed');
|
534
545
|
logger.error(e);
|
546
|
+
await this.transitionTo('failed');
|
535
547
|
}
|
536
548
|
};
|
537
549
|
this.onDialogClick = () => {
|
@@ -641,6 +653,7 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
641
653
|
}
|
642
654
|
}
|
643
655
|
async initialize() {
|
656
|
+
var _a;
|
644
657
|
if (!this.userId) {
|
645
658
|
logger.error('No UserId set');
|
646
659
|
return;
|
@@ -649,11 +662,11 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
649
662
|
return;
|
650
663
|
}
|
651
664
|
await delay(POPUP_IMPRESSION_DELAY);
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
665
|
+
try {
|
666
|
+
const response = await fetch(this.getUrl('/cart/expired'), {
|
667
|
+
method: 'GET',
|
668
|
+
headers: this.getHeaders(),
|
669
|
+
});
|
657
670
|
if (!response.ok) {
|
658
671
|
throw new Error(`Unable to get Expired Cart ${response.status}: ${await response.text()}`);
|
659
672
|
}
|
@@ -661,16 +674,27 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
661
674
|
const result = await response.json();
|
662
675
|
this.hasEmail = result.email;
|
663
676
|
this.lastExpiredCart = result.carts[0];
|
664
|
-
if (
|
665
|
-
this.
|
666
|
-
|
677
|
+
if ((_a = result.carts) === null || _a === void 0 ? void 0 : _a.length) {
|
678
|
+
if (this.silentRestore) {
|
679
|
+
this.restoreCart().catch(logger.error);
|
680
|
+
}
|
681
|
+
else if (!this.isPopUpDismissed) {
|
682
|
+
this.showModal();
|
683
|
+
}
|
684
|
+
if (result.hasJustExpired) {
|
685
|
+
window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
|
686
|
+
}
|
667
687
|
}
|
668
|
-
}
|
669
|
-
|
688
|
+
}
|
689
|
+
catch (err) {
|
690
|
+
logger.error(err);
|
691
|
+
}
|
670
692
|
}
|
671
693
|
showModal() {
|
672
694
|
this.dialog.showModal();
|
673
|
-
new Promise(requestAnimationFrame)
|
695
|
+
new Promise(requestAnimationFrame)
|
696
|
+
.catch(logger.error)
|
697
|
+
.finally(() => fadeInDialog(this.dialog));
|
674
698
|
this.dispatchEvent(new CustomEvent('blotout-wallet-shown', { bubbles: true }));
|
675
699
|
fetch(this.getUrl('/user/event'), {
|
676
700
|
method: 'POST',
|
@@ -679,7 +703,9 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
679
703
|
}).catch(logger.error);
|
680
704
|
}
|
681
705
|
hideModal(action) {
|
682
|
-
fadeOutToBottom(this.dialog)
|
706
|
+
fadeOutToBottom(this.dialog)
|
707
|
+
.catch(logger.error)
|
708
|
+
.finally(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
|
683
709
|
this.dispatchEvent(new CustomEvent('blotout-wallet-hidden', { bubbles: true }));
|
684
710
|
}
|
685
711
|
getHeaders(json = false) {
|
@@ -701,18 +727,20 @@ let BlotoutWallet = class BlotoutWallet extends s {
|
|
701
727
|
}
|
702
728
|
async skipCarts() {
|
703
729
|
this.hideModal('skip');
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
730
|
+
try {
|
731
|
+
const response = await fetch(this.getUrl('/cart/skip'), {
|
732
|
+
method: 'POST',
|
733
|
+
headers: this.getHeaders(),
|
734
|
+
});
|
709
735
|
if (!response.ok) {
|
710
736
|
throw new Error(`Could not mark cart as skipped - ${response.status}: ${await response.text()}`);
|
711
737
|
}
|
712
738
|
window.edgetag('tag', 'CartRecovery_CartDeclined', {}, {}, { destination: this.edgeURL });
|
713
739
|
this.lastExpiredCart = undefined;
|
714
|
-
}
|
715
|
-
|
740
|
+
}
|
741
|
+
catch (e) {
|
742
|
+
logger.error(e);
|
743
|
+
}
|
716
744
|
}
|
717
745
|
render() {
|
718
746
|
if (this.isPopUpDismissed) {
|
@@ -891,7 +919,7 @@ BlotoutWallet = __decorate([
|
|
891
919
|
], BlotoutWallet);
|
892
920
|
|
893
921
|
const init = (params) => {
|
894
|
-
var _a, _b, _c, _d, _e;
|
922
|
+
var _a, _b, _c, _d, _e, _f;
|
895
923
|
if (
|
896
924
|
// if loaded in non-browser SDKs
|
897
925
|
!window ||
|
@@ -926,6 +954,7 @@ const init = (params) => {
|
|
926
954
|
element.edgeURL = params.baseUrl;
|
927
955
|
element.userId = params.userId;
|
928
956
|
element.restoreRedirect = (_e = params.manifest.variables) === null || _e === void 0 ? void 0 : _e['restoreRedirect'];
|
957
|
+
element.silentRestore = ((_f = params.manifest.variables) === null || _f === void 0 ? void 0 : _f['silentRestore']) === '1';
|
929
958
|
document.body.append(element);
|
930
959
|
}
|
931
960
|
};
|
package/package.json
CHANGED
@@ -58,7 +58,8 @@ const parseCookies = (cookie) => {
|
|
58
58
|
return Object.fromEntries(cookie
|
59
59
|
.split(/;\s+/)
|
60
60
|
.map((r) => r.split('=').map((str) => str.trim()))
|
61
|
-
.map(([cookieKey,
|
61
|
+
.map(([cookieKey, ...cookieValues]) => {
|
62
|
+
const cookieValue = cookieValues.join('=');
|
62
63
|
if (!cookieKey) {
|
63
64
|
return [];
|
64
65
|
}
|
package/stores/shopify/index.js
CHANGED
@@ -59,7 +59,8 @@
|
|
59
59
|
return Object.fromEntries(cookie
|
60
60
|
.split(/;\s+/)
|
61
61
|
.map((r) => r.split('=').map((str) => str.trim()))
|
62
|
-
.map(([cookieKey,
|
62
|
+
.map(([cookieKey, ...cookieValues]) => {
|
63
|
+
const cookieValue = cookieValues.join('=');
|
63
64
|
if (!cookieKey) {
|
64
65
|
return [];
|
65
66
|
}
|
package/stores/shopify/index.mjs
CHANGED
@@ -56,7 +56,8 @@ const parseCookies = (cookie) => {
|
|
56
56
|
return Object.fromEntries(cookie
|
57
57
|
.split(/;\s+/)
|
58
58
|
.map((r) => r.split('=').map((str) => str.trim()))
|
59
|
-
.map(([cookieKey,
|
59
|
+
.map(([cookieKey, ...cookieValues]) => {
|
60
|
+
const cookieValue = cookieValues.join('=');
|
60
61
|
if (!cookieKey) {
|
61
62
|
return [];
|
62
63
|
}
|