@zonos/elements 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/cjs/{cart-d4b52ae8.js → cart-55512e32.js} +11 -1
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/zonos-address_2.cjs.entry.js +1 -1
  4. package/dist/cjs/zonos-cart-items_10.cjs.entry.js +1 -1
  5. package/dist/cjs/zonos-checkout.cjs.entry.js +5 -1
  6. package/dist/cjs/zonos-controller.cjs.entry.js +48 -2
  7. package/dist/cjs/zonos-payment.cjs.entry.js +1 -1
  8. package/dist/cjs/zonos-shipping-rich-radio.cjs.entry.js +1 -1
  9. package/dist/collection/components/checkout/zonos-checkout/zonos-checkout.js +4 -0
  10. package/dist/collection/components/common/zonos-shipping-rich-radio/zonos-shipping-rich-radio.css +1 -0
  11. package/dist/collection/components/main/zonos-controller.js +46 -0
  12. package/dist/collection/components/store/checkout/stripe.js +11 -1
  13. package/dist/collection/components/utils/checkout/initCheckout.js +1 -1
  14. package/dist/collection/environment.js +22 -13
  15. package/dist/collection/scripts/zonos.js +84 -3
  16. package/dist/collection/utils/generateVercelDeployUrl.js +3 -2
  17. package/dist/components/cart.js +11 -1
  18. package/dist/components/zonos-checkout.js +4 -0
  19. package/dist/components/zonos-controller.js +47 -1
  20. package/dist/components/zonos-shipping-rich-radio2.js +1 -1
  21. package/dist/esm/{cart-e1b93711.js → cart-17650017.js} +11 -1
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/zonos-address_2.entry.js +1 -1
  24. package/dist/esm/zonos-cart-items_10.entry.js +1 -1
  25. package/dist/esm/zonos-checkout.entry.js +5 -1
  26. package/dist/esm/zonos-controller.entry.js +48 -2
  27. package/dist/esm/zonos-payment.entry.js +1 -1
  28. package/dist/esm/zonos-shipping-rich-radio.entry.js +1 -1
  29. package/dist/esm-es5/cart-17650017.js +1 -0
  30. package/dist/esm-es5/index.js +1 -1
  31. package/dist/esm-es5/zonos-address_2.entry.js +1 -1
  32. package/dist/esm-es5/zonos-cart-items_10.entry.js +1 -1
  33. package/dist/esm-es5/zonos-checkout.entry.js +1 -1
  34. package/dist/esm-es5/zonos-controller.entry.js +1 -1
  35. package/dist/esm-es5/zonos-payment.entry.js +1 -1
  36. package/dist/esm-es5/zonos-shipping-rich-radio.entry.js +1 -1
  37. package/dist/scripts/loadZonos.js +86 -5
  38. package/dist/scripts/zonos.js +86 -5
  39. package/dist/types/components/main/zonos-controller.d.ts +1 -0
  40. package/dist/types/components/store/checkout/stripe.d.ts +2 -1
  41. package/dist/types/components/utils/changeDeepProperty.d.ts +1 -1
  42. package/dist/types/components/utils/changeDeepPropertyAtIndex.d.ts +1 -1
  43. package/dist/types/components/utils/checkout/initCheckout.d.ts +1 -1
  44. package/dist/types/environment.d.ts +6 -1
  45. package/dist/types/scripts/zonos.d.ts +3 -0
  46. package/dist/zonos-elements/assets/RemoveIcon.svg +1 -1
  47. package/dist/zonos-elements/index.esm.js +1 -1
  48. package/dist/zonos-elements/p-0ed3bb9f.system.entry.js +1 -0
  49. package/dist/zonos-elements/{p-a3641931.system.entry.js → p-224125da.system.entry.js} +1 -1
  50. package/dist/zonos-elements/p-3a56c240.entry.js +1 -0
  51. package/dist/zonos-elements/p-8378d94e.js +1 -0
  52. package/dist/zonos-elements/{p-05256415.system.entry.js → p-84b00605.system.entry.js} +1 -1
  53. package/dist/zonos-elements/p-8b415737.system.entry.js +1 -0
  54. package/dist/zonos-elements/{p-40778e43.entry.js → p-9202375f.entry.js} +1 -1
  55. package/dist/zonos-elements/p-a1fa50fb.entry.js +1 -0
  56. package/dist/zonos-elements/{p-60821b2a.entry.js → p-bc2c42f5.entry.js} +1 -1
  57. package/dist/zonos-elements/{p-365970ff.entry.js → p-cd71e41e.entry.js} +1 -1
  58. package/dist/zonos-elements/{p-81c699f7.system.entry.js → p-cf97cc68.system.entry.js} +1 -1
  59. package/dist/zonos-elements/{p-40083e93.system.entry.js → p-d6b8563b.system.entry.js} +1 -1
  60. package/dist/zonos-elements/{p-96a3c767.entry.js → p-e5908de2.entry.js} +1 -1
  61. package/dist/zonos-elements/p-f6add79c.system.js +1 -0
  62. package/dist/zonos-elements/p-f8491335.system.js +1 -1
  63. package/dist/zonos-elements/{p-53649e16.system.js → p-f95ac9ec.system.js} +1 -1
  64. package/dist/zonos-elements/zonos-elements.esm.js +1 -1
  65. package/package.json +3 -3
  66. package/dist/esm-es5/cart-e1b93711.js +0 -1
  67. package/dist/zonos-elements/p-25db3885.js +0 -1
  68. package/dist/zonos-elements/p-34a49bce.entry.js +0 -1
  69. package/dist/zonos-elements/p-5d7ffddb.entry.js +0 -1
  70. package/dist/zonos-elements/p-8db8cc05.system.js +0 -1
  71. package/dist/zonos-elements/p-914ce305.system.entry.js +0 -1
  72. package/dist/zonos-elements/p-de9d8a4f.system.entry.js +0 -1
@@ -92,6 +92,7 @@ const { onChange: onChange$1, reset: reset$1, state: stripeStore, } = zonosStore
92
92
  stripeAddressEventData: null,
93
93
  stripeAddressUsedWhenFetchingLC: null,
94
94
  stripeElements: null,
95
+ stripeElementsOptions: null,
95
96
  stripeLinkElement: null,
96
97
  stripeLinkEventData: null,
97
98
  stripeLinkUsedWhenFetchingLC: null,
@@ -132,13 +133,22 @@ const initStripeElements = async (props) => {
132
133
  overridePrimaryColor: props === null || props === void 0 ? void 0 : props.overridePrimaryColor,
133
134
  overrideTheme: props === null || props === void 0 ? void 0 : props.overrideTheme,
134
135
  });
136
+ // compare with the previous options to see if we need to update
137
+ const isSameOptions = JSON.stringify(stripeOptions) ===
138
+ JSON.stringify(stripeStore.stripeElementsOptions);
135
139
  if (!stripeStore.stripeElements) {
136
140
  // init stripe elements if it doesn't exist
137
141
  stripeStore.stripeElements = (_a = stripeStore.stripe) === null || _a === void 0 ? void 0 : _a.elements(stripeOptions);
142
+ // save stripe elements options for later comparison
143
+ stripeStore.stripeElementsOptions = stripeOptions;
144
+ localization.log('Stripe elements initialized');
145
+ return;
138
146
  }
139
- else {
147
+ if (!isSameOptions) {
140
148
  // update elements with new option if it already exists
141
149
  stripeStore.stripeElements.update(stripeOptions);
150
+ // save stripe elements options for later comparison
151
+ stripeStore.stripeElementsOptions = stripeOptions;
142
152
  }
143
153
  localization.log('Stripe elements initialized');
144
154
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const cart = require('./cart-d4b52ae8.js');
5
+ const cart = require('./cart-55512e32.js');
6
6
  require('./zonosStore-a430ec5b.js');
7
7
  require('./index-9542d2e7.js');
8
8
  require('./localization-d7fe7290.js');
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-9542d2e7.js');
6
- const cart = require('./cart-d4b52ae8.js');
6
+ const cart = require('./cart-55512e32.js');
7
7
  const localization = require('./localization-d7fe7290.js');
8
8
  require('./zonosStore-a430ec5b.js');
9
9
  require('./isDarkColor-f3446afd.js');
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-9542d2e7.js');
6
- const cart = require('./cart-d4b52ae8.js');
6
+ const cart = require('./cart-55512e32.js');
7
7
  const localization = require('./localization-d7fe7290.js');
8
8
  const getBorderRadius = require('./getBorderRadius-fdd605c6.js');
9
9
  const submitGtag = require('./submitGtag-d65003f9.js');
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-9542d2e7.js');
6
- const cart = require('./cart-d4b52ae8.js');
6
+ const cart = require('./cart-55512e32.js');
7
7
  const localization = require('./localization-d7fe7290.js');
8
8
  const zonosStore = require('./zonosStore-a430ec5b.js');
9
9
  const submitGtag = require('./submitGtag-d65003f9.js');
@@ -135,6 +135,8 @@ const ZonosCheckout = class {
135
135
  e.preventDefault();
136
136
  e.stopPropagation();
137
137
  localization.log('zonos checkout button clicked');
138
+ // start loading
139
+ cart.stripeStore.isFetchingSession = true;
138
140
  this.open = true;
139
141
  try {
140
142
  // buildCartDetail need to be catch since it may throw error
@@ -145,6 +147,8 @@ const ZonosCheckout = class {
145
147
  submitGtag.submitGtag('zonos-checkout-start');
146
148
  }
147
149
  catch (err) {
150
+ // stop loading
151
+ cart.stripeStore.isFetchingSession = false;
148
152
  cart.cartStoreUpdateToErrorState({
149
153
  messages: [
150
154
  localization.translate("There's been an error creating your checkout session. Please reload and try again or contact support if the error persists"),
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-9542d2e7.js');
6
- const cart = require('./cart-d4b52ae8.js');
6
+ const cart = require('./cart-55512e32.js');
7
7
  const localization = require('./localization-d7fe7290.js');
8
8
  const zonosStore = require('./zonosStore-a430ec5b.js');
9
9
  require('./isDarkColor-f3446afd.js');
@@ -27,7 +27,7 @@ const injectCheckoutElement = () => {
27
27
  document.body.appendChild(newCheckoutElement);
28
28
  }
29
29
  };
30
- const initCheckout = async (config) => {
30
+ const initCheckout = (config) => {
31
31
  if (!config.placeOrderButtonSelector) {
32
32
  // do nothing if checkout button anchor is not set
33
33
  return;
@@ -66,6 +66,44 @@ const ZonosController = class {
66
66
  constructor(hostRef) {
67
67
  index.registerInstance(this, hostRef);
68
68
  this.stripeInitEvent = index.createEvent(this, "stripeInitEvent", 7);
69
+ this.disablePlaceOrderButtons = ({ disable }) => {
70
+ const placeOrderButtonSelector = zonosStore.zonosStore.checkoutSettings.placeOrderButtonSelector;
71
+ if (!placeOrderButtonSelector) {
72
+ return;
73
+ }
74
+ const disableEvent = (e) => {
75
+ const target = e.target;
76
+ // prevent default and propagation when the item has disabled attribute
77
+ if (target.getAttribute('disabled')) {
78
+ e.preventDefault();
79
+ e.stopPropagation();
80
+ }
81
+ };
82
+ const placeOrderButton = document.querySelectorAll(placeOrderButtonSelector);
83
+ placeOrderButton.forEach(button => {
84
+ if (disable) {
85
+ button.setAttribute('disabled', 'true');
86
+ // prevent the selector to perform default action when it's disabled
87
+ button.addEventListener('click', disableEvent);
88
+ }
89
+ else {
90
+ button.removeAttribute('disabled');
91
+ // clean up the event listener
92
+ button.removeEventListener('click', disableEvent);
93
+ }
94
+ });
95
+ // only auto enable if autoEnable is true and the state is enable
96
+ if (disable) {
97
+ setTimeout(() => {
98
+ // release it if zonos is not initialized after 5 seconds (this is to prevent the place order button from being disabled forever due to api)
99
+ placeOrderButton.forEach(button => {
100
+ button.removeAttribute('disabled');
101
+ // clean up the event listener if exists
102
+ button.removeEventListener('click', disableEvent);
103
+ });
104
+ }, 5000);
105
+ }
106
+ };
69
107
  this.config = undefined;
70
108
  this.zonosApiKey = undefined;
71
109
  }
@@ -81,6 +119,10 @@ const ZonosController = class {
81
119
  cart.stripeStore.stripe = stripe;
82
120
  void initCheckout(zonosStore.zonosStore.checkoutSettings);
83
121
  localization.log('init checkout element');
122
+ // enable place order button after checkout is loaded
123
+ this.disablePlaceOrderButtons({
124
+ disable: false,
125
+ });
84
126
  }
85
127
  /**
86
128
  * Init zonos notification
@@ -103,6 +145,10 @@ const ZonosController = class {
103
145
  localization.log('Failed to load zonos settings. This domain may not have access', 'warn');
104
146
  return;
105
147
  }
148
+ // disable place order button until checkout is loaded
149
+ this.disablePlaceOrderButtons({
150
+ disable: true,
151
+ });
106
152
  // init zonos notification
107
153
  this.initZonosNotification();
108
154
  // load default setting if fail to load user setting
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const index = require('./index-9542d2e7.js');
6
- const cart = require('./cart-d4b52ae8.js');
6
+ const cart = require('./cart-55512e32.js');
7
7
  require('./zonosStore-a430ec5b.js');
8
8
  require('./localization-d7fe7290.js');
9
9
  require('./isDarkColor-f3446afd.js');
@@ -8,7 +8,7 @@ const classes = require('./classes-b7918f56.js');
8
8
  const getBorderRadius = require('./getBorderRadius-fdd605c6.js');
9
9
  const isColorVariable = require('./isColorVariable-c1ed7303.js');
10
10
 
11
- const zonosShippingRichRadioCss = ":host{font-family:Inter;display:block}:host img{max-width:100%}:host dl,:host dd,:host h1,:host h2,:host h3,:host h4,:host h5,:host h6,:host hr,:host figure,:host p,:host pre{margin:0}:host{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}:host{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}:host input{margin:0;accent-color:var(--selected-border-color, var(--amino-blue-600))}:host .zonos--shipping-rich-radio-item{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;padding:var(--amino-space-16);-ms-flex-align:center;align-items:center;gap:var(--amino-space-16);cursor:pointer;border:1px solid var(--amino-gray-200)}:host .zonos--shipping-rich-radio-item:first-child{border-top-left-radius:var(--border-radius, var(--amino-radius-10));border-top-right-radius:var(--border-radius, var(--amino-radius-10))}:host .zonos--shipping-rich-radio-item:last-child{border-bottom-right-radius:var(--border-radius, var(--amino-radius-10))}:host .zonos--shipping-rich-radio-item:not(:last-child){border-bottom:none}:host .zonos--shipping-rich-radio-item.selected{outline:1px solid var(--selected-border-color, var(--amino-blue-600));outline-offset:-1px}:host .zonos--shipping-info{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex:1;flex:1}:host .zonos--shipping-detail{-ms-flex:1;flex:1}:host .zonos--sub-detail{display:-ms-inline-flexbox;display:inline-flex;gap:8px;-ms-flex-wrap:wrap;flex-wrap:wrap}";
11
+ const zonosShippingRichRadioCss = ":host{font-family:Inter;display:block}:host img{max-width:100%}:host dl,:host dd,:host h1,:host h2,:host h3,:host h4,:host h5,:host h6,:host hr,:host figure,:host p,:host pre{margin:0}:host{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}:host{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}:host input{margin:0;accent-color:var(--selected-border-color, var(--amino-blue-600))}:host .zonos--shipping-rich-radio-item{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;padding:var(--amino-space-16);-ms-flex-align:center;align-items:center;gap:var(--amino-space-16);cursor:pointer;border:1px solid var(--amino-gray-200)}:host .zonos--shipping-rich-radio-item:first-child{border-top-left-radius:var(--border-radius, var(--amino-radius-10));border-top-right-radius:var(--border-radius, var(--amino-radius-10))}:host .zonos--shipping-rich-radio-item:last-child{border-bottom-right-radius:var(--border-radius, var(--amino-radius-10));border-bottom-left-radius:var(--border-radius, var(--amino-radius-10))}:host .zonos--shipping-rich-radio-item:not(:last-child){border-bottom:none}:host .zonos--shipping-rich-radio-item.selected{outline:1px solid var(--selected-border-color, var(--amino-blue-600));outline-offset:-1px}:host .zonos--shipping-info{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex:1;flex:1}:host .zonos--shipping-detail{-ms-flex:1;flex:1}:host .zonos--sub-detail{display:-ms-inline-flexbox;display:inline-flex;gap:8px;-ms-flex-wrap:wrap;flex-wrap:wrap}";
12
12
 
13
13
  const ZonosShippingRichRadio = class {
14
14
  constructor(hostRef) {
@@ -130,6 +130,8 @@ export class ZonosCheckout {
130
130
  e.preventDefault();
131
131
  e.stopPropagation();
132
132
  log('zonos checkout button clicked');
133
+ // start loading
134
+ stripeStore.isFetchingSession = true;
133
135
  this.open = true;
134
136
  try {
135
137
  // buildCartDetail need to be catch since it may throw error
@@ -140,6 +142,8 @@ export class ZonosCheckout {
140
142
  submitGtag('zonos-checkout-start');
141
143
  }
142
144
  catch (err) {
145
+ // stop loading
146
+ stripeStore.isFetchingSession = false;
143
147
  cartStoreUpdateToErrorState({
144
148
  messages: [
145
149
  translate("There's been an error creating your checkout session. Please reload and try again or contact support if the error persists"),
@@ -50,6 +50,7 @@
50
50
  }
51
51
  :host .zonos--shipping-rich-radio-item:last-child {
52
52
  border-bottom-right-radius: var(--border-radius, var(--amino-radius-10));
53
+ border-bottom-left-radius: var(--border-radius, var(--amino-radius-10));
53
54
  }
54
55
  :host .zonos--shipping-rich-radio-item:not(:last-child) {
55
56
  border-bottom: none;
@@ -8,6 +8,44 @@ import { initHello } from "../utils/hello/initHello";
8
8
  import { log } from "../utils/logging/log";
9
9
  export class ZonosController {
10
10
  constructor() {
11
+ this.disablePlaceOrderButtons = ({ disable }) => {
12
+ const placeOrderButtonSelector = zonosStore.checkoutSettings.placeOrderButtonSelector;
13
+ if (!placeOrderButtonSelector) {
14
+ return;
15
+ }
16
+ const disableEvent = (e) => {
17
+ const target = e.target;
18
+ // prevent default and propagation when the item has disabled attribute
19
+ if (target.getAttribute('disabled')) {
20
+ e.preventDefault();
21
+ e.stopPropagation();
22
+ }
23
+ };
24
+ const placeOrderButton = document.querySelectorAll(placeOrderButtonSelector);
25
+ placeOrderButton.forEach(button => {
26
+ if (disable) {
27
+ button.setAttribute('disabled', 'true');
28
+ // prevent the selector to perform default action when it's disabled
29
+ button.addEventListener('click', disableEvent);
30
+ }
31
+ else {
32
+ button.removeAttribute('disabled');
33
+ // clean up the event listener
34
+ button.removeEventListener('click', disableEvent);
35
+ }
36
+ });
37
+ // only auto enable if autoEnable is true and the state is enable
38
+ if (disable) {
39
+ setTimeout(() => {
40
+ // release it if zonos is not initialized after 5 seconds (this is to prevent the place order button from being disabled forever due to api)
41
+ placeOrderButton.forEach(button => {
42
+ button.removeAttribute('disabled');
43
+ // clean up the event listener if exists
44
+ button.removeEventListener('click', disableEvent);
45
+ });
46
+ }, 5000);
47
+ }
48
+ };
11
49
  this.config = undefined;
12
50
  this.zonosApiKey = undefined;
13
51
  }
@@ -23,6 +61,10 @@ export class ZonosController {
23
61
  stripeStore.stripe = stripe;
24
62
  void initCheckout(zonosStore.checkoutSettings);
25
63
  log('init checkout element');
64
+ // enable place order button after checkout is loaded
65
+ this.disablePlaceOrderButtons({
66
+ disable: false,
67
+ });
26
68
  }
27
69
  /**
28
70
  * Init zonos notification
@@ -45,6 +87,10 @@ export class ZonosController {
45
87
  log('Failed to load zonos settings. This domain may not have access', 'warn');
46
88
  return;
47
89
  }
90
+ // disable place order button until checkout is loaded
91
+ this.disablePlaceOrderButtons({
92
+ disable: true,
93
+ });
48
94
  // init zonos notification
49
95
  this.initZonosNotification();
50
96
  // load default setting if fail to load user setting
@@ -20,6 +20,7 @@ const { onChange, reset, state: stripeStore, } = createStore(() => ({
20
20
  stripeAddressEventData: null,
21
21
  stripeAddressUsedWhenFetchingLC: null,
22
22
  stripeElements: null,
23
+ stripeElementsOptions: null,
23
24
  stripeLinkElement: null,
24
25
  stripeLinkEventData: null,
25
26
  stripeLinkUsedWhenFetchingLC: null,
@@ -60,13 +61,22 @@ const initStripeElements = async (props) => {
60
61
  overridePrimaryColor: props === null || props === void 0 ? void 0 : props.overridePrimaryColor,
61
62
  overrideTheme: props === null || props === void 0 ? void 0 : props.overrideTheme,
62
63
  });
64
+ // compare with the previous options to see if we need to update
65
+ const isSameOptions = JSON.stringify(stripeOptions) ===
66
+ JSON.stringify(stripeStore.stripeElementsOptions);
63
67
  if (!stripeStore.stripeElements) {
64
68
  // init stripe elements if it doesn't exist
65
69
  stripeStore.stripeElements = (_a = stripeStore.stripe) === null || _a === void 0 ? void 0 : _a.elements(stripeOptions);
70
+ // save stripe elements options for later comparison
71
+ stripeStore.stripeElementsOptions = stripeOptions;
72
+ log('Stripe elements initialized');
73
+ return;
66
74
  }
67
- else {
75
+ if (!isSameOptions) {
68
76
  // update elements with new option if it already exists
69
77
  stripeStore.stripeElements.update(stripeOptions);
78
+ // save stripe elements options for later comparison
79
+ stripeStore.stripeElementsOptions = stripeOptions;
70
80
  }
71
81
  log('Stripe elements initialized');
72
82
  }
@@ -8,7 +8,7 @@ const injectCheckoutElement = () => {
8
8
  document.body.appendChild(newCheckoutElement);
9
9
  }
10
10
  };
11
- export const initCheckout = async (config) => {
11
+ export const initCheckout = (config) => {
12
12
  if (!config.placeOrderButtonSelector) {
13
13
  // do nothing if checkout button anchor is not set
14
14
  return;
@@ -3,6 +3,9 @@
3
3
  import { createEnv } from "@t3-oss/env-core";
4
4
  import { config } from "dotenv";
5
5
  import { z } from "zod";
6
+ // rollup and ts somehow can't compile this with absolute path
7
+ // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
8
+ import { generateVercelDeployUrl } from "./utils/generateVercelDeployUrl";
6
9
  export const isClientSide = typeof window !== 'undefined';
7
10
  export const inProdEnvironment = process.env.NODE_ENV === 'production';
8
11
  export const inTestEnvironment = process.env.NODE_ENV === 'test';
@@ -15,7 +18,6 @@ let packageVersion = `${process.env.npm_package_version}` ||
15
18
  process.env.NEXT_PUBLIC_ZONOS_PACKAGE_VERSION;
16
19
  const UNPKG_ZONOS_URL = `https://unpkg.com/@zonos/elements@${packageVersion}`;
17
20
  export const formattedUrl = ({ packageVersion: _packageVersion, type = 'full', url, }) => {
18
- var _a;
19
21
  if (!url) {
20
22
  // return origin value so t3 can throw error when it's empty
21
23
  return url;
@@ -29,17 +31,11 @@ export const formattedUrl = ({ packageVersion: _packageVersion, type = 'full', u
29
31
  // only run this in Vercel, ignore in CI
30
32
  if (isVercelPreview || (inVercel && type === 'vercel-git')) {
31
33
  // use vercel branch_url instead of the production url
32
- const vercelGitBranchUrl = process.env.VERCEL_BRANCH_URL;
33
- if (!vercelGitBranchUrl) {
34
- throw new Error('Fail to get vercel branch url');
34
+ const vercelGitCommitMessage = process.env.VERCEL_GIT_COMMIT_MESSAGE;
35
+ const branchName = process.env.VERCEL_GIT_COMMIT_REF;
36
+ if (!vercelGitCommitMessage || !branchName) {
37
+ throw new Error('Fail to get vercel commit ref or branch name');
35
38
  }
36
- // extract the git suffix from the vercel git branch url
37
- // ex: zonos-elements-storybook-git-fix-e2e-cron-test-zonos.vercel.app => git-fix-e2e-cron-test-zonos.vercel.app
38
- const gitSuffix = (_a = /.*-git-(.*)/g.exec(vercelGitBranchUrl)) === null || _a === void 0 ? void 0 : _a[1];
39
- if (!gitSuffix) {
40
- throw new Error(`Fail to get git suffix from url ${url}`);
41
- }
42
- // replace the git suffix with the project name
43
39
  // get project name based on the `${url}`
44
40
  const isStorybook =
45
41
  // url: storybook.js.zonos.com
@@ -56,7 +52,12 @@ export const formattedUrl = ({ packageVersion: _packageVersion, type = 'full', u
56
52
  : isServerless
57
53
  ? 'zonos-elements-serverless'
58
54
  : 'zonos-elements';
59
- return `https://${projectName}-git-${gitSuffix}`;
55
+ // generate generated deploy url based on the branch name
56
+ const vercelGitBranchSuffix = generateVercelDeployUrl({
57
+ branchName,
58
+ projectName,
59
+ });
60
+ return `https://${vercelGitBranchSuffix}`;
60
61
  }
61
62
  // only require package version in production and in CI, so that we still can use dev url (no version prefix).
62
63
  if (!_packageVersion && (isVercelProd || inCI)) {
@@ -140,8 +141,16 @@ export const env = createEnv({
140
141
  * Env object that has all of native env variable used in code to replace them with
141
142
  * actual values from .env
142
143
  */
143
- export const getReplaceEnv = () => Object.keys(env).reduce((prev, curr) => {
144
+ export const getReplaceEnv = (props) => Object.keys(env).reduce((prev, curr) => {
144
145
  const currEnv = curr;
146
+ const override = props === null || props === void 0 ? void 0 : props.override;
147
+ const foundOverride = !!override && currEnv in override;
148
+ // return the override value if it's found
149
+ if (foundOverride) {
150
+ // @ts-expect-error
151
+ prev[`process.env.${currEnv}`] = `"${override[currEnv]}"`;
152
+ return prev;
153
+ }
145
154
  if (currEnv) {
146
155
  // @ts-expect-error
147
156
  prev[`process.env.${currEnv}`] = `"${env[currEnv] || ''}"`;
@@ -2,7 +2,42 @@ var _a;
2
2
  import { log } from "../components/utils/logging/log";
3
3
  import { logError } from "../components/utils/logging/logError";
4
4
  import { zonosLoadStripe } from "./loadStripe";
5
- const ZONOS_URL = process.env.NEXT_PUBLIC_ZONOS_CDN_URL;
5
+ // 3 hours
6
+ const EXPIRED_QA_TIME = 3 * 60 * 60 * 1000;
7
+ // validate the time format (yyyymmddhhmmss) in the qa params if exceeds 1 hour, don't use qa
8
+ const isZonosQa = (() => {
9
+ const zonosQaTime = window.location.search.match(/\?.*(&*)zonosQa=(\d+)/);
10
+ if (!zonosQaTime) {
11
+ return false;
12
+ }
13
+ const [, , zonosQaTimeExtracted] = zonosQaTime;
14
+ if (!zonosQaTimeExtracted) {
15
+ return false;
16
+ }
17
+ const zonosQaTimeValue = parseInt(zonosQaTimeExtracted, 10);
18
+ const now = new Date();
19
+ const nowTime = now.getTime();
20
+ const isValid = nowTime - zonosQaTimeValue < EXPIRED_QA_TIME;
21
+ if (isValid) {
22
+ // Zonos class is not available in here yet, so we use console.warn instead of log util
23
+ // eslint-disable-next-line no-console
24
+ console.warn(`[ZONOS-WARNING] USING DEBUG DOMAIN, THIS IS ONLY FOR ZONOS DEVELOPER TO DEBUG, PLEASE REMOVE zonosQa=xxx OUT OF URL IF YOU DON'T KNOW WHAT YOU'RE DOING`);
25
+ }
26
+ else {
27
+ // Zonos class is not available in here yet, so we use console.warn instead of log util
28
+ // eslint-disable-next-line no-console
29
+ console.warn(`[ZONOS-WARNING] QA DOMAIN IS EXPIRED, USING PRODUCTION DOMAIN NOW`);
30
+ // remove the zonosQa param from url
31
+ const urlSearchParams = new URLSearchParams(window.location.search);
32
+ urlSearchParams.delete('zonosQa');
33
+ const newUrl = `${window.location.pathname}?${urlSearchParams.toString()}`;
34
+ window.history.replaceState({}, '', newUrl);
35
+ }
36
+ return isValid;
37
+ })();
38
+ const ZONOS_URL = isZonosQa
39
+ ? 'https://debug.js.zonos.com'
40
+ : process.env.NEXT_PUBLIC_ZONOS_CDN_URL;
6
41
  const UNPKG_ZONOS_URL = process.env.NEXT_PUBLIC_ZONOS_UNPKG_CDN_URL;
7
42
  const INTER_FONT_URL = 'https://rsms.me';
8
43
  const INTER_FONT_REGEX = /^https:\/\/rsms\.me\/inter\/inter\.css(.*)$/;
@@ -15,6 +50,7 @@ Zonos.debug = !!window.location.search.match(/\?.*(&*)zonosDebug=1/);
15
50
  Zonos.isBigCommerce = false;
16
51
  Zonos.internationalHideSelector = '';
17
52
  Zonos.version = `v${process.env.NEXT_PUBLIC_ZONOS_PACKAGE_VERSION}`;
53
+ Zonos.getCurrentTimestamp = () => new Date().getTime();
18
54
  Zonos.init = async ({ appearance, checkoutSettings, currencyConverter, helloSettings, zonosApiKey, }) => {
19
55
  if (Zonos.doneInit) {
20
56
  // do nothing if zonos is already initializeds
@@ -26,7 +62,6 @@ Zonos.init = async ({ appearance, checkoutSettings, currencyConverter, helloSett
26
62
  return;
27
63
  }
28
64
  _a.zonosApiKey = zonosApiKey;
29
- // eslint-disable-next-line no-console
30
65
  log('init zonos');
31
66
  // inject zonos cdn
32
67
  Zonos.injectZonosCdn();
@@ -56,10 +91,56 @@ Zonos.showNotification = (notification) => {
56
91
  const zonosController = document.querySelector('zonos-controller');
57
92
  void (zonosController === null || zonosController === void 0 ? void 0 : zonosController.showNotification(notification));
58
93
  };
94
+ Zonos.disablePlaceOrderButtons = ({ autoEnable = true, disable, placeOrderButtonSelector, }) => {
95
+ // if placeOrderAnchor is passed in the config for checkoutSettings, disable the place order button until zonos is initialized
96
+ if (placeOrderButtonSelector) {
97
+ const placeOrderButton = document.querySelectorAll(placeOrderButtonSelector);
98
+ const disableEvent = (e) => {
99
+ const target = e.target;
100
+ // prevent default and propagation when the item has disabled attribute
101
+ if (target.getAttribute('disabled')) {
102
+ e.preventDefault();
103
+ e.stopPropagation();
104
+ }
105
+ };
106
+ placeOrderButton.forEach(button => {
107
+ if (disable) {
108
+ button.setAttribute('disabled', 'true');
109
+ // prevent the selector to perform default action when it's disabled
110
+ button.addEventListener('click', disableEvent);
111
+ }
112
+ else {
113
+ button.removeAttribute('disabled');
114
+ // clean up the event listener
115
+ button.removeEventListener('click', disableEvent);
116
+ }
117
+ });
118
+ // only auto enable if autoEnable is true and we are setting button disable
119
+ if (autoEnable && disable) {
120
+ setTimeout(() => {
121
+ // release it if zonos is not initialized after 5 seconds (this is to prevent the place order button from being disabled forever due to api)
122
+ placeOrderButton.forEach(button => {
123
+ button.removeAttribute('disabled');
124
+ // clean up the event listener if exists
125
+ button.removeEventListener('click', disableEvent);
126
+ });
127
+ }, 5000);
128
+ }
129
+ }
130
+ };
59
131
  Zonos.injectController = ({ config, zonosApiKey, }) => {
132
+ var _b;
60
133
  if (document.querySelector('zonos-controller')) {
61
134
  return;
62
135
  }
136
+ // if placeOrderAnchor is passed in the config for checkoutSettings, disable the place order button until zonos is initialized
137
+ if ((_b = config.checkoutSettings) === null || _b === void 0 ? void 0 : _b.placeOrderButtonSelector) {
138
+ const placeOrderButtonSelector = config.checkoutSettings.placeOrderButtonSelector;
139
+ _a.disablePlaceOrderButtons({
140
+ disable: true,
141
+ placeOrderButtonSelector,
142
+ });
143
+ }
63
144
  const zonosController = document.createElement('zonos-controller');
64
145
  zonosController.config = config;
65
146
  zonosController.zonosApiKey = zonosApiKey;
@@ -167,7 +248,7 @@ Zonos.injectStylesheet = ({ fallBackDomain, stylesheetDomain, theRestUrl, }) =>
167
248
  };
168
249
  Zonos.injectZonosCss = () => {
169
250
  const findStyleLink = () => {
170
- return !!document.querySelector(`link[rel="stylesheet"][href^="${ZONOS_URL}/dist/zonos-elements/zonos-elements.css"]`);
251
+ return !!document.querySelector(`link[rel="stylesheet"][href*="/dist/zonos-elements/zonos-elements.css"]`);
171
252
  };
172
253
  if (findStyleLink()) {
173
254
  // eslint-disable-next-line no-console
@@ -1,5 +1,6 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
- import sha256 from "crypto-js/sha256";
1
+ // For some reason, rollup couldn't bundle this file without specifying .js extension
2
+ // eslint-disable-next-line import/no-extraneous-dependencies, import/extensions
3
+ import sha256 from "crypto-js/sha256.js";
3
4
  /**
4
5
  * Generate a Vercel deploy URL based on the branch name and project name
5
6
  * @note not including https://
@@ -90,6 +90,7 @@ const { onChange: onChange$1, reset: reset$1, state: stripeStore, } = createStor
90
90
  stripeAddressEventData: null,
91
91
  stripeAddressUsedWhenFetchingLC: null,
92
92
  stripeElements: null,
93
+ stripeElementsOptions: null,
93
94
  stripeLinkElement: null,
94
95
  stripeLinkEventData: null,
95
96
  stripeLinkUsedWhenFetchingLC: null,
@@ -130,13 +131,22 @@ const initStripeElements = async (props) => {
130
131
  overridePrimaryColor: props === null || props === void 0 ? void 0 : props.overridePrimaryColor,
131
132
  overrideTheme: props === null || props === void 0 ? void 0 : props.overrideTheme,
132
133
  });
134
+ // compare with the previous options to see if we need to update
135
+ const isSameOptions = JSON.stringify(stripeOptions) ===
136
+ JSON.stringify(stripeStore.stripeElementsOptions);
133
137
  if (!stripeStore.stripeElements) {
134
138
  // init stripe elements if it doesn't exist
135
139
  stripeStore.stripeElements = (_a = stripeStore.stripe) === null || _a === void 0 ? void 0 : _a.elements(stripeOptions);
140
+ // save stripe elements options for later comparison
141
+ stripeStore.stripeElementsOptions = stripeOptions;
142
+ log('Stripe elements initialized');
143
+ return;
136
144
  }
137
- else {
145
+ if (!isSameOptions) {
138
146
  // update elements with new option if it already exists
139
147
  stripeStore.stripeElements.update(stripeOptions);
148
+ // save stripe elements options for later comparison
149
+ stripeStore.stripeElementsOptions = stripeOptions;
140
150
  }
141
151
  log('Stripe elements initialized');
142
152
  }
@@ -155,6 +155,8 @@ const ZonosCheckout$1 = /*@__PURE__*/ proxyCustomElement(class ZonosCheckout ext
155
155
  e.preventDefault();
156
156
  e.stopPropagation();
157
157
  log('zonos checkout button clicked');
158
+ // start loading
159
+ stripeStore.isFetchingSession = true;
158
160
  this.open = true;
159
161
  try {
160
162
  // buildCartDetail need to be catch since it may throw error
@@ -165,6 +167,8 @@ const ZonosCheckout$1 = /*@__PURE__*/ proxyCustomElement(class ZonosCheckout ext
165
167
  submitGtag('zonos-checkout-start');
166
168
  }
167
169
  catch (err) {
170
+ // stop loading
171
+ stripeStore.isFetchingSession = false;
168
172
  cartStoreUpdateToErrorState({
169
173
  messages: [
170
174
  translate("There's been an error creating your checkout session. Please reload and try again or contact support if the error persists"),