@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 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, cookieValue]) => {
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 dialogAnimation = element.animate([
367
- { transform: 'translateY(-20px)', opacity: 0 },
368
- { transform: 'translateY(0)', opacity: 1 },
369
- ], { duration: 600, easing: spring, composite: 'add' });
370
- const backdropAnimation = element.animate([{ opacity: 0 }, { opacity: 1 }], {
371
- duration: 300,
372
- easing: 'ease-out',
373
- pseudoElement: '::backdrop',
374
- fill: 'forwards',
375
- });
376
- 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));
377
387
  };
378
388
  const fadeOutToBottom = (element) => {
379
- const dialogAnimation = element.animate([
380
- { transform: 'translateY(0)', opacity: 1 },
381
- { transform: 'translateY(20px)', opacity: 0 },
382
- ], { duration: 600, easing: spring });
383
- const backdropAnimation = element.animate([{ opacity: 1 }, { opacity: 0 }], {
384
- duration: 300,
385
- easing: 'ease-out',
386
- pseudoElement: '::backdrop',
387
- fill: 'forwards',
388
- });
389
- 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));
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
- if (email) {
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).then(() => {
529
- if (this.state == 'restored') {
530
- 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;
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
- fetch(this.getUrl('/cart/expired'), {
655
- method: 'GET',
656
- headers: this.getHeaders(),
657
- })
658
- .then(async (response) => {
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 (result.carts && result.carts.length && !this.isPopUpDismissed) {
667
- this.showModal();
668
- 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
+ }
669
689
  }
670
- })
671
- .catch(logger.error);
690
+ }
691
+ catch (err) {
692
+ logger.error(err);
693
+ }
672
694
  }
673
695
  showModal() {
674
696
  this.dialog.showModal();
675
- new Promise(requestAnimationFrame).then(() => fadeInDialog(this.dialog));
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).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); });
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
- await fetch(this.getUrl('/cart/skip'), {
707
- method: 'POST',
708
- headers: this.getHeaders(),
709
- })
710
- .then(async (response) => {
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
- .catch(logger.error);
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, cookieValue]) => {
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 dialogAnimation = element.animate([
368
- { transform: 'translateY(-20px)', opacity: 0 },
369
- { transform: 'translateY(0)', opacity: 1 },
370
- ], { duration: 600, easing: spring, composite: 'add' });
371
- const backdropAnimation = element.animate([{ opacity: 0 }, { opacity: 1 }], {
372
- duration: 300,
373
- easing: 'ease-out',
374
- pseudoElement: '::backdrop',
375
- fill: 'forwards',
376
- });
377
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
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 dialogAnimation = element.animate([
381
- { transform: 'translateY(0)', opacity: 1 },
382
- { transform: 'translateY(20px)', opacity: 0 },
383
- ], { duration: 600, easing: spring });
384
- const backdropAnimation = element.animate([{ opacity: 1 }, { opacity: 0 }], {
385
- duration: 300,
386
- easing: 'ease-out',
387
- pseudoElement: '::backdrop',
388
- fill: 'forwards',
389
- });
390
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
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
- if (email) {
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).then(() => {
530
- if (this.state == 'restored') {
531
- this.hideModal('restore');
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
- fetch(this.getUrl('/cart/expired'), {
656
- method: 'GET',
657
- headers: this.getHeaders(),
658
- })
659
- .then(async (response) => {
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 (result.carts && result.carts.length && !this.isPopUpDismissed) {
668
- this.showModal();
669
- window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
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
- .catch(logger.error);
691
+ }
692
+ catch (err) {
693
+ logger.error(err);
694
+ }
673
695
  }
674
696
  showModal() {
675
697
  this.dialog.showModal();
676
- new Promise(requestAnimationFrame).then(() => fadeInDialog(this.dialog));
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).then(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
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
- await fetch(this.getUrl('/cart/skip'), {
708
- method: 'POST',
709
- headers: this.getHeaders(),
710
- })
711
- .then(async (response) => {
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
- .catch(logger.error);
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, cookieValue]) => {
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 dialogAnimation = element.animate([
365
- { transform: 'translateY(-20px)', opacity: 0 },
366
- { transform: 'translateY(0)', opacity: 1 },
367
- ], { duration: 600, easing: spring, composite: 'add' });
368
- const backdropAnimation = element.animate([{ opacity: 0 }, { opacity: 1 }], {
369
- duration: 300,
370
- easing: 'ease-out',
371
- pseudoElement: '::backdrop',
372
- fill: 'forwards',
373
- });
374
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
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 dialogAnimation = element.animate([
378
- { transform: 'translateY(0)', opacity: 1 },
379
- { transform: 'translateY(20px)', opacity: 0 },
380
- ], { duration: 600, easing: spring });
381
- const backdropAnimation = element.animate([{ opacity: 1 }, { opacity: 0 }], {
382
- duration: 300,
383
- easing: 'ease-out',
384
- pseudoElement: '::backdrop',
385
- fill: 'forwards',
386
- });
387
- return Promise.all([dialogAnimation.finished, backdropAnimation.finished]);
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
- if (email) {
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).then(() => {
527
- if (this.state == 'restored') {
528
- this.hideModal('restore');
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
- fetch(this.getUrl('/cart/expired'), {
653
- method: 'GET',
654
- headers: this.getHeaders(),
655
- })
656
- .then(async (response) => {
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 (result.carts && result.carts.length && !this.isPopUpDismissed) {
665
- this.showModal();
666
- window.edgetag('tag', 'CartRecovery_CartExpiredOnVisit', {}, {}, { destination: this.edgeURL });
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
- .catch(logger.error);
688
+ }
689
+ catch (err) {
690
+ logger.error(err);
691
+ }
670
692
  }
671
693
  showModal() {
672
694
  this.dialog.showModal();
673
- new Promise(requestAnimationFrame).then(() => fadeInDialog(this.dialog));
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).then(() => { var _a; return (_a = this.dialog) === null || _a === void 0 ? void 0 : _a.close(action); });
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
- await fetch(this.getUrl('/cart/skip'), {
705
- method: 'POST',
706
- headers: this.getHeaders(),
707
- })
708
- .then(async (response) => {
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
- .catch(logger.error);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotoutio/providers-blotout-wallet-sdk",
3
- "version": "0.61.0",
3
+ "version": "0.62.1",
4
4
  "description": "Blotout Wallet SDK for EdgeTag",
5
5
  "author": "Blotout",
6
6
  "license": "MIT",
@@ -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, cookieValue]) => {
61
+ .map(([cookieKey, ...cookieValues]) => {
62
+ const cookieValue = cookieValues.join('=');
62
63
  if (!cookieKey) {
63
64
  return [];
64
65
  }
@@ -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, cookieValue]) => {
62
+ .map(([cookieKey, ...cookieValues]) => {
63
+ const cookieValue = cookieValues.join('=');
63
64
  if (!cookieKey) {
64
65
  return [];
65
66
  }
@@ -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, cookieValue]) => {
59
+ .map(([cookieKey, ...cookieValues]) => {
60
+ const cookieValue = cookieValues.join('=');
60
61
  if (!cookieKey) {
61
62
  return [];
62
63
  }