@zonos/elements 1.3.45 → 1.3.47

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 (128) hide show
  1. package/dist/cjs/{cart-89b4f62d.js → cart-85870c2e.js} +187 -62
  2. package/dist/cjs/{sendErrorLog-a966a8c1.js → createCustomEvent-aacc2833.js} +2 -22
  3. package/dist/cjs/index.cjs.js +13 -8
  4. package/dist/cjs/{paypal-1a1882c4.js → paypal-e4428dbf.js} +3 -3
  5. package/dist/cjs/zonos-address_8.cjs.entry.js +1 -1
  6. package/dist/cjs/zonos-cart-items_12.cjs.entry.js +25 -19
  7. package/dist/cjs/zonos-checkout.cjs.entry.js +10 -10
  8. package/dist/cjs/zonos-controller.cjs.entry.js +6 -6
  9. package/dist/cjs/zonos-country-flag.cjs.entry.js +1 -1
  10. package/dist/cjs/zonos-country-select_4.cjs.entry.js +1 -1
  11. package/dist/cjs/zonos-hello-dialog.cjs.entry.js +1 -1
  12. package/dist/cjs/zonos-hello.cjs.entry.js +2 -3
  13. package/dist/cjs/zonos-language-select_2.cjs.entry.js +1 -1
  14. package/dist/cjs/zonos-notification_3.cjs.entry.js +2 -2
  15. package/dist/collection/components/checkout/zonos-checkout/zonos-checkout-finish/zonos-checkout-finish.js +14 -8
  16. package/dist/collection/components/main/zonos-controller.js +4 -3
  17. package/dist/collection/components/store/checkout/stripe.js +4 -7
  18. package/dist/collection/components/store/hello/localization.js +1 -1
  19. package/dist/collection/components/utils/api/calculateLandedCost.js +1 -2
  20. package/dist/collection/components/utils/api/checkItemRestrictions.js +1 -2
  21. package/dist/collection/components/utils/api/getCountries.js +1 -1
  22. package/dist/collection/components/utils/api/getCountryLandedCost.js +1 -1
  23. package/dist/collection/components/utils/api/getExchangeRate.js +6 -2
  24. package/dist/collection/components/utils/api/getInclusivePricing.js +1 -2
  25. package/dist/collection/components/utils/api/getLocaleMessages.js +7 -2
  26. package/dist/collection/components/utils/api/getLocalization.js +3 -6
  27. package/dist/collection/components/utils/api/getShippingZones.js +1 -2
  28. package/dist/collection/components/utils/api/getZonosSettings.js +1 -2
  29. package/dist/collection/components/utils/api/paypalCaptureOrder.js +1 -1
  30. package/dist/collection/components/utils/api/paypalCreateOrder.js +1 -1
  31. package/dist/collection/components/utils/api/trackConversionEvent.js +1 -2
  32. package/dist/collection/components/utils/api/triggerBuildLandedCost.js +3 -2
  33. package/dist/collection/components/utils/getNextFallbackApi.js +18 -0
  34. package/dist/collection/components/utils/handleFetch.js +84 -20
  35. package/dist/collection/components/utils/logging/sendErrorLog.js +33 -6
  36. package/dist/collection/components/utils/logging/sendLoadScriptLog.js +1 -1
  37. package/dist/collection/environment.js +15 -78
  38. package/dist/collection/scripts/_getZonosQaUrl.js +6 -2
  39. package/dist/collection/scripts/_zonosBase.js +1 -0
  40. package/dist/collection/utils/formattedCloudflareApiUrl.js +43 -0
  41. package/dist/collection/utils/formattedUrl.js +80 -0
  42. package/dist/collection/utils/generateCloudflareDeployUrl.js +21 -0
  43. package/dist/esm/{cart-9f40efd7.js → cart-3aae6236.js} +188 -64
  44. package/dist/esm/{sendErrorLog-aea606c0.js → createCustomEvent-ccb20b48.js} +3 -22
  45. package/dist/esm/index.js +13 -8
  46. package/dist/esm/{paypal-f4bb6ce7.js → paypal-b1589e7b.js} +3 -3
  47. package/dist/esm/zonos-address_8.entry.js +1 -1
  48. package/dist/esm/zonos-cart-items_12.entry.js +17 -11
  49. package/dist/esm/zonos-checkout.entry.js +3 -3
  50. package/dist/esm/zonos-controller.entry.js +6 -6
  51. package/dist/esm/zonos-country-flag.entry.js +1 -1
  52. package/dist/esm/zonos-country-select_4.entry.js +1 -1
  53. package/dist/esm/zonos-hello-dialog.entry.js +1 -1
  54. package/dist/esm/zonos-hello.entry.js +2 -3
  55. package/dist/esm/zonos-language-select_2.entry.js +1 -1
  56. package/dist/esm/zonos-notification_3.entry.js +2 -2
  57. package/dist/esm-es5/{cart-9f40efd7.js → cart-3aae6236.js} +1 -1
  58. package/dist/esm-es5/createCustomEvent-ccb20b48.js +1 -0
  59. package/dist/esm-es5/index.js +1 -1
  60. package/dist/esm-es5/paypal-b1589e7b.js +17 -0
  61. package/dist/esm-es5/zonos-address_8.entry.js +1 -1
  62. package/dist/esm-es5/zonos-cart-items_12.entry.js +1 -1
  63. package/dist/esm-es5/zonos-checkout.entry.js +1 -1
  64. package/dist/esm-es5/zonos-controller.entry.js +1 -1
  65. package/dist/esm-es5/zonos-country-flag.entry.js +1 -1
  66. package/dist/esm-es5/zonos-country-select_4.entry.js +1 -1
  67. package/dist/esm-es5/zonos-hello-dialog.entry.js +1 -1
  68. package/dist/esm-es5/zonos-hello.entry.js +1 -1
  69. package/dist/esm-es5/zonos-language-select_2.entry.js +1 -1
  70. package/dist/esm-es5/zonos-notification_3.entry.js +1 -1
  71. package/dist/scripts/index.d.ts +11 -0
  72. package/dist/scripts/index.js +1 -1
  73. package/dist/scripts/loadZonos.js +1 -1
  74. package/dist/scripts/zonos.js +1 -1
  75. package/dist/types/components/utils/getNextFallbackApi.d.ts +10 -0
  76. package/dist/types/components/utils/handleFetch.d.ts +10 -1
  77. package/dist/types/components/utils/logging/sendErrorLog.d.ts +7 -1
  78. package/dist/types/environment.d.ts +8 -9
  79. package/dist/types/scripts/_getNextFallbackUrl.d.ts +1 -1
  80. package/dist/types/scripts/_zonosBase.d.ts +5 -0
  81. package/dist/types/utils/formattedCloudflareApiUrl.d.ts +20 -0
  82. package/dist/types/utils/formattedUrl.d.ts +9 -0
  83. package/dist/types/utils/generateCloudflareDeployUrl.d.ts +10 -0
  84. package/dist/zonos-elements/assets/RemoveIcon.svg +1 -1
  85. package/dist/zonos-elements/index.esm.js +1 -1
  86. package/dist/zonos-elements/{p-7b8099ed.js → p-08a43211.js} +1 -1
  87. package/dist/zonos-elements/p-1738fe3f.entry.js +1 -0
  88. package/dist/zonos-elements/p-284520ae.js +17 -0
  89. package/dist/zonos-elements/{p-578f42c1.entry.js → p-3225705b.entry.js} +1 -1
  90. package/dist/zonos-elements/{p-8630168f.system.entry.js → p-3403a81a.system.entry.js} +1 -1
  91. package/dist/zonos-elements/p-3fb9e320.system.js +17 -0
  92. package/dist/zonos-elements/{p-acf9a97e.system.entry.js → p-3fd66f5b.system.entry.js} +1 -1
  93. package/dist/zonos-elements/{p-8bf1af28.entry.js → p-57c67bbf.entry.js} +1 -1
  94. package/dist/zonos-elements/{p-4204ccf9.system.entry.js → p-6d613cee.system.entry.js} +1 -1
  95. package/dist/zonos-elements/p-7d0663ab.system.entry.js +1 -0
  96. package/dist/zonos-elements/{p-7bd28076.system.entry.js → p-8949d4a2.system.entry.js} +1 -1
  97. package/dist/zonos-elements/p-8b02985f.entry.js +1 -0
  98. package/dist/zonos-elements/p-90935326.system.entry.js +1 -0
  99. package/dist/zonos-elements/{p-c7952400.entry.js → p-9c9e8288.entry.js} +1 -1
  100. package/dist/zonos-elements/{p-43d3cafd.system.js → p-a576cbb8.system.js} +1 -1
  101. package/dist/zonos-elements/p-aa0127b3.system.js +1 -0
  102. package/dist/zonos-elements/{p-d014791e.entry.js → p-b9815df4.entry.js} +1 -1
  103. package/dist/zonos-elements/{p-ca0a5c22.system.entry.js → p-c035c64f.system.entry.js} +1 -1
  104. package/dist/zonos-elements/p-c3ca9e48.system.entry.js +1 -0
  105. package/dist/zonos-elements/p-c78dd680.system.js +1 -1
  106. package/dist/zonos-elements/{p-5845029a.system.entry.js → p-d5741e4e.system.entry.js} +1 -1
  107. package/dist/zonos-elements/{p-8618e185.entry.js → p-d5b21512.entry.js} +1 -1
  108. package/dist/zonos-elements/{p-37c9fdd2.system.entry.js → p-e4033aa7.system.entry.js} +1 -1
  109. package/dist/zonos-elements/{p-567b457b.entry.js → p-ea58a4a6.entry.js} +1 -1
  110. package/dist/zonos-elements/{p-f9754e48.entry.js → p-ed496e98.entry.js} +1 -1
  111. package/dist/zonos-elements/p-eefeab02.js +1 -0
  112. package/dist/zonos-elements/p-f25559fd.entry.js +1 -0
  113. package/dist/zonos-elements/p-f9b50965.system.js +1 -0
  114. package/dist/zonos-elements/zonos-elements.esm.js +1 -1
  115. package/package.json +1 -1
  116. package/dist/esm-es5/paypal-f4bb6ce7.js +0 -17
  117. package/dist/esm-es5/sendErrorLog-aea606c0.js +0 -1
  118. package/dist/zonos-elements/p-0bfe455c.system.entry.js +0 -1
  119. package/dist/zonos-elements/p-13618b27.system.entry.js +0 -1
  120. package/dist/zonos-elements/p-29f4cce5.system.js +0 -17
  121. package/dist/zonos-elements/p-2d01b8e6.system.entry.js +0 -1
  122. package/dist/zonos-elements/p-3490d40f.js +0 -17
  123. package/dist/zonos-elements/p-5b9f2535.system.js +0 -1
  124. package/dist/zonos-elements/p-6f759c76.system.js +0 -1
  125. package/dist/zonos-elements/p-757166b8.entry.js +0 -1
  126. package/dist/zonos-elements/p-76291114.entry.js +0 -1
  127. package/dist/zonos-elements/p-9aef3a35.entry.js +0 -1
  128. package/dist/zonos-elements/p-d99e58f2.js +0 -1
@@ -14,7 +14,6 @@ export const trackConversionEvent = async (eventName, metadata) => {
14
14
  !window.Zonos.zonosConversionTest) {
15
15
  return;
16
16
  }
17
- const url = `${process.env.NEXT_PUBLIC_ZONOS_ROUTE_URL}/api/zonos-elements/track-conversion-event`;
18
17
  const countryCode = localizationStore.selectedCountryCode;
19
18
  const organizationId = zonosStore.organizationId;
20
19
  const checkoutSessionId = cartStore.checkoutSessionId;
@@ -29,7 +28,7 @@ export const trackConversionEvent = async (eventName, metadata) => {
29
28
  metadata,
30
29
  organizationId,
31
30
  };
32
- await handleFetch(url, {
31
+ await handleFetch('/api/zonos-elements/track-conversion-event', {
33
32
  body,
34
33
  method: 'POST',
35
34
  });
@@ -1,4 +1,5 @@
1
1
  import { prepCalculateLandedCost } from "./prepCalculateLandedCost";
2
+ import { MAIN_BASE_API } from "../getNextFallbackApi";
2
3
  import { handleFetch } from "../handleFetch";
3
4
  export const triggerBuildLandedCost = async (buildLandedCost) => {
4
5
  var _a, _b, _c, _d;
@@ -9,13 +10,13 @@ export const triggerBuildLandedCost = async (buildLandedCost) => {
9
10
  checkoutSessionId: data.checkoutSessionId,
10
11
  contact: data.contact,
11
12
  shippingAddress: data.shippingAddress,
12
- zonosApiRoute: process.env.NEXT_PUBLIC_ZONOS_ROUTE_URL,
13
+ zonosApiRoute: MAIN_BASE_API,
13
14
  });
14
15
  if (!landedCost || ((_a = landedCost.errors) === null || _a === void 0 ? void 0 : _a.length)) {
15
16
  throw new Error(`Failed to build landed cost: ${((_c = (_b = landedCost === null || landedCost === void 0 ? void 0 : landedCost.errors) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.message) || 'Unknown error'}`);
16
17
  }
17
18
  // Validate the landed cost object to make sure the returned value from buildLandedCost has a valid schema
18
- const { errors, json } = await handleFetch(`${process.env.NEXT_PUBLIC_ZONOS_ROUTE_URL}/api/zonos-elements/validate-landed-cost`, {
19
+ const { errors, json } = await handleFetch('/api/zonos-elements/validate-landed-cost', {
19
20
  body: landedCost,
20
21
  headers: {
21
22
  'Content-Type': 'application/json',
@@ -0,0 +1,18 @@
1
+ const fallbackApiType = ['vercel', 'cloudflare'];
2
+ export const MAIN_BASE_API_TYPE = fallbackApiType[0];
3
+ export const fallbackApiList = {
4
+ cloudflare: process.env.NEXT_PUBLIC_ZONOS_CLOUDFLARE_URL,
5
+ vercel: process.env.NEXT_PUBLIC_ZONOS_ROUTE_URL,
6
+ };
7
+ export const MAIN_BASE_API = fallbackApiList[MAIN_BASE_API_TYPE];
8
+ /**
9
+ * Next available fallback api type
10
+ */
11
+ export const getNextFallbackApiType = (currentApiType = MAIN_BASE_API_TYPE) => {
12
+ const currentIndex = fallbackApiType.indexOf(currentApiType);
13
+ const nextFallbackApiType = fallbackApiType[currentIndex + 1];
14
+ if (!nextFallbackApiType) {
15
+ return null;
16
+ }
17
+ return nextFallbackApiType;
18
+ };
@@ -10,6 +10,10 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  }
11
11
  return t;
12
12
  };
13
+ import { fallbackApiList, getNextFallbackApiType, MAIN_BASE_API_TYPE, } from "./getNextFallbackApi";
14
+ import { jsonParse } from "./jsonParse";
15
+ import { log } from "./logging/log";
16
+ import { sendErrorLog } from "./logging/sendErrorLog";
13
17
  const getResponseBody = async ({ response, shouldLog = true, shouldThrow = false, }) => {
14
18
  try {
15
19
  const json = await response.json();
@@ -26,14 +30,36 @@ const getResponseBody = async ({ response, shouldLog = true, shouldThrow = false
26
30
  return null;
27
31
  }
28
32
  };
29
- const handleRequest = async (url, options) => {
33
+ const encodeString = (text) => {
34
+ try {
35
+ // encode the string, remove the "=" at the end of the encoded string
36
+ const encodedString = btoa(text).replace(/=/g, '');
37
+ return encodedString;
38
+ }
39
+ catch (error) {
40
+ // return the reverse string if the encoding failed
41
+ return text
42
+ .replace(/[^A-Za-z0-9]/g, '')
43
+ .split('')
44
+ .reverse()
45
+ .join('');
46
+ }
47
+ };
48
+ const handleRequest = async ({ basePathType, options, path, }) => {
30
49
  let response;
50
+ // fallback to the main base API if the passed in base path is not available
51
+ const baseUrl = fallbackApiList[basePathType] || MAIN_BASE_API_TYPE;
52
+ const url = baseUrl + path;
53
+ // adding random encoded token to the url so that the request will be cached differently for each store
54
+ const modifiedUrl = new URL(url);
55
+ modifiedUrl.searchParams.set('zToken', encodeString(window.location.hostname));
31
56
  try {
32
- response = await fetch(url, options);
57
+ response = await fetch(modifiedUrl.toString(), options);
33
58
  }
34
59
  catch (e) {
35
60
  if (e instanceof Error) {
36
61
  return {
62
+ baseUrl,
37
63
  errors: [{ message: e.message, type: 'unknown' }],
38
64
  json: null,
39
65
  response: null,
@@ -42,6 +68,7 @@ const handleRequest = async (url, options) => {
42
68
  }
43
69
  const message = 'Fail to fetch';
44
70
  return {
71
+ baseUrl,
45
72
  errors: [{ message, type: 'unknown' }],
46
73
  json: null,
47
74
  response: null,
@@ -57,6 +84,7 @@ const handleRequest = async (url, options) => {
57
84
  if (response.ok) {
58
85
  const data = await getResponseBody({ response });
59
86
  return {
87
+ baseUrl,
60
88
  errors: [],
61
89
  json: data,
62
90
  response,
@@ -71,6 +99,7 @@ const handleRequest = async (url, options) => {
71
99
  });
72
100
  const message = JSON.stringify(data);
73
101
  return {
102
+ baseUrl,
74
103
  errors: [{ message, type: status }],
75
104
  json: null,
76
105
  response,
@@ -80,6 +109,7 @@ const handleRequest = async (url, options) => {
80
109
  catch (e) {
81
110
  const message = 'Unknown error';
82
111
  return {
112
+ baseUrl,
83
113
  errors: [{ message: `${status}: ${message}`, type: status }],
84
114
  json: null,
85
115
  response: null,
@@ -87,31 +117,65 @@ const handleRequest = async (url, options) => {
87
117
  };
88
118
  }
89
119
  };
90
- function encodeString(text) {
91
- try {
92
- // encode the string, remove the "=" at the end of the encoded string
93
- const encodedString = btoa(text).replace(/=/g, '');
94
- return encodedString;
120
+ const handleRequestWithFallback = async ({ basePathType, options, path, }) => {
121
+ var _a, _b;
122
+ const _c = await handleRequest({
123
+ basePathType,
124
+ options,
125
+ path,
126
+ }), { errors, response } = _c, rest = __rest(_c, ["errors", "response"]);
127
+ const nextFallbackApiType = getNextFallbackApiType(basePathType);
128
+ const unknownError = errors.find(({ type }) => type === 'unknown');
129
+ const isUnknownError = !!unknownError || (response === null || response === void 0 ? void 0 : response.status) === 404;
130
+ const shouldCallFallback =
131
+ // If next fallback is available, and the error is unknown (fail to fetch) or 404
132
+ nextFallbackApiType && isUnknownError;
133
+ // Should log the error if it's unknown error
134
+ if (isUnknownError) {
135
+ void sendErrorLog({
136
+ endpoint: fallbackApiList[basePathType] + path,
137
+ errors: errors.map(({ message }) => message),
138
+ metadata: {
139
+ currentBasePath: basePathType,
140
+ nextFallbackApiType,
141
+ requestHeaders: options === null || options === void 0 ? void 0 : options.headers,
142
+ requestPayload: jsonParse((_a = options === null || options === void 0 ? void 0 : options.body) === null || _a === void 0 ? void 0 : _a.toString()) || ((_b = options === null || options === void 0 ? void 0 : options.body) === null || _b === void 0 ? void 0 : _b.toString()),
143
+ status: response === null || response === void 0 ? void 0 : response.status,
144
+ statusText: response === null || response === void 0 ? void 0 : response.statusText,
145
+ },
146
+ // When the error is unknown, error reporting should be enabled for period of time after release, so we can monitor the error. We should always report error for the last fallback API fails
147
+ shouldPostReleaseErrorReporting: !!nextFallbackApiType,
148
+ });
95
149
  }
96
- catch (error) {
97
- // return the reverse string if the encoding failed
98
- return text
99
- .replace(/[^A-Za-z0-9]/g, '')
100
- .split('')
101
- .reverse()
102
- .join('');
150
+ if (shouldCallFallback) {
151
+ log(`=== "${path}" failed to fetch, trying next fallback ${nextFallbackApiType}`);
152
+ return handleRequestWithFallback({
153
+ basePathType: nextFallbackApiType,
154
+ options,
155
+ path,
156
+ });
103
157
  }
104
- }
105
- export const handleFetch = async (url, _opts) => {
158
+ // No more fallbacks, just return the result
159
+ return Object.assign({ errors, response }, rest);
160
+ };
161
+ /**
162
+ * Fetch request and will request to fallback API when the first one fails
163
+ * @param path Path name of the request (e.g. /api/something/com).
164
+ * @param _opts fetch options
165
+ */
166
+ export const handleFetch = async (path, _opts) => {
106
167
  const opts = __rest(_opts || {}, []);
107
168
  const body = opts.body ? JSON.stringify(opts.body) : undefined;
108
169
  const method = opts.method || 'GET';
109
- // adding random encoded token to the url so that the request will be cached differently for each store
110
- const modifiedUrl = new URL(url);
111
- modifiedUrl.searchParams.set('zToken', encodeString(window.location.hostname));
112
170
  // headers content type
113
171
  const headers = Object.assign({ 'Content-Type': 'application/json', 'Zonos-Is-BigCommerce': window.Zonos.isBigCommerce.toString(), 'Zonos-Referer': window.location.hostname, 'Zonos-Version': window.Zonos.version, credentialtoken: window.Zonos.zonosApiKey || 'Empty credential token from zonos-elements' }, opts.headers);
114
172
  const options = Object.assign(Object.assign({}, opts), { body: method === 'GET' ? undefined : body, headers,
115
173
  method });
116
- return handleRequest(modifiedUrl.toString(), options);
174
+ // This is for testing fallback API, set fallback API type to start with
175
+ const useFallbackApi = new URLSearchParams(window.location.search).get('useFallbackApi');
176
+ return handleRequestWithFallback({
177
+ basePathType: useFallbackApi || MAIN_BASE_API_TYPE,
178
+ options,
179
+ path,
180
+ });
117
181
  };
@@ -1,5 +1,18 @@
1
- import { handleFetch } from "../handleFetch";
2
- export const sendErrorLog = async ({ endpoint, errors, metadata }) => {
1
+ import { fallbackApiList, getNextFallbackApiType, MAIN_BASE_API, } from "../getNextFallbackApi";
2
+ /**
3
+ * This is the time in milliseconds after release time that we will start sending error logs to the new API
4
+ * @default 1 hour
5
+ */
6
+ const postReleaseReportingDuration = 1 * 3600 * 1000; // 1 hour
7
+ export const sendErrorLog = async ({ endpoint, errors, metadata, shouldPostReleaseErrorReporting, }) => {
8
+ if (shouldPostReleaseErrorReporting) {
9
+ // We only want to report errors that happened if current time is less than 2 hours after release time
10
+ const releaseTime = Number(window.Zonos.releaseDate);
11
+ const currentTime = new Date().getTime();
12
+ if (currentTime - releaseTime > postReleaseReportingDuration) {
13
+ return;
14
+ }
15
+ }
3
16
  const userAgentData = 'userAgentData' in window.navigator
4
17
  ? // userAgentData is not yet supported in all browsers
5
18
  window.navigator.userAgentData
@@ -11,8 +24,22 @@ export const sendErrorLog = async ({ endpoint, errors, metadata }) => {
11
24
  ? userAgentData
12
25
  : window.navigator.userAgent }, metadata),
13
26
  };
14
- void handleFetch(`${process.env.NEXT_PUBLIC_ZONOS_ROUTE_URL}/api/zonos-elements/log-error`, {
15
- body: errorObject,
16
- method: 'POST',
17
- });
27
+ try {
28
+ // use native fetch because in handleFetch also calls sendErrorLog and it will possibly cause circular dependencies issue
29
+ void fetch(`${MAIN_BASE_API}/api/zonos-elements/log-error`, {
30
+ body: JSON.stringify(errorObject),
31
+ method: 'POST',
32
+ });
33
+ }
34
+ catch (_err) {
35
+ const nextFallbackApi = getNextFallbackApiType();
36
+ if (!nextFallbackApi) {
37
+ return;
38
+ }
39
+ // request to the fallback API if the first one fails
40
+ void fetch(`${fallbackApiList[nextFallbackApi]}/api/zonos-elements/log-error`, {
41
+ body: JSON.stringify(errorObject),
42
+ method: 'POST',
43
+ });
44
+ }
18
45
  };
@@ -14,7 +14,7 @@ export const sendLoadScriptLog = async (params) => {
14
14
  const scriptLoadLogBody = Object.assign(Object.assign({ href: window.location.href }, params), { metadata: Object.assign({ connectionDownlink: baseConnection === null || baseConnection === void 0 ? void 0 : baseConnection.downlink, connectionEffectiveType: baseConnection === null || baseConnection === void 0 ? void 0 : baseConnection.effectiveType, connectionRtt: baseConnection === null || baseConnection === void 0 ? void 0 : baseConnection.rtt, connectionSaveData: baseConnection === null || baseConnection === void 0 ? void 0 : baseConnection.saveData, userAgent: userAgentData && userAgentData.brands.length > 0
15
15
  ? userAgentData
16
16
  : window.navigator.userAgent }, params.metadata) });
17
- void handleFetch(`${process.env.NEXT_PUBLIC_ZONOS_ROUTE_URL}/api/zonos-elements/log-script-load`, {
17
+ void handleFetch('/api/zonos-elements/log-script-load', {
18
18
  body: scriptLoadLogBody,
19
19
  method: 'POST',
20
20
  });
@@ -5,7 +5,10 @@ import { config } from "dotenv";
5
5
  import { z } from "zod";
6
6
  // rollup and ts somehow can't compile this with absolute path
7
7
  // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
8
- import { generateVercelDeployUrl } from "./utils/generateVercelDeployUrl";
8
+ import { formattedCloudflareApiUrl } from "./utils/formattedCloudflareApiUrl";
9
+ // rollup and ts somehow can't compile this with absolute path
10
+ // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
11
+ import { formattedUrl } from "./utils/formattedUrl";
9
12
  export const isClientSide = typeof window !== 'undefined';
10
13
  export const inProdEnvironment = process.env.NODE_ENV === 'production';
11
14
  export const inTestEnvironment = process.env.NODE_ENV === 'test';
@@ -26,83 +29,6 @@ const UNPKG_ZONOS_URL = `https://unpkg.com/@zonos/elements@${packageVersion}`;
26
29
  */
27
30
  const CDNJS_ZONOS_URL = `https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/${packageVersion}`;
28
31
  const currentBranch = process.env.VERCEL_GIT_COMMIT_REF || process.env.BRANCH_NAME;
29
- export const formattedUrl = ({ branchName, inCI: _inCI, inVercel: _inVercel, isVercelPreview: _isVercelPreview, packageVersion: _packageVersion, type = 'full', url, }) => {
30
- if (!url) {
31
- // return origin value so t3 can throw error when it's empty
32
- return url;
33
- }
34
- const trimmedUrl = (_url) => _url === null || _url === void 0 ? void 0 : _url.replace('https://', '');
35
- const domainOnlyUrl = trimmedUrl(url);
36
- if (!_inCI && !_inVercel) {
37
- // local host environment, no need to format url
38
- return `https://${domainOnlyUrl}`;
39
- }
40
- const isProdBranch = branchName && ['main'].includes(branchName);
41
- const isServerless =
42
- // url: route.js.zonos.com
43
- domainOnlyUrl.includes('route.js') ||
44
- // url: zonos-elements-serverless-git-something
45
- domainOnlyUrl.includes('serverless-git');
46
- const isTest =
47
- // url: test.js.zonos.com
48
- domainOnlyUrl.includes('test.') ||
49
- // url: zonos-elements-test-git-something
50
- domainOnlyUrl.includes('test-git') ||
51
- // url: something.preview.js.zonos.com (this is only applicable on preview deployment of `zonos-elements` and `zonos-elements-test`)
52
- domainOnlyUrl.includes('preview.js.zonos.com');
53
- if (isTest && isProdBranch) {
54
- return `https://${domainOnlyUrl}`;
55
- }
56
- // always use vercel url if in vercel env, non-production branch (not qa or main branch) or the domain using is a test url
57
- if ((_isVercelPreview && !isProdBranch) ||
58
- isTest ||
59
- (_inVercel && type === 'vercel-git')) {
60
- // use vercel branch_url instead of the production url
61
- if (!branchName) {
62
- throw new Error('Fail to get vercel commit ref or branch name');
63
- }
64
- // get project name based on the `${url}`
65
- const isStorybook =
66
- // url: storybook.js.zonos.com
67
- domainOnlyUrl.includes('storybook.js') ||
68
- // url: zonos-elements-storybook-git-something
69
- domainOnlyUrl.includes('storybook-git');
70
- const projectName = isStorybook
71
- ? 'zonos-elements-storybook'
72
- : isServerless
73
- ? 'zonos-elements-serverless'
74
- : 'zonos-elements';
75
- // add -test suffix for test environment
76
- const fullProjectName = isTest ? `${projectName}-test` : projectName;
77
- // generate generated deploy url based on the branch name
78
- const vercelGitBranchSuffix = generateVercelDeployUrl({
79
- branchName,
80
- projectName: fullProjectName,
81
- });
82
- return `https://${vercelGitBranchSuffix}`;
83
- }
84
- // only require package version in production and in CI, so that we still can use dev url (no version prefix).
85
- if (!_packageVersion && (isProdBranch || _inCI)) {
86
- throw new Error('package version is required');
87
- }
88
- const version = type === 'major' ? `${_packageVersion === null || _packageVersion === void 0 ? void 0 : _packageVersion.split('.')[0]}` : _packageVersion;
89
- const isVersionedUrl = domainOnlyUrl === null || domainOnlyUrl === void 0 ? void 0 : domainOnlyUrl.startsWith('v');
90
- const shouldAddVersion = (isProdBranch || _inCI) && !isVersionedUrl;
91
- /**
92
- * Trimming the `qa` from the domain url only when we add version prefix
93
- * @reason We've now introduced alpha versioning for the QA branch deployment.
94
- * However, we've generated the domain as `v1.2.4-alpha.1.js.zonos.com`, while the
95
- * current CDN URL env uses `qa.js.zonos.com` on qa branch. This discrepancy causes
96
- * this function to return an invalid alpha domain (v1.2.4-alpha.1.qa.js.zonos.com).
97
- */
98
- const trimmedQaUrl = shouldAddVersion
99
- ? domainOnlyUrl === null || domainOnlyUrl === void 0 ? void 0 : domainOnlyUrl.replace('qa.js.zonos.com', 'js.zonos.com')
100
- : domainOnlyUrl;
101
- // only set version for the url once
102
- return shouldAddVersion
103
- ? `https://v${version}.${trimmedQaUrl}`
104
- : `https://${trimmedQaUrl}`;
105
- };
106
32
  if (typeof window === 'undefined') {
107
33
  // storybook can't access to any "node" modules
108
34
  config();
@@ -124,9 +50,11 @@ else {
124
50
  }
125
51
  const envClient = {
126
52
  NEXT_PUBLIC_FLAG_URL: z.string(),
53
+ NEXT_PUBLIC_RELEASE_DATE: z.string(),
127
54
  NEXT_PUBLIC_ZONOS_API_KEY: z.string(),
128
55
  NEXT_PUBLIC_ZONOS_CDNJS_CDN_URL: z.string(),
129
56
  NEXT_PUBLIC_ZONOS_CDN_URL: z.string(),
57
+ NEXT_PUBLIC_ZONOS_CLOUDFLARE_URL: z.string(),
130
58
  NEXT_PUBLIC_ZONOS_JS_DELIVR_CDN_URL: z.string(),
131
59
  NEXT_PUBLIC_ZONOS_PACKAGE_VERSION: z.string(),
132
60
  NEXT_PUBLIC_ZONOS_ROUTE_URL: z.string(),
@@ -149,6 +77,7 @@ export const env = createEnv({
149
77
  // eslint-disable-next-line sort-keys/sort-keys-fix
150
78
  runtimeEnvStrict: {
151
79
  NEXT_PUBLIC_FLAG_URL: process.env.NEXT_PUBLIC_FLAG_URL,
80
+ NEXT_PUBLIC_RELEASE_DATE: new Date().getTime().toString(),
152
81
  NEXT_PUBLIC_ZONOS_API_KEY: process.env.NEXT_PUBLIC_ZONOS_API_KEY,
153
82
  NEXT_PUBLIC_ZONOS_CDNJS_CDN_URL: CDNJS_ZONOS_URL,
154
83
  /**
@@ -164,6 +93,14 @@ export const env = createEnv({
164
93
  type: 'full',
165
94
  url: process.env.NEXT_PUBLIC_ZONOS_CDN_URL,
166
95
  }),
96
+ NEXT_PUBLIC_ZONOS_CLOUDFLARE_URL: formattedCloudflareApiUrl({
97
+ branchName: currentBranch,
98
+ inCI,
99
+ inVercel,
100
+ isVercelPreview,
101
+ projectName: 'zonos-elements',
102
+ url: process.env.NEXT_PUBLIC_ZONOS_CLOUDFLARE_URL,
103
+ }),
167
104
  NEXT_PUBLIC_ZONOS_JS_DELIVR_CDN_URL: JS_DELIVR_ZONOS_URL,
168
105
  NEXT_PUBLIC_ZONOS_PACKAGE_VERSION: packageVersion,
169
106
  /**
@@ -16,11 +16,15 @@ export const getZonosQaUrl = () => {
16
16
  const qaUrl = extractZonosQaUrl(window.location.href);
17
17
  const cdnUrl = process.env.NEXT_PUBLIC_ZONOS_CDN_URL;
18
18
  // when the qaUrl is not set and the built URL is from the test domain, use the test domain for testing
19
- if (!qaUrl && cdnUrl.includes('test.')) {
19
+ if (!qaUrl &&
20
+ (cdnUrl.includes('test.') ||
21
+ // Vercel git domain
22
+ cdnUrl.includes('test-'))) {
20
23
  return cdnUrl;
21
24
  }
22
25
  // when local demo app is running, it needs to use the local dev script unless the qaUrl is set
23
- if (!qaUrl && window.location.hostname === 'dev.demo.elements.zonos.com') {
26
+ if (!qaUrl &&
27
+ ['dev.demo.elements.zonos.com'].includes(window.location.hostname)) {
24
28
  return 'https://dev.elements.zonos.com';
25
29
  }
26
30
  if (!qaUrl) {
@@ -40,6 +40,7 @@ Zonos.zonosConversionTest = typeof window !== 'undefined' &&
40
40
  !!window.location.search.match(/\?.*(&*)zonosConversionTest/);
41
41
  Zonos._paypalMockResponse = null;
42
42
  Zonos.isBigCommerce = false;
43
+ Zonos.releaseDate = process.env.NEXT_PUBLIC_RELEASE_DATE;
43
44
  /**
44
45
  * By default, the package will load from npm
45
46
  */
@@ -0,0 +1,43 @@
1
+ // rollup and ts somehow can't compile this with absolute path
2
+ // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
3
+ import { generateCloudflareDeployUrl } from "./generateCloudflareDeployUrl";
4
+ /**
5
+ * This is to generate cloudflare url based on the environment. This won't
6
+ * - Get the cloudflare alias to build if the environment is Preview
7
+ * - Get the cloudflare production url (not preview alias) if it's production
8
+ * @note
9
+ * This is mainly used for get correct Cloudflare API to be used in scripts
10
+ * @note
11
+ * "url" is the API url in Cloudflare
12
+ * @returns
13
+ * - `https://<branch_name>.<project_name>.pages.dev` if is Preview
14
+ * - `https://route.elements.zonos.com` if is Production
15
+ */
16
+ export const formattedCloudflareApiUrl = ({ branchName, inCI: _inCI, inVercel: _inVercel, isVercelPreview: _isVercelPreview, projectName, url, }) => {
17
+ if (!url) {
18
+ // return origin value so t3 can throw error when it's empty
19
+ return url;
20
+ }
21
+ const trimmedUrl = (_url) => _url === null || _url === void 0 ? void 0 : _url.replace('https://', '');
22
+ const domainOnlyUrl = trimmedUrl(url);
23
+ if (!_inCI && !_inVercel) {
24
+ // local host environment, no need to format url
25
+ return `https://${domainOnlyUrl}`;
26
+ }
27
+ const isProdBranch = branchName && ['main'].includes(branchName);
28
+ // always use Cloudflare preview alias if in not production environment
29
+ if (_isVercelPreview && !isProdBranch) {
30
+ // use Cloudflare branch_url instead of the production url
31
+ if (!branchName) {
32
+ throw new Error('Fail to get Cloudflare commit ref or branch name');
33
+ }
34
+ // generate generated deploy url based on the branch name
35
+ const cloudflareUrl = generateCloudflareDeployUrl({
36
+ branchName,
37
+ projectName,
38
+ });
39
+ return `https://${cloudflareUrl}`;
40
+ }
41
+ // use cloudflare production url
42
+ return `https://${domainOnlyUrl}`;
43
+ };
@@ -0,0 +1,80 @@
1
+ // rollup and ts somehow can't compile this with absolute path
2
+ // eslint-disable-next-line no-relative-import-paths/no-relative-import-paths
3
+ import { generateVercelDeployUrl } from "./generateVercelDeployUrl";
4
+ export const formattedUrl = ({ branchName, inCI: _inCI, inVercel: _inVercel, isVercelPreview: _isVercelPreview, packageVersion: _packageVersion, type = 'full', url, }) => {
5
+ if (!url) {
6
+ // return origin value so t3 can throw error when it's empty
7
+ return url;
8
+ }
9
+ const trimmedUrl = (_url) => _url === null || _url === void 0 ? void 0 : _url.replace('https://', '');
10
+ const domainOnlyUrl = trimmedUrl(url);
11
+ if (!_inCI && !_inVercel) {
12
+ // local host environment, no need to format url
13
+ return `https://${domainOnlyUrl}`;
14
+ }
15
+ const isProdBranch = branchName && ['main'].includes(branchName);
16
+ const isServerless =
17
+ // url: route.js.zonos.com
18
+ domainOnlyUrl.includes('route.js') ||
19
+ // url: zonos-elements-serverless-git-something
20
+ domainOnlyUrl.includes('serverless-git');
21
+ const isTest =
22
+ // url: test.js.zonos.com
23
+ domainOnlyUrl.includes('test.') ||
24
+ // url: zonos-elements-test-git-something
25
+ domainOnlyUrl.includes('test-git') ||
26
+ // url: something.preview.js.zonos.com (this is only applicable on preview deployment of `zonos-elements` and `zonos-elements-test`)
27
+ domainOnlyUrl.includes('preview.js.zonos.com');
28
+ if (isTest && isProdBranch) {
29
+ return `https://${domainOnlyUrl}`;
30
+ }
31
+ // always use vercel url if in vercel env, non-production branch (not qa or main branch) or the domain using is a test url
32
+ if ((_isVercelPreview && !isProdBranch) ||
33
+ isTest ||
34
+ (_inVercel && type === 'vercel-git')) {
35
+ // use vercel branch_url instead of the production url
36
+ if (!branchName) {
37
+ throw new Error('Fail to get vercel commit ref or branch name');
38
+ }
39
+ // get project name based on the `${url}`
40
+ const isStorybook =
41
+ // url: storybook.js.zonos.com
42
+ domainOnlyUrl.includes('storybook.js') ||
43
+ // url: zonos-elements-storybook-git-something
44
+ domainOnlyUrl.includes('storybook-git');
45
+ const projectName = isStorybook
46
+ ? 'zonos-elements-storybook'
47
+ : isServerless
48
+ ? 'zonos-elements-serverless'
49
+ : 'zonos-elements';
50
+ // add -test suffix for test environment
51
+ const fullProjectName = isTest ? `${projectName}-test` : projectName;
52
+ // generate generated deploy url based on the branch name
53
+ const vercelGitBranchSuffix = generateVercelDeployUrl({
54
+ branchName,
55
+ projectName: fullProjectName,
56
+ });
57
+ return `https://${vercelGitBranchSuffix}`;
58
+ }
59
+ // only require package version in production and in CI, so that we still can use dev url (no version prefix).
60
+ if (!_packageVersion && (isProdBranch || _inCI)) {
61
+ throw new Error('package version is required');
62
+ }
63
+ const version = type === 'major' ? `${_packageVersion === null || _packageVersion === void 0 ? void 0 : _packageVersion.split('.')[0]}` : _packageVersion;
64
+ const isVersionedUrl = domainOnlyUrl === null || domainOnlyUrl === void 0 ? void 0 : domainOnlyUrl.startsWith('v');
65
+ const shouldAddVersion = (isProdBranch || _inCI) && !isVersionedUrl;
66
+ /**
67
+ * Trimming the `qa` from the domain url only when we add version prefix
68
+ * @reason We've now introduced alpha versioning for the QA branch deployment.
69
+ * However, we've generated the domain as `v1.2.4-alpha.1.js.zonos.com`, while the
70
+ * current CDN URL env uses `qa.js.zonos.com` on qa branch. This discrepancy causes
71
+ * this function to return an invalid alpha domain (v1.2.4-alpha.1.qa.js.zonos.com).
72
+ */
73
+ const trimmedQaUrl = shouldAddVersion
74
+ ? domainOnlyUrl === null || domainOnlyUrl === void 0 ? void 0 : domainOnlyUrl.replace('qa.js.zonos.com', 'js.zonos.com')
75
+ : domainOnlyUrl;
76
+ // only set version for the url once
77
+ return shouldAddVersion
78
+ ? `https://v${version}.${trimmedQaUrl}`
79
+ : `https://${trimmedQaUrl}`;
80
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Generate a Cloudflare deploy URL based on the branch name and project name
3
+ * @note not including https://
4
+ * @return {url} string
5
+ * @urlExample build-cloudflare-2.zonos-elements.page.dev
6
+ */
7
+ export const generateCloudflareDeployUrl = ({ branchName, projectName, }) => {
8
+ const normalizedProjectName = projectName.toLowerCase().replace(/\s+/g, '-');
9
+ // remove dots and replace non-alphanumeric characters with dashes
10
+ const normalizedBranchName = branchName
11
+ .toLowerCase()
12
+ .replace(/\./g, '-') // Replace periods with hyphens
13
+ .replace(/\//g, '-') // Replace slashes with hyphens
14
+ .replace(/[^a-z0-9-_]/g, '') // Remove any characters that aren't alphanumeric, hyphens, or underscores
15
+ .replace(/-+/g, '-') // Collapse multiple hyphens into a single hyphen
16
+ .replace(/^-+|-+$/g, ''); // Trim hyphens from start and end
17
+ if (!normalizedProjectName || !normalizedBranchName) {
18
+ return null;
19
+ }
20
+ return `${normalizedBranchName}.${normalizedProjectName}.pages.dev`;
21
+ };