@blotoutio/providers-blotout-wallet-sdk 0.60.1 → 0.62.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/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' },
@@ -64,28 +66,39 @@ const cartTokenTwoCookie = 'cart2';
64
66
  const cartTokenLinkCookie = 'bwCartLinkToken';
65
67
 
66
68
  const getCookieValue = (key) => {
69
+ var _a;
67
70
  try {
68
71
  if (!document || !document.cookie) {
69
72
  return '';
70
73
  }
71
- const name = `${key}=`;
72
- const decodedCookie = decodeURIComponent(document.cookie);
73
- const ca = decodedCookie.split(';');
74
- for (let i = 0; i < ca.length; i++) {
75
- let c = ca[i];
76
- while (c.charAt(0) === ' ') {
77
- c = c.substring(1);
78
- }
79
- if (c.indexOf(name) === 0) {
80
- return c.substring(name.length, c.length);
81
- }
82
- }
83
- return '';
74
+ const cookies = parseCookies(document.cookie);
75
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
84
76
  }
85
77
  catch {
86
78
  return '';
87
79
  }
88
80
  };
81
+ const parseCookies = (cookie) => {
82
+ return Object.fromEntries(cookie
83
+ .split(/;\s+/)
84
+ .map((r) => r.split('=').map((str) => str.trim()))
85
+ .map(([cookieKey, cookieValue]) => {
86
+ if (!cookieKey) {
87
+ return [];
88
+ }
89
+ let decodedValue = '';
90
+ if (cookieValue) {
91
+ try {
92
+ decodedValue = decodeURIComponent(cookieValue);
93
+ }
94
+ catch (e) {
95
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
96
+ decodedValue = cookieValue;
97
+ }
98
+ }
99
+ return [cookieKey, decodedValue];
100
+ }));
101
+ };
89
102
  const setCookie = (key, value, options) => {
90
103
  var _a;
91
104
  try {
@@ -351,31 +364,43 @@ const cssVars = i$4 `
351
364
  }
352
365
  `;
353
366
 
367
+ const isGecko = () => /\bGecko\/\d+/.test(navigator.userAgent);
368
+
354
369
  const fadeInDialog = (element) => {
355
- const dialogAnimation = element.animate([
356
- { transform: 'translateY(-20px)', opacity: 0 },
357
- { transform: 'translateY(0)', opacity: 1 },
358
- ], { duration: 600, easing: spring, composite: 'add' });
359
- const backdropAnimation = element.animate([{ opacity: 0 }, { opacity: 1 }], {
360
- duration: 300,
361
- easing: 'ease-out',
362
- pseudoElement: '::backdrop',
363
- fill: 'forwards',
364
- });
365
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
370
+ const animations = [
371
+ element.animate([
372
+ { transform: 'translateY(-20px)', opacity: 0 },
373
+ { transform: 'translateY(0)', opacity: 1 },
374
+ ], { duration: 600, easing: spring, composite: 'add' }),
375
+ ];
376
+ // Gecko does not support animating ::backdrop pseudo elements
377
+ if (!isGecko()) {
378
+ animations.push(element.animate([{ opacity: 0 }, { opacity: 1 }], {
379
+ duration: 300,
380
+ easing: 'ease-out',
381
+ pseudoElement: '::backdrop',
382
+ fill: 'forwards',
383
+ }));
384
+ }
385
+ return Promise.all(animations.map((anim) => anim.finished));
366
386
  };
367
387
  const fadeOutToBottom = (element) => {
368
- const dialogAnimation = element.animate([
369
- { transform: 'translateY(0)', opacity: 1 },
370
- { transform: 'translateY(20px)', opacity: 0 },
371
- ], { duration: 600, easing: spring });
372
- const backdropAnimation = element.animate([{ opacity: 1 }, { opacity: 0 }], {
373
- duration: 300,
374
- easing: 'ease-out',
375
- pseudoElement: '::backdrop',
376
- fill: 'forwards',
377
- });
378
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
388
+ const animations = [
389
+ element.animate([
390
+ { transform: 'translateY(0)', opacity: 1 },
391
+ { transform: 'translateY(20px)', opacity: 0 },
392
+ ], { duration: 600, easing: spring }),
393
+ ];
394
+ // Gecko does not support animating ::backdrop pseudo elements
395
+ if (!isGecko()) {
396
+ animations.push(element.animate([{ opacity: 1 }, { opacity: 0 }], {
397
+ duration: 300,
398
+ easing: 'ease-out',
399
+ pseudoElement: '::backdrop',
400
+ fill: 'forwards',
401
+ }));
402
+ }
403
+ return Promise.all(animations.map((anim) => anim.finished));
379
404
  };
380
405
  const flipOut = (element) => {
381
406
  const animation = element.animate([
@@ -438,7 +463,6 @@ const formatString = (str) => {
438
463
  const parts = str.split(/<\s*br\s*\/?\s*>/);
439
464
  return o(parts, x `<br />`);
440
465
  };
441
- const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
442
466
  let BlotoutWallet = class BlotoutWallet extends s {
443
467
  constructor() {
444
468
  super(...arguments);
@@ -451,78 +475,76 @@ let BlotoutWallet = class BlotoutWallet extends s {
451
475
  .then(() => (this.state = newState))
452
476
  .then(() => flipIn(this.dialog));
453
477
  };
478
+ this.restoreCart = async () => {
479
+ if (!this.lastExpiredCart) {
480
+ return;
481
+ }
482
+ const email = this.email.value.trim().toLowerCase();
483
+ if (email) {
484
+ window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
485
+ const response = await fetch(this.getUrl('/user/email'), {
486
+ method: 'POST',
487
+ body: JSON.stringify({
488
+ email: email,
489
+ }),
490
+ headers: this.getHeaders(true),
491
+ });
492
+ if (!response.ok) {
493
+ throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
494
+ }
495
+ this.email.value = '';
496
+ this.hasEmail = true;
497
+ this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
498
+ window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
499
+ }
500
+ await this.storeApi.addItems(this.lastExpiredCart.items);
501
+ const expiredCartId = this.lastExpiredCart.cartId;
502
+ // this cookie will be cleared once the next event is processed
503
+ setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
504
+ // We attempt to mark the cart as restored, but if the request fails,
505
+ // we log the error in the console and let the user continue. Since the
506
+ // problem is probably in the `/cart/restore` endpoint, further attempts
507
+ // would not resolve the problem, which would just increase the number
508
+ // of failed calls and not solve the problem.
509
+ const response = await fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
510
+ method: 'POST',
511
+ headers: this.getHeaders(),
512
+ });
513
+ if (!response.ok) {
514
+ throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
515
+ }
516
+ this.lastExpiredCart = undefined;
517
+ this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
518
+ bubbles: true,
519
+ }));
520
+ // Send the request as beacon as there could be a immediate redirect in the next step
521
+ window.edgetag('tag', 'CartRecovery_CartRestored', { isSilent: !!this.silentRestore }, {}, { method: 'beacon' });
522
+ };
454
523
  this.onSubmit = async (ev) => {
455
524
  ev.preventDefault();
456
525
  ev.stopPropagation();
457
- const email = this.email.value.trim().toLowerCase();
458
526
  try {
459
527
  await this.transitionTo('loading');
460
- if (email) {
461
- window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
462
- const response = await fetch(this.getUrl('/user/email'), {
463
- method: 'POST',
464
- body: JSON.stringify({
465
- email: email,
466
- }),
467
- headers: this.getHeaders(true),
468
- });
469
- if (!response.ok) {
470
- throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
471
- }
472
- this.email.value = '';
473
- this.hasEmail = true;
474
- this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
475
- window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
476
- }
477
- if (this.lastExpiredCart) {
478
- await this.storeApi.addItems(this.lastExpiredCart.items);
479
- this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
480
- bubbles: true,
481
- }));
482
- const expiredCartId = this.lastExpiredCart.cartId;
483
- // this cookie will be cleared once the next event is processed
484
- setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
485
- // We attempt to mark the cart as restored, but if the request fails,
486
- // we log the error in the console and let the user continue. Since the
487
- // problem is probably in the `/cart/restore` endpoint, further attempts
488
- // would not resolve the problem, which would just increase the number
489
- // of failed calls and not solve the problem.
490
- fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
491
- method: 'POST',
492
- headers: this.getHeaders(),
493
- })
494
- .then(async (response) => {
495
- if (!response.ok) {
496
- throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
497
- }
498
- // Send the request as beacon as there could be a immediate redirect in the next step
499
- window.edgetag('tag', 'CartRecovery_CartRestored', {}, {}, { method: 'beacon' });
500
- // Redirect to custom path
501
- if (this.restoreRedirect) {
502
- try {
503
- const redirect = new URL(this.restoreRedirect, window.location.origin);
504
- window.location.href = redirect.href;
505
- }
506
- catch (e) {
507
- console.error('Invalid redirect URL', e);
508
- }
509
- }
510
- })
511
- .catch((err) => {
512
- console.error(err);
513
- });
514
- this.lastExpiredCart = undefined;
515
- }
528
+ await this.restoreCart();
516
529
  await this.transitionTo('restored');
517
- delay(2000).then(() => {
518
- if (this.state == 'restored') {
519
- this.hideModal('restore');
530
+ await delay(2000);
531
+ if (this.state == 'restored') {
532
+ this.hideModal('restore');
533
+ }
534
+ // Redirect to custom path
535
+ if (this.restoreRedirect) {
536
+ try {
537
+ const redirect = new URL(this.restoreRedirect, window.location.origin);
538
+ window.location.href = redirect.href;
520
539
  }
521
- });
540
+ catch (e) {
541
+ console.error('Invalid redirect URL', e);
542
+ }
543
+ }
522
544
  }
523
545
  catch (e) {
524
- await this.transitionTo('failed');
525
546
  logger.error(e);
547
+ await this.transitionTo('failed');
526
548
  }
527
549
  };
528
550
  this.onDialogClick = () => {
@@ -632,6 +654,7 @@ let BlotoutWallet = class BlotoutWallet extends s {
632
654
  }
633
655
  }
634
656
  async initialize() {
657
+ var _a;
635
658
  if (!this.userId) {
636
659
  logger.error('No UserId set');
637
660
  return;
@@ -640,11 +663,11 @@ let BlotoutWallet = class BlotoutWallet extends s {
640
663
  return;
641
664
  }
642
665
  await delay(POPUP_IMPRESSION_DELAY);
643
- fetch(this.getUrl('/cart/expired'), {
644
- method: 'GET',
645
- headers: this.getHeaders(),
646
- })
647
- .then(async (response) => {
666
+ try {
667
+ const response = await fetch(this.getUrl('/cart/expired'), {
668
+ method: 'GET',
669
+ headers: this.getHeaders(),
670
+ });
648
671
  if (!response.ok) {
649
672
  throw new Error(`Unable to get Expired Cart ${response.status}: ${await response.text()}`);
650
673
  }
@@ -652,16 +675,27 @@ let BlotoutWallet = class BlotoutWallet extends s {
652
675
  const result = await response.json();
653
676
  this.hasEmail = result.email;
654
677
  this.lastExpiredCart = result.carts[0];
655
- if (result.carts && result.carts.length && !this.isPopUpDismissed) {
656
- this.showModal();
657
- window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
678
+ if ((_a = result.carts) === null || _a === void 0 ? void 0 : _a.length) {
679
+ if (this.silentRestore) {
680
+ this.restoreCart().catch(logger.error);
681
+ }
682
+ else if (!this.isPopUpDismissed) {
683
+ this.showModal();
684
+ }
685
+ if (result.hasJustExpired) {
686
+ window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
687
+ }
658
688
  }
659
- })
660
- .catch(logger.error);
689
+ }
690
+ catch (err) {
691
+ logger.error(err);
692
+ }
661
693
  }
662
694
  showModal() {
663
695
  this.dialog.showModal();
664
- new Promise(requestAnimationFrame).then(() => fadeInDialog(this.dialog));
696
+ new Promise(requestAnimationFrame)
697
+ .catch(logger.error)
698
+ .finally(() => fadeInDialog(this.dialog));
665
699
  this.dispatchEvent(new CustomEvent('blotout-wallet-shown', { bubbles: true }));
666
700
  fetch(this.getUrl('/user/event'), {
667
701
  method: 'POST',
@@ -670,7 +704,9 @@ let BlotoutWallet = class BlotoutWallet extends s {
670
704
  }).catch(logger.error);
671
705
  }
672
706
  hideModal(action) {
673
- fadeOutToBottom(this.dialog).then(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
707
+ fadeOutToBottom(this.dialog)
708
+ .catch(logger.error)
709
+ .finally(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
674
710
  this.dispatchEvent(new CustomEvent('blotout-wallet-hidden', { bubbles: true }));
675
711
  }
676
712
  getHeaders(json = false) {
@@ -692,18 +728,20 @@ let BlotoutWallet = class BlotoutWallet extends s {
692
728
  }
693
729
  async skipCarts() {
694
730
  this.hideModal('skip');
695
- await fetch(this.getUrl('/cart/skip'), {
696
- method: 'POST',
697
- headers: this.getHeaders(),
698
- })
699
- .then(async (response) => {
731
+ try {
732
+ const response = await fetch(this.getUrl('/cart/skip'), {
733
+ method: 'POST',
734
+ headers: this.getHeaders(),
735
+ });
700
736
  if (!response.ok) {
701
737
  throw new Error(`Could not mark cart as skipped - ${response.status}: ${await response.text()}`);
702
738
  }
703
739
  window.edgetag('tag', 'CartRecovery_CartDeclined', {}, {}, { destination: this.edgeURL });
704
740
  this.lastExpiredCart = undefined;
705
- })
706
- .catch(logger.error);
741
+ }
742
+ catch (e) {
743
+ logger.error(e);
744
+ }
707
745
  }
708
746
  render() {
709
747
  if (this.isPopUpDismissed) {
@@ -882,7 +920,7 @@ BlotoutWallet = __decorate([
882
920
  ], BlotoutWallet);
883
921
 
884
922
  const init = (params) => {
885
- var _a, _b, _c, _d, _e;
923
+ var _a, _b, _c, _d, _e, _f;
886
924
  if (
887
925
  // if loaded in non-browser SDKs
888
926
  !window ||
@@ -917,6 +955,7 @@ const init = (params) => {
917
955
  element.edgeURL = params.baseUrl;
918
956
  element.userId = params.userId;
919
957
  element.restoreRedirect = (_e = params.manifest.variables) === null || _e === void 0 ? void 0 : _e['restoreRedirect'];
958
+ element.silentRestore = ((_f = params.manifest.variables) === null || _f === void 0 ? void 0 : _f['silentRestore']) === '1';
920
959
  document.body.append(element);
921
960
  }
922
961
  };
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' },
@@ -65,28 +67,39 @@ var ProvidersBlotoutWalletSdk = (function () {
65
67
  const cartTokenLinkCookie = 'bwCartLinkToken';
66
68
 
67
69
  const getCookieValue = (key) => {
70
+ var _a;
68
71
  try {
69
72
  if (!document || !document.cookie) {
70
73
  return '';
71
74
  }
72
- const name = `${key}=`;
73
- const decodedCookie = decodeURIComponent(document.cookie);
74
- const ca = decodedCookie.split(';');
75
- for (let i = 0; i < ca.length; i++) {
76
- let c = ca[i];
77
- while (c.charAt(0) === ' ') {
78
- c = c.substring(1);
79
- }
80
- if (c.indexOf(name) === 0) {
81
- return c.substring(name.length, c.length);
82
- }
83
- }
84
- return '';
75
+ const cookies = parseCookies(document.cookie);
76
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
85
77
  }
86
78
  catch {
87
79
  return '';
88
80
  }
89
81
  };
82
+ const parseCookies = (cookie) => {
83
+ return Object.fromEntries(cookie
84
+ .split(/;\s+/)
85
+ .map((r) => r.split('=').map((str) => str.trim()))
86
+ .map(([cookieKey, cookieValue]) => {
87
+ if (!cookieKey) {
88
+ return [];
89
+ }
90
+ let decodedValue = '';
91
+ if (cookieValue) {
92
+ try {
93
+ decodedValue = decodeURIComponent(cookieValue);
94
+ }
95
+ catch (e) {
96
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
97
+ decodedValue = cookieValue;
98
+ }
99
+ }
100
+ return [cookieKey, decodedValue];
101
+ }));
102
+ };
90
103
  const setCookie = (key, value, options) => {
91
104
  var _a;
92
105
  try {
@@ -352,31 +365,43 @@ var ProvidersBlotoutWalletSdk = (function () {
352
365
  }
353
366
  `;
354
367
 
368
+ const isGecko = () => /\bGecko\/\d+/.test(navigator.userAgent);
369
+
355
370
  const fadeInDialog = (element) => {
356
- const dialogAnimation = element.animate([
357
- { transform: 'translateY(-20px)', opacity: 0 },
358
- { transform: 'translateY(0)', opacity: 1 },
359
- ], { duration: 600, easing: spring, composite: 'add' });
360
- const backdropAnimation = element.animate([{ opacity: 0 }, { opacity: 1 }], {
361
- duration: 300,
362
- easing: 'ease-out',
363
- pseudoElement: '::backdrop',
364
- fill: 'forwards',
365
- });
366
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
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));
367
387
  };
368
388
  const fadeOutToBottom = (element) => {
369
- const dialogAnimation = element.animate([
370
- { transform: 'translateY(0)', opacity: 1 },
371
- { transform: 'translateY(20px)', opacity: 0 },
372
- ], { duration: 600, easing: spring });
373
- const backdropAnimation = element.animate([{ opacity: 1 }, { opacity: 0 }], {
374
- duration: 300,
375
- easing: 'ease-out',
376
- pseudoElement: '::backdrop',
377
- fill: 'forwards',
378
- });
379
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
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));
380
405
  };
381
406
  const flipOut = (element) => {
382
407
  const animation = element.animate([
@@ -439,7 +464,6 @@ var ProvidersBlotoutWalletSdk = (function () {
439
464
  const parts = str.split(/<\s*br\s*\/?\s*>/);
440
465
  return o(parts, x `<br />`);
441
466
  };
442
- const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
443
467
  let BlotoutWallet = class BlotoutWallet extends s {
444
468
  constructor() {
445
469
  super(...arguments);
@@ -452,78 +476,76 @@ var ProvidersBlotoutWalletSdk = (function () {
452
476
  .then(() => (this.state = newState))
453
477
  .then(() => flipIn(this.dialog));
454
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
+ };
455
524
  this.onSubmit = async (ev) => {
456
525
  ev.preventDefault();
457
526
  ev.stopPropagation();
458
- const email = this.email.value.trim().toLowerCase();
459
527
  try {
460
528
  await this.transitionTo('loading');
461
- if (email) {
462
- window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
463
- const response = await fetch(this.getUrl('/user/email'), {
464
- method: 'POST',
465
- body: JSON.stringify({
466
- email: email,
467
- }),
468
- headers: this.getHeaders(true),
469
- });
470
- if (!response.ok) {
471
- throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
472
- }
473
- this.email.value = '';
474
- this.hasEmail = true;
475
- this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
476
- window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
477
- }
478
- if (this.lastExpiredCart) {
479
- await this.storeApi.addItems(this.lastExpiredCart.items);
480
- this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
481
- bubbles: true,
482
- }));
483
- const expiredCartId = this.lastExpiredCart.cartId;
484
- // this cookie will be cleared once the next event is processed
485
- setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
486
- // We attempt to mark the cart as restored, but if the request fails,
487
- // we log the error in the console and let the user continue. Since the
488
- // problem is probably in the `/cart/restore` endpoint, further attempts
489
- // would not resolve the problem, which would just increase the number
490
- // of failed calls and not solve the problem.
491
- fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
492
- method: 'POST',
493
- headers: this.getHeaders(),
494
- })
495
- .then(async (response) => {
496
- if (!response.ok) {
497
- throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
498
- }
499
- // Send the request as beacon as there could be a immediate redirect in the next step
500
- window.edgetag('tag', 'CartRecovery_CartRestored', {}, {}, { method: 'beacon' });
501
- // Redirect to custom path
502
- if (this.restoreRedirect) {
503
- try {
504
- const redirect = new URL(this.restoreRedirect, window.location.origin);
505
- window.location.href = redirect.href;
506
- }
507
- catch (e) {
508
- console.error('Invalid redirect URL', e);
509
- }
510
- }
511
- })
512
- .catch((err) => {
513
- console.error(err);
514
- });
515
- this.lastExpiredCart = undefined;
516
- }
529
+ await this.restoreCart();
517
530
  await this.transitionTo('restored');
518
- delay(2000).then(() => {
519
- if (this.state == 'restored') {
520
- this.hideModal('restore');
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;
521
540
  }
522
- });
541
+ catch (e) {
542
+ console.error('Invalid redirect URL', e);
543
+ }
544
+ }
523
545
  }
524
546
  catch (e) {
525
- await this.transitionTo('failed');
526
547
  logger.error(e);
548
+ await this.transitionTo('failed');
527
549
  }
528
550
  };
529
551
  this.onDialogClick = () => {
@@ -633,6 +655,7 @@ var ProvidersBlotoutWalletSdk = (function () {
633
655
  }
634
656
  }
635
657
  async initialize() {
658
+ var _a;
636
659
  if (!this.userId) {
637
660
  logger.error('No UserId set');
638
661
  return;
@@ -641,11 +664,11 @@ var ProvidersBlotoutWalletSdk = (function () {
641
664
  return;
642
665
  }
643
666
  await delay(POPUP_IMPRESSION_DELAY);
644
- fetch(this.getUrl('/cart/expired'), {
645
- method: 'GET',
646
- headers: this.getHeaders(),
647
- })
648
- .then(async (response) => {
667
+ try {
668
+ const response = await fetch(this.getUrl('/cart/expired'), {
669
+ method: 'GET',
670
+ headers: this.getHeaders(),
671
+ });
649
672
  if (!response.ok) {
650
673
  throw new Error(`Unable to get Expired Cart ${response.status}: ${await response.text()}`);
651
674
  }
@@ -653,16 +676,27 @@ var ProvidersBlotoutWalletSdk = (function () {
653
676
  const result = await response.json();
654
677
  this.hasEmail = result.email;
655
678
  this.lastExpiredCart = result.carts[0];
656
- if (result.carts && result.carts.length && !this.isPopUpDismissed) {
657
- this.showModal();
658
- window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
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
+ }
659
689
  }
660
- })
661
- .catch(logger.error);
690
+ }
691
+ catch (err) {
692
+ logger.error(err);
693
+ }
662
694
  }
663
695
  showModal() {
664
696
  this.dialog.showModal();
665
- new Promise(requestAnimationFrame).then(() => fadeInDialog(this.dialog));
697
+ new Promise(requestAnimationFrame)
698
+ .catch(logger.error)
699
+ .finally(() => fadeInDialog(this.dialog));
666
700
  this.dispatchEvent(new CustomEvent('blotout-wallet-shown', { bubbles: true }));
667
701
  fetch(this.getUrl('/user/event'), {
668
702
  method: 'POST',
@@ -671,7 +705,9 @@ var ProvidersBlotoutWalletSdk = (function () {
671
705
  }).catch(logger.error);
672
706
  }
673
707
  hideModal(action) {
674
- fadeOutToBottom(this.dialog).then(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
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); });
675
711
  this.dispatchEvent(new CustomEvent('blotout-wallet-hidden', { bubbles: true }));
676
712
  }
677
713
  getHeaders(json = false) {
@@ -693,18 +729,20 @@ var ProvidersBlotoutWalletSdk = (function () {
693
729
  }
694
730
  async skipCarts() {
695
731
  this.hideModal('skip');
696
- await fetch(this.getUrl('/cart/skip'), {
697
- method: 'POST',
698
- headers: this.getHeaders(),
699
- })
700
- .then(async (response) => {
732
+ try {
733
+ const response = await fetch(this.getUrl('/cart/skip'), {
734
+ method: 'POST',
735
+ headers: this.getHeaders(),
736
+ });
701
737
  if (!response.ok) {
702
738
  throw new Error(`Could not mark cart as skipped - ${response.status}: ${await response.text()}`);
703
739
  }
704
740
  window.edgetag('tag', 'CartRecovery_CartDeclined', {}, {}, { destination: this.edgeURL });
705
741
  this.lastExpiredCart = undefined;
706
- })
707
- .catch(logger.error);
742
+ }
743
+ catch (e) {
744
+ logger.error(e);
745
+ }
708
746
  }
709
747
  render() {
710
748
  if (this.isPopUpDismissed) {
@@ -883,7 +921,7 @@ var ProvidersBlotoutWalletSdk = (function () {
883
921
  ], BlotoutWallet);
884
922
 
885
923
  const init = (params) => {
886
- var _a, _b, _c, _d, _e;
924
+ var _a, _b, _c, _d, _e, _f;
887
925
  if (
888
926
  // if loaded in non-browser SDKs
889
927
  !window ||
@@ -918,6 +956,7 @@ var ProvidersBlotoutWalletSdk = (function () {
918
956
  element.edgeURL = params.baseUrl;
919
957
  element.userId = params.userId;
920
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';
921
960
  document.body.append(element);
922
961
  }
923
962
  };
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' },
@@ -62,28 +64,39 @@ const cartTokenTwoCookie = 'cart2';
62
64
  const cartTokenLinkCookie = 'bwCartLinkToken';
63
65
 
64
66
  const getCookieValue = (key) => {
67
+ var _a;
65
68
  try {
66
69
  if (!document || !document.cookie) {
67
70
  return '';
68
71
  }
69
- const name = `${key}=`;
70
- const decodedCookie = decodeURIComponent(document.cookie);
71
- const ca = decodedCookie.split(';');
72
- for (let i = 0; i < ca.length; i++) {
73
- let c = ca[i];
74
- while (c.charAt(0) === ' ') {
75
- c = c.substring(1);
76
- }
77
- if (c.indexOf(name) === 0) {
78
- return c.substring(name.length, c.length);
79
- }
80
- }
81
- return '';
72
+ const cookies = parseCookies(document.cookie);
73
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
82
74
  }
83
75
  catch {
84
76
  return '';
85
77
  }
86
78
  };
79
+ const parseCookies = (cookie) => {
80
+ return Object.fromEntries(cookie
81
+ .split(/;\s+/)
82
+ .map((r) => r.split('=').map((str) => str.trim()))
83
+ .map(([cookieKey, cookieValue]) => {
84
+ if (!cookieKey) {
85
+ return [];
86
+ }
87
+ let decodedValue = '';
88
+ if (cookieValue) {
89
+ try {
90
+ decodedValue = decodeURIComponent(cookieValue);
91
+ }
92
+ catch (e) {
93
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
94
+ decodedValue = cookieValue;
95
+ }
96
+ }
97
+ return [cookieKey, decodedValue];
98
+ }));
99
+ };
87
100
  const setCookie = (key, value, options) => {
88
101
  var _a;
89
102
  try {
@@ -349,31 +362,43 @@ const cssVars = i$4 `
349
362
  }
350
363
  `;
351
364
 
365
+ const isGecko = () => /\bGecko\/\d+/.test(navigator.userAgent);
366
+
352
367
  const fadeInDialog = (element) => {
353
- const dialogAnimation = element.animate([
354
- { transform: 'translateY(-20px)', opacity: 0 },
355
- { transform: 'translateY(0)', opacity: 1 },
356
- ], { duration: 600, easing: spring, composite: 'add' });
357
- const backdropAnimation = element.animate([{ opacity: 0 }, { opacity: 1 }], {
358
- duration: 300,
359
- easing: 'ease-out',
360
- pseudoElement: '::backdrop',
361
- fill: 'forwards',
362
- });
363
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
368
+ const animations = [
369
+ element.animate([
370
+ { transform: 'translateY(-20px)', opacity: 0 },
371
+ { transform: 'translateY(0)', opacity: 1 },
372
+ ], { duration: 600, easing: spring, composite: 'add' }),
373
+ ];
374
+ // Gecko does not support animating ::backdrop pseudo elements
375
+ if (!isGecko()) {
376
+ animations.push(element.animate([{ opacity: 0 }, { opacity: 1 }], {
377
+ duration: 300,
378
+ easing: 'ease-out',
379
+ pseudoElement: '::backdrop',
380
+ fill: 'forwards',
381
+ }));
382
+ }
383
+ return Promise.all(animations.map((anim) => anim.finished));
364
384
  };
365
385
  const fadeOutToBottom = (element) => {
366
- const dialogAnimation = element.animate([
367
- { transform: 'translateY(0)', opacity: 1 },
368
- { transform: 'translateY(20px)', opacity: 0 },
369
- ], { duration: 600, easing: spring });
370
- const backdropAnimation = element.animate([{ opacity: 1 }, { opacity: 0 }], {
371
- duration: 300,
372
- easing: 'ease-out',
373
- pseudoElement: '::backdrop',
374
- fill: 'forwards',
375
- });
376
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
386
+ const animations = [
387
+ element.animate([
388
+ { transform: 'translateY(0)', opacity: 1 },
389
+ { transform: 'translateY(20px)', opacity: 0 },
390
+ ], { duration: 600, easing: spring }),
391
+ ];
392
+ // Gecko does not support animating ::backdrop pseudo elements
393
+ if (!isGecko()) {
394
+ animations.push(element.animate([{ opacity: 1 }, { opacity: 0 }], {
395
+ duration: 300,
396
+ easing: 'ease-out',
397
+ pseudoElement: '::backdrop',
398
+ fill: 'forwards',
399
+ }));
400
+ }
401
+ return Promise.all(animations.map((anim) => anim.finished));
377
402
  };
378
403
  const flipOut = (element) => {
379
404
  const animation = element.animate([
@@ -436,7 +461,6 @@ const formatString = (str) => {
436
461
  const parts = str.split(/<\s*br\s*\/?\s*>/);
437
462
  return o(parts, x `<br />`);
438
463
  };
439
- const delay = (n, resolvedValue) => new Promise((resolve) => setTimeout(() => resolve(resolvedValue), n));
440
464
  let BlotoutWallet = class BlotoutWallet extends s {
441
465
  constructor() {
442
466
  super(...arguments);
@@ -449,78 +473,76 @@ let BlotoutWallet = class BlotoutWallet extends s {
449
473
  .then(() => (this.state = newState))
450
474
  .then(() => flipIn(this.dialog));
451
475
  };
476
+ this.restoreCart = async () => {
477
+ if (!this.lastExpiredCart) {
478
+ return;
479
+ }
480
+ const email = this.email.value.trim().toLowerCase();
481
+ if (email) {
482
+ window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
483
+ const response = await fetch(this.getUrl('/user/email'), {
484
+ method: 'POST',
485
+ body: JSON.stringify({
486
+ email: email,
487
+ }),
488
+ headers: this.getHeaders(true),
489
+ });
490
+ if (!response.ok) {
491
+ throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
492
+ }
493
+ this.email.value = '';
494
+ this.hasEmail = true;
495
+ this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
496
+ window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
497
+ }
498
+ await this.storeApi.addItems(this.lastExpiredCart.items);
499
+ const expiredCartId = this.lastExpiredCart.cartId;
500
+ // this cookie will be cleared once the next event is processed
501
+ setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
502
+ // We attempt to mark the cart as restored, but if the request fails,
503
+ // we log the error in the console and let the user continue. Since the
504
+ // problem is probably in the `/cart/restore` endpoint, further attempts
505
+ // would not resolve the problem, which would just increase the number
506
+ // of failed calls and not solve the problem.
507
+ const response = await fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
508
+ method: 'POST',
509
+ headers: this.getHeaders(),
510
+ });
511
+ if (!response.ok) {
512
+ throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
513
+ }
514
+ this.lastExpiredCart = undefined;
515
+ this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
516
+ bubbles: true,
517
+ }));
518
+ // Send the request as beacon as there could be a immediate redirect in the next step
519
+ window.edgetag('tag', 'CartRecovery_CartRestored', { isSilent: !!this.silentRestore }, {}, { method: 'beacon' });
520
+ };
452
521
  this.onSubmit = async (ev) => {
453
522
  ev.preventDefault();
454
523
  ev.stopPropagation();
455
- const email = this.email.value.trim().toLowerCase();
456
524
  try {
457
525
  await this.transitionTo('loading');
458
- if (email) {
459
- window.edgetag('user', 'email', email, {}, { destination: this.edgeURL });
460
- const response = await fetch(this.getUrl('/user/email'), {
461
- method: 'POST',
462
- body: JSON.stringify({
463
- email: email,
464
- }),
465
- headers: this.getHeaders(true),
466
- });
467
- if (!response.ok) {
468
- throw new Error(`Could not save email ${response.status}: ${await response.text()}`);
469
- }
470
- this.email.value = '';
471
- this.hasEmail = true;
472
- this.dispatchEvent(new CustomEvent('blotout-wallet-email-saved', { bubbles: true }));
473
- window.edgetag('tag', 'CartRecovery_KeepCartEmailSaved', {}, {}, { destination: this.edgeURL });
474
- }
475
- if (this.lastExpiredCart) {
476
- await this.storeApi.addItems(this.lastExpiredCart.items);
477
- this.dispatchEvent(new CustomEvent('blotout-wallet-restored', {
478
- bubbles: true,
479
- }));
480
- const expiredCartId = this.lastExpiredCart.cartId;
481
- // this cookie will be cleared once the next event is processed
482
- setCookie(cartTokenLinkCookie, expiredCartId, { path: '/' });
483
- // We attempt to mark the cart as restored, but if the request fails,
484
- // we log the error in the console and let the user continue. Since the
485
- // problem is probably in the `/cart/restore` endpoint, further attempts
486
- // would not resolve the problem, which would just increase the number
487
- // of failed calls and not solve the problem.
488
- fetch(this.getUrl(`/cart/restore/${expiredCartId}`), {
489
- method: 'POST',
490
- headers: this.getHeaders(),
491
- })
492
- .then(async (response) => {
493
- if (!response.ok) {
494
- throw new Error(`Could not update status in DB - ${response.status}: ${response.text}\n\n${await response.text()}`);
495
- }
496
- // Send the request as beacon as there could be a immediate redirect in the next step
497
- window.edgetag('tag', 'CartRecovery_CartRestored', {}, {}, { method: 'beacon' });
498
- // Redirect to custom path
499
- if (this.restoreRedirect) {
500
- try {
501
- const redirect = new URL(this.restoreRedirect, window.location.origin);
502
- window.location.href = redirect.href;
503
- }
504
- catch (e) {
505
- console.error('Invalid redirect URL', e);
506
- }
507
- }
508
- })
509
- .catch((err) => {
510
- console.error(err);
511
- });
512
- this.lastExpiredCart = undefined;
513
- }
526
+ await this.restoreCart();
514
527
  await this.transitionTo('restored');
515
- delay(2000).then(() => {
516
- if (this.state == 'restored') {
517
- this.hideModal('restore');
528
+ await delay(2000);
529
+ if (this.state == 'restored') {
530
+ this.hideModal('restore');
531
+ }
532
+ // Redirect to custom path
533
+ if (this.restoreRedirect) {
534
+ try {
535
+ const redirect = new URL(this.restoreRedirect, window.location.origin);
536
+ window.location.href = redirect.href;
518
537
  }
519
- });
538
+ catch (e) {
539
+ console.error('Invalid redirect URL', e);
540
+ }
541
+ }
520
542
  }
521
543
  catch (e) {
522
- await this.transitionTo('failed');
523
544
  logger.error(e);
545
+ await this.transitionTo('failed');
524
546
  }
525
547
  };
526
548
  this.onDialogClick = () => {
@@ -630,6 +652,7 @@ let BlotoutWallet = class BlotoutWallet extends s {
630
652
  }
631
653
  }
632
654
  async initialize() {
655
+ var _a;
633
656
  if (!this.userId) {
634
657
  logger.error('No UserId set');
635
658
  return;
@@ -638,11 +661,11 @@ let BlotoutWallet = class BlotoutWallet extends s {
638
661
  return;
639
662
  }
640
663
  await delay(POPUP_IMPRESSION_DELAY);
641
- fetch(this.getUrl('/cart/expired'), {
642
- method: 'GET',
643
- headers: this.getHeaders(),
644
- })
645
- .then(async (response) => {
664
+ try {
665
+ const response = await fetch(this.getUrl('/cart/expired'), {
666
+ method: 'GET',
667
+ headers: this.getHeaders(),
668
+ });
646
669
  if (!response.ok) {
647
670
  throw new Error(`Unable to get Expired Cart ${response.status}: ${await response.text()}`);
648
671
  }
@@ -650,16 +673,27 @@ let BlotoutWallet = class BlotoutWallet extends s {
650
673
  const result = await response.json();
651
674
  this.hasEmail = result.email;
652
675
  this.lastExpiredCart = result.carts[0];
653
- if (result.carts && result.carts.length && !this.isPopUpDismissed) {
654
- this.showModal();
655
- window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
676
+ if ((_a = result.carts) === null || _a === void 0 ? void 0 : _a.length) {
677
+ if (this.silentRestore) {
678
+ this.restoreCart().catch(logger.error);
679
+ }
680
+ else if (!this.isPopUpDismissed) {
681
+ this.showModal();
682
+ }
683
+ if (result.hasJustExpired) {
684
+ window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
685
+ }
656
686
  }
657
- })
658
- .catch(logger.error);
687
+ }
688
+ catch (err) {
689
+ logger.error(err);
690
+ }
659
691
  }
660
692
  showModal() {
661
693
  this.dialog.showModal();
662
- new Promise(requestAnimationFrame).then(() => fadeInDialog(this.dialog));
694
+ new Promise(requestAnimationFrame)
695
+ .catch(logger.error)
696
+ .finally(() => fadeInDialog(this.dialog));
663
697
  this.dispatchEvent(new CustomEvent('blotout-wallet-shown', { bubbles: true }));
664
698
  fetch(this.getUrl('/user/event'), {
665
699
  method: 'POST',
@@ -668,7 +702,9 @@ let BlotoutWallet = class BlotoutWallet extends s {
668
702
  }).catch(logger.error);
669
703
  }
670
704
  hideModal(action) {
671
- fadeOutToBottom(this.dialog).then(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
705
+ fadeOutToBottom(this.dialog)
706
+ .catch(logger.error)
707
+ .finally(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
672
708
  this.dispatchEvent(new CustomEvent('blotout-wallet-hidden', { bubbles: true }));
673
709
  }
674
710
  getHeaders(json = false) {
@@ -690,18 +726,20 @@ let BlotoutWallet = class BlotoutWallet extends s {
690
726
  }
691
727
  async skipCarts() {
692
728
  this.hideModal('skip');
693
- await fetch(this.getUrl('/cart/skip'), {
694
- method: 'POST',
695
- headers: this.getHeaders(),
696
- })
697
- .then(async (response) => {
729
+ try {
730
+ const response = await fetch(this.getUrl('/cart/skip'), {
731
+ method: 'POST',
732
+ headers: this.getHeaders(),
733
+ });
698
734
  if (!response.ok) {
699
735
  throw new Error(`Could not mark cart as skipped - ${response.status}: ${await response.text()}`);
700
736
  }
701
737
  window.edgetag('tag', 'CartRecovery_CartDeclined', {}, {}, { destination: this.edgeURL });
702
738
  this.lastExpiredCart = undefined;
703
- })
704
- .catch(logger.error);
739
+ }
740
+ catch (e) {
741
+ logger.error(e);
742
+ }
705
743
  }
706
744
  render() {
707
745
  if (this.isPopUpDismissed) {
@@ -880,7 +918,7 @@ BlotoutWallet = __decorate([
880
918
  ], BlotoutWallet);
881
919
 
882
920
  const init = (params) => {
883
- var _a, _b, _c, _d, _e;
921
+ var _a, _b, _c, _d, _e, _f;
884
922
  if (
885
923
  // if loaded in non-browser SDKs
886
924
  !window ||
@@ -915,6 +953,7 @@ const init = (params) => {
915
953
  element.edgeURL = params.baseUrl;
916
954
  element.userId = params.userId;
917
955
  element.restoreRedirect = (_e = params.manifest.variables) === null || _e === void 0 ? void 0 : _e['restoreRedirect'];
956
+ element.silentRestore = ((_f = params.manifest.variables) === null || _f === void 0 ? void 0 : _f['silentRestore']) === '1';
918
957
  document.body.append(element);
919
958
  }
920
959
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotoutio/providers-blotout-wallet-sdk",
3
- "version": "0.60.1",
3
+ "version": "0.62.0",
4
4
  "description": "Blotout Wallet SDK for EdgeTag",
5
5
  "author": "Blotout",
6
6
  "license": "MIT",
@@ -42,28 +42,39 @@ const registryKey = Symbol.for('blotout-wallet');
42
42
  (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
43
43
 
44
44
  const getCookieValue = (key) => {
45
+ var _a;
45
46
  try {
46
47
  if (!document || !document.cookie) {
47
48
  return '';
48
49
  }
49
- const name = `${key}=`;
50
- const decodedCookie = decodeURIComponent(document.cookie);
51
- const ca = decodedCookie.split(';');
52
- for (let i = 0; i < ca.length; i++) {
53
- let c = ca[i];
54
- while (c.charAt(0) === ' ') {
55
- c = c.substring(1);
56
- }
57
- if (c.indexOf(name) === 0) {
58
- return c.substring(name.length, c.length);
59
- }
60
- }
61
- return '';
50
+ const cookies = parseCookies(document.cookie);
51
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
62
52
  }
63
53
  catch {
64
54
  return '';
65
55
  }
66
56
  };
57
+ const parseCookies = (cookie) => {
58
+ return Object.fromEntries(cookie
59
+ .split(/;\s+/)
60
+ .map((r) => r.split('=').map((str) => str.trim()))
61
+ .map(([cookieKey, cookieValue]) => {
62
+ if (!cookieKey) {
63
+ return [];
64
+ }
65
+ let decodedValue = '';
66
+ if (cookieValue) {
67
+ try {
68
+ decodedValue = decodeURIComponent(cookieValue);
69
+ }
70
+ catch (e) {
71
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
72
+ decodedValue = cookieValue;
73
+ }
74
+ }
75
+ return [cookieKey, decodedValue];
76
+ }));
77
+ };
67
78
 
68
79
  // eslint-disable-next-line @nx/enforce-module-boundaries
69
80
  const createShopApi = (fetchOverride = window.fetch) => ({
@@ -43,28 +43,39 @@
43
43
  (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
44
44
 
45
45
  const getCookieValue = (key) => {
46
+ var _a;
46
47
  try {
47
48
  if (!document || !document.cookie) {
48
49
  return '';
49
50
  }
50
- const name = `${key}=`;
51
- const decodedCookie = decodeURIComponent(document.cookie);
52
- const ca = decodedCookie.split(';');
53
- for (let i = 0; i < ca.length; i++) {
54
- let c = ca[i];
55
- while (c.charAt(0) === ' ') {
56
- c = c.substring(1);
57
- }
58
- if (c.indexOf(name) === 0) {
59
- return c.substring(name.length, c.length);
60
- }
61
- }
62
- return '';
51
+ const cookies = parseCookies(document.cookie);
52
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
63
53
  }
64
54
  catch {
65
55
  return '';
66
56
  }
67
57
  };
58
+ const parseCookies = (cookie) => {
59
+ return Object.fromEntries(cookie
60
+ .split(/;\s+/)
61
+ .map((r) => r.split('=').map((str) => str.trim()))
62
+ .map(([cookieKey, cookieValue]) => {
63
+ if (!cookieKey) {
64
+ return [];
65
+ }
66
+ let decodedValue = '';
67
+ if (cookieValue) {
68
+ try {
69
+ decodedValue = decodeURIComponent(cookieValue);
70
+ }
71
+ catch (e) {
72
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
73
+ decodedValue = cookieValue;
74
+ }
75
+ }
76
+ return [cookieKey, decodedValue];
77
+ }));
78
+ };
68
79
 
69
80
  // eslint-disable-next-line @nx/enforce-module-boundaries
70
81
  const createShopApi = (fetchOverride = window.fetch) => ({
@@ -40,28 +40,39 @@ const registryKey = Symbol.for('blotout-wallet');
40
40
  (_a = window[registryKey]) !== null && _a !== void 0 ? _a : (window[registryKey] = {});
41
41
 
42
42
  const getCookieValue = (key) => {
43
+ var _a;
43
44
  try {
44
45
  if (!document || !document.cookie) {
45
46
  return '';
46
47
  }
47
- const name = `${key}=`;
48
- const decodedCookie = decodeURIComponent(document.cookie);
49
- const ca = decodedCookie.split(';');
50
- for (let i = 0; i < ca.length; i++) {
51
- let c = ca[i];
52
- while (c.charAt(0) === ' ') {
53
- c = c.substring(1);
54
- }
55
- if (c.indexOf(name) === 0) {
56
- return c.substring(name.length, c.length);
57
- }
58
- }
59
- return '';
48
+ const cookies = parseCookies(document.cookie);
49
+ return (_a = cookies[key]) !== null && _a !== void 0 ? _a : '';
60
50
  }
61
51
  catch {
62
52
  return '';
63
53
  }
64
54
  };
55
+ const parseCookies = (cookie) => {
56
+ return Object.fromEntries(cookie
57
+ .split(/;\s+/)
58
+ .map((r) => r.split('=').map((str) => str.trim()))
59
+ .map(([cookieKey, cookieValue]) => {
60
+ if (!cookieKey) {
61
+ return [];
62
+ }
63
+ let decodedValue = '';
64
+ if (cookieValue) {
65
+ try {
66
+ decodedValue = decodeURIComponent(cookieValue);
67
+ }
68
+ catch (e) {
69
+ console.log(`Unable to decode cookie ${cookieKey}: ${e}`);
70
+ decodedValue = cookieValue;
71
+ }
72
+ }
73
+ return [cookieKey, decodedValue];
74
+ }));
75
+ };
65
76
 
66
77
  // eslint-disable-next-line @nx/enforce-module-boundaries
67
78
  const createShopApi = (fetchOverride = window.fetch) => ({