@tiquo/dom-package 1.1.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -22,12 +22,13 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  TiquoAuth: () => TiquoAuth,
24
24
  TiquoAuthError: () => TiquoAuthError,
25
+ TiquoPhone: () => TiquoPhone,
25
26
  addCustomerUserId: () => addCustomerUserId,
26
27
  clearCachedEmail: () => clearCachedEmail,
27
28
  default: () => index_default,
28
29
  getCustomerUserIds: () => getCustomerUserIds,
29
30
  getPrefilledEmailFromCookie: () => getPrefilledEmailFromCookie,
30
- isClerkAuthenticated: () => isClerkAuthenticated,
31
+ isDashboardSession: () => isDashboardSession,
31
32
  trackCustomerPresence: () => trackCustomerPresence,
32
33
  useTiquoAuth: () => useTiquoAuth
33
34
  });
@@ -36,9 +37,10 @@ module.exports = __toCommonJS(index_exports);
36
37
  // src/customer-cookie.ts
37
38
  var COOKIE_NAME = "tiquo_customer_user_ids";
38
39
  var COOKIE_MAX_AGE = 31536e3;
39
- function isClerkAuthenticated() {
40
+ var STAFF_SESSION_MARKERS = ["__clerk_db_jwt", "__session"];
41
+ function isDashboardSession() {
40
42
  if (typeof document === "undefined") return false;
41
- return document.cookie.includes("__clerk_db_jwt") || document.cookie.includes("__session");
43
+ return STAFF_SESSION_MARKERS.some((marker) => document.cookie.includes(marker));
42
44
  }
43
45
  function getCustomerUserIds() {
44
46
  if (typeof document === "undefined") return [];
@@ -59,8 +61,8 @@ function getCustomerUserIds() {
59
61
  function addCustomerUserId(userId) {
60
62
  if (typeof document === "undefined") return;
61
63
  if (typeof window === "undefined") return;
62
- if (isClerkAuthenticated()) {
63
- console.log("[Customer Cookie] Skipping - Clerk user detected");
64
+ if (isDashboardSession()) {
65
+ console.log("[Customer Cookie] Skipping - staff session detected");
64
66
  return;
65
67
  }
66
68
  if (!userId || typeof userId !== "string") {
@@ -86,16 +88,15 @@ function addCustomerUserId(userId) {
86
88
  cookieParts.push("Secure");
87
89
  }
88
90
  document.cookie = cookieParts.join("; ");
89
- console.log("[Customer Cookie] Added user ID to cookie:", userId);
90
91
  }
91
- var CONVEX_SITE_URL = "https://edge.tiquo.app";
92
+ var API_BASE_URL = "https://edge.tiquo.app";
92
93
  var cachedEmailData = null;
93
94
  var EMAIL_CACHE_TTL = 5 * 60 * 1e3;
94
95
  async function getPrefilledEmailFromCookie(organizationId) {
95
96
  if (typeof window === "undefined") {
96
97
  return null;
97
98
  }
98
- if (isClerkAuthenticated()) {
99
+ if (isDashboardSession()) {
99
100
  return null;
100
101
  }
101
102
  const userIds = getCustomerUserIds();
@@ -110,7 +111,7 @@ async function getPrefilledEmailFromCookie(organizationId) {
110
111
  };
111
112
  }
112
113
  try {
113
- const response = await fetch(`${CONVEX_SITE_URL}/api/customer-cookie-email`, {
114
+ const response = await fetch(`${API_BASE_URL}/api/customer-cookie-email`, {
114
115
  method: "POST",
115
116
  headers: { "Content-Type": "application/json" },
116
117
  body: JSON.stringify({ userIds, organizationId })
@@ -145,15 +146,15 @@ async function trackCustomerPresence(organizationId) {
145
146
  if (typeof window === "undefined") {
146
147
  return { success: false, error: "Not in browser environment" };
147
148
  }
148
- if (isClerkAuthenticated()) {
149
- return { success: false, error: "Clerk user detected" };
149
+ if (isDashboardSession()) {
150
+ return { success: false, error: "Staff session detected" };
150
151
  }
151
152
  const userIds = getCustomerUserIds();
152
153
  if (userIds.length === 0) {
153
154
  return { success: false, error: "No user IDs in cookie" };
154
155
  }
155
156
  try {
156
- const response = await fetch(`${CONVEX_SITE_URL}/api/customer-presence`, {
157
+ const response = await fetch(`${API_BASE_URL}/api/customer-presence`, {
157
158
  method: "POST",
158
159
  headers: { "Content-Type": "application/json" },
159
160
  body: JSON.stringify({ userIds, organizationId })
@@ -169,6 +170,485 @@ async function trackCustomerPresence(organizationId) {
169
170
  }
170
171
  }
171
172
 
173
+ // src/phone-utils.ts
174
+ var COUNTRIES = [
175
+ // ── North America (NANP +1) ──
176
+ { code: "US", name: "United States", dialCode: "+1", format: "(XXX) XXX-XXXX", flag: "\u{1F1FA}\u{1F1F8}" },
177
+ { code: "CA", name: "Canada", dialCode: "+1", format: "(XXX) XXX-XXXX", flag: "\u{1F1E8}\u{1F1E6}" },
178
+ { code: "AG", name: "Antigua and Barbuda", dialCode: "+1268", format: "XXX-XXXX", flag: "\u{1F1E6}\u{1F1EC}" },
179
+ { code: "AI", name: "Anguilla", dialCode: "+1264", format: "XXX-XXXX", flag: "\u{1F1E6}\u{1F1EE}" },
180
+ { code: "AS", name: "American Samoa", dialCode: "+1684", format: "XXX-XXXX", flag: "\u{1F1E6}\u{1F1F8}" },
181
+ { code: "BB", name: "Barbados", dialCode: "+1246", format: "XXX-XXXX", flag: "\u{1F1E7}\u{1F1E7}" },
182
+ { code: "BM", name: "Bermuda", dialCode: "+1441", format: "XXX-XXXX", flag: "\u{1F1E7}\u{1F1F2}" },
183
+ { code: "BS", name: "Bahamas", dialCode: "+1242", format: "XXX-XXXX", flag: "\u{1F1E7}\u{1F1F8}" },
184
+ { code: "DM", name: "Dominica", dialCode: "+1767", format: "XXX-XXXX", flag: "\u{1F1E9}\u{1F1F2}" },
185
+ { code: "DO", name: "Dominican Republic", dialCode: "+1809", format: "XXX-XXXX", flag: "\u{1F1E9}\u{1F1F4}" },
186
+ { code: "GD", name: "Grenada", dialCode: "+1473", format: "XXX-XXXX", flag: "\u{1F1EC}\u{1F1E9}" },
187
+ { code: "GU", name: "Guam", dialCode: "+1671", format: "XXX-XXXX", flag: "\u{1F1EC}\u{1F1FA}" },
188
+ { code: "JM", name: "Jamaica", dialCode: "+1876", format: "XXX-XXXX", flag: "\u{1F1EF}\u{1F1F2}" },
189
+ { code: "KN", name: "Saint Kitts and Nevis", dialCode: "+1869", format: "XXX-XXXX", flag: "\u{1F1F0}\u{1F1F3}" },
190
+ { code: "KY", name: "Cayman Islands", dialCode: "+1345", format: "XXX-XXXX", flag: "\u{1F1F0}\u{1F1FE}" },
191
+ { code: "LC", name: "Saint Lucia", dialCode: "+1758", format: "XXX-XXXX", flag: "\u{1F1F1}\u{1F1E8}" },
192
+ { code: "MP", name: "Northern Mariana Islands", dialCode: "+1670", format: "XXX-XXXX", flag: "\u{1F1F2}\u{1F1F5}" },
193
+ { code: "MS", name: "Montserrat", dialCode: "+1664", format: "XXX-XXXX", flag: "\u{1F1F2}\u{1F1F8}" },
194
+ { code: "PR", name: "Puerto Rico", dialCode: "+1787", format: "XXX-XXXX", flag: "\u{1F1F5}\u{1F1F7}" },
195
+ { code: "SX", name: "Sint Maarten", dialCode: "+1721", format: "XXX-XXXX", flag: "\u{1F1F8}\u{1F1FD}" },
196
+ { code: "TC", name: "Turks and Caicos Islands", dialCode: "+1649", format: "XXX-XXXX", flag: "\u{1F1F9}\u{1F1E8}" },
197
+ { code: "TT", name: "Trinidad and Tobago", dialCode: "+1868", format: "XXX-XXXX", flag: "\u{1F1F9}\u{1F1F9}" },
198
+ { code: "VC", name: "Saint Vincent and the Grenadines", dialCode: "+1784", format: "XXX-XXXX", flag: "\u{1F1FB}\u{1F1E8}" },
199
+ { code: "VG", name: "British Virgin Islands", dialCode: "+1284", format: "XXX-XXXX", flag: "\u{1F1FB}\u{1F1EC}" },
200
+ { code: "VI", name: "US Virgin Islands", dialCode: "+1340", format: "XXX-XXXX", flag: "\u{1F1FB}\u{1F1EE}" },
201
+ // ── Europe ──
202
+ { code: "GB", name: "United Kingdom", dialCode: "+44", format: "XXXX XXXXXX", flag: "\u{1F1EC}\u{1F1E7}" },
203
+ { code: "IE", name: "Ireland", dialCode: "+353", format: "XX XXX XXXX", flag: "\u{1F1EE}\u{1F1EA}" },
204
+ { code: "FR", name: "France", dialCode: "+33", format: "X XX XX XX XX", flag: "\u{1F1EB}\u{1F1F7}" },
205
+ { code: "DE", name: "Germany", dialCode: "+49", format: "XXX XXXXXXX", flag: "\u{1F1E9}\u{1F1EA}" },
206
+ { code: "IT", name: "Italy", dialCode: "+39", format: "XXX XXX XXXX", flag: "\u{1F1EE}\u{1F1F9}" },
207
+ { code: "ES", name: "Spain", dialCode: "+34", format: "XXX XXX XXX", flag: "\u{1F1EA}\u{1F1F8}" },
208
+ { code: "PT", name: "Portugal", dialCode: "+351", format: "XXX XXX XXX", flag: "\u{1F1F5}\u{1F1F9}" },
209
+ { code: "NL", name: "Netherlands", dialCode: "+31", format: "X XXXX XXXX", flag: "\u{1F1F3}\u{1F1F1}" },
210
+ { code: "BE", name: "Belgium", dialCode: "+32", format: "XXX XX XX XX", flag: "\u{1F1E7}\u{1F1EA}" },
211
+ { code: "LU", name: "Luxembourg", dialCode: "+352", format: "XXX XXX XXX", flag: "\u{1F1F1}\u{1F1FA}" },
212
+ { code: "CH", name: "Switzerland", dialCode: "+41", format: "XX XXX XX XX", flag: "\u{1F1E8}\u{1F1ED}" },
213
+ { code: "AT", name: "Austria", dialCode: "+43", format: "XXX XXXXXXX", flag: "\u{1F1E6}\u{1F1F9}" },
214
+ { code: "SE", name: "Sweden", dialCode: "+46", format: "XX XXX XX XX", flag: "\u{1F1F8}\u{1F1EA}" },
215
+ { code: "NO", name: "Norway", dialCode: "+47", format: "XXX XX XXX", flag: "\u{1F1F3}\u{1F1F4}" },
216
+ { code: "DK", name: "Denmark", dialCode: "+45", format: "XX XX XX XX", flag: "\u{1F1E9}\u{1F1F0}" },
217
+ { code: "FI", name: "Finland", dialCode: "+358", format: "XX XXX XXXX", flag: "\u{1F1EB}\u{1F1EE}" },
218
+ { code: "IS", name: "Iceland", dialCode: "+354", format: "XXX XXXX", flag: "\u{1F1EE}\u{1F1F8}" },
219
+ { code: "PL", name: "Poland", dialCode: "+48", format: "XXX XXX XXX", flag: "\u{1F1F5}\u{1F1F1}" },
220
+ { code: "CZ", name: "Czech Republic", dialCode: "+420", format: "XXX XXX XXX", flag: "\u{1F1E8}\u{1F1FF}" },
221
+ { code: "SK", name: "Slovakia", dialCode: "+421", format: "XXX XXX XXX", flag: "\u{1F1F8}\u{1F1F0}" },
222
+ { code: "HU", name: "Hungary", dialCode: "+36", format: "XX XXX XXXX", flag: "\u{1F1ED}\u{1F1FA}" },
223
+ { code: "RO", name: "Romania", dialCode: "+40", format: "XXX XXX XXX", flag: "\u{1F1F7}\u{1F1F4}" },
224
+ { code: "BG", name: "Bulgaria", dialCode: "+359", format: "XX XXX XXXX", flag: "\u{1F1E7}\u{1F1EC}" },
225
+ { code: "HR", name: "Croatia", dialCode: "+385", format: "XX XXX XXXX", flag: "\u{1F1ED}\u{1F1F7}" },
226
+ { code: "SI", name: "Slovenia", dialCode: "+386", format: "XX XXX XXX", flag: "\u{1F1F8}\u{1F1EE}" },
227
+ { code: "RS", name: "Serbia", dialCode: "+381", format: "XX XXX XXXX", flag: "\u{1F1F7}\u{1F1F8}" },
228
+ { code: "BA", name: "Bosnia and Herzegovina", dialCode: "+387", format: "XX XXX XXX", flag: "\u{1F1E7}\u{1F1E6}" },
229
+ { code: "ME", name: "Montenegro", dialCode: "+382", format: "XX XXX XXX", flag: "\u{1F1F2}\u{1F1EA}" },
230
+ { code: "MK", name: "North Macedonia", dialCode: "+389", format: "XX XXX XXX", flag: "\u{1F1F2}\u{1F1F0}" },
231
+ { code: "AL", name: "Albania", dialCode: "+355", format: "XX XXX XXXX", flag: "\u{1F1E6}\u{1F1F1}" },
232
+ { code: "XK", name: "Kosovo", dialCode: "+383", format: "XX XXX XXX", flag: "\u{1F1FD}\u{1F1F0}" },
233
+ { code: "GR", name: "Greece", dialCode: "+30", format: "XXX XXX XXXX", flag: "\u{1F1EC}\u{1F1F7}" },
234
+ { code: "CY", name: "Cyprus", dialCode: "+357", format: "XX XXXXXX", flag: "\u{1F1E8}\u{1F1FE}" },
235
+ { code: "MT", name: "Malta", dialCode: "+356", format: "XXXX XXXX", flag: "\u{1F1F2}\u{1F1F9}" },
236
+ { code: "TR", name: "Turkey", dialCode: "+90", format: "XXX XXX XXXX", flag: "\u{1F1F9}\u{1F1F7}" },
237
+ { code: "LT", name: "Lithuania", dialCode: "+370", format: "XXX XXXXX", flag: "\u{1F1F1}\u{1F1F9}" },
238
+ { code: "LV", name: "Latvia", dialCode: "+371", format: "XXXX XXXX", flag: "\u{1F1F1}\u{1F1FB}" },
239
+ { code: "EE", name: "Estonia", dialCode: "+372", format: "XXXX XXXX", flag: "\u{1F1EA}\u{1F1EA}" },
240
+ { code: "MD", name: "Moldova", dialCode: "+373", format: "XX XXX XXX", flag: "\u{1F1F2}\u{1F1E9}" },
241
+ { code: "UA", name: "Ukraine", dialCode: "+380", format: "XX XXX XX XX", flag: "\u{1F1FA}\u{1F1E6}" },
242
+ { code: "BY", name: "Belarus", dialCode: "+375", format: "XX XXX XX XX", flag: "\u{1F1E7}\u{1F1FE}" },
243
+ { code: "RU", name: "Russia", dialCode: "+7", format: "XXX XXX-XX-XX", flag: "\u{1F1F7}\u{1F1FA}" },
244
+ { code: "GE", name: "Georgia", dialCode: "+995", format: "XXX XX XX XX", flag: "\u{1F1EC}\u{1F1EA}" },
245
+ { code: "AM", name: "Armenia", dialCode: "+374", format: "XX XXXXXX", flag: "\u{1F1E6}\u{1F1F2}" },
246
+ { code: "AZ", name: "Azerbaijan", dialCode: "+994", format: "XX XXX XX XX", flag: "\u{1F1E6}\u{1F1FF}" },
247
+ { code: "MC", name: "Monaco", dialCode: "+377", format: "XX XX XX XX", flag: "\u{1F1F2}\u{1F1E8}" },
248
+ { code: "AD", name: "Andorra", dialCode: "+376", format: "XXX XXX", flag: "\u{1F1E6}\u{1F1E9}" },
249
+ { code: "SM", name: "San Marino", dialCode: "+378", format: "XXXX XXXXXX", flag: "\u{1F1F8}\u{1F1F2}" },
250
+ { code: "LI", name: "Liechtenstein", dialCode: "+423", format: "XXX XX XX", flag: "\u{1F1F1}\u{1F1EE}" },
251
+ { code: "VA", name: "Vatican City", dialCode: "+379", format: "XXXX XXXX", flag: "\u{1F1FB}\u{1F1E6}" },
252
+ { code: "GI", name: "Gibraltar", dialCode: "+350", format: "XXXX XXXX", flag: "\u{1F1EC}\u{1F1EE}" },
253
+ { code: "FO", name: "Faroe Islands", dialCode: "+298", format: "XXXXXX", flag: "\u{1F1EB}\u{1F1F4}" },
254
+ { code: "GL", name: "Greenland", dialCode: "+299", format: "XX XX XX", flag: "\u{1F1EC}\u{1F1F1}" },
255
+ // ── Asia ──
256
+ { code: "CN", name: "China", dialCode: "+86", format: "XXX XXXX XXXX", flag: "\u{1F1E8}\u{1F1F3}" },
257
+ { code: "JP", name: "Japan", dialCode: "+81", format: "XX XXXX XXXX", flag: "\u{1F1EF}\u{1F1F5}" },
258
+ { code: "KR", name: "South Korea", dialCode: "+82", format: "XX XXXX XXXX", flag: "\u{1F1F0}\u{1F1F7}" },
259
+ { code: "KP", name: "North Korea", dialCode: "+850", format: "XXX XXX XXXX", flag: "\u{1F1F0}\u{1F1F5}" },
260
+ { code: "IN", name: "India", dialCode: "+91", format: "XXXXX XXXXX", flag: "\u{1F1EE}\u{1F1F3}" },
261
+ { code: "PK", name: "Pakistan", dialCode: "+92", format: "XXX XXXXXXX", flag: "\u{1F1F5}\u{1F1F0}" },
262
+ { code: "BD", name: "Bangladesh", dialCode: "+880", format: "XXXX XXXXXX", flag: "\u{1F1E7}\u{1F1E9}" },
263
+ { code: "LK", name: "Sri Lanka", dialCode: "+94", format: "XX XXX XXXX", flag: "\u{1F1F1}\u{1F1F0}" },
264
+ { code: "NP", name: "Nepal", dialCode: "+977", format: "XXX XXXXXXX", flag: "\u{1F1F3}\u{1F1F5}" },
265
+ { code: "AF", name: "Afghanistan", dialCode: "+93", format: "XX XXX XXXX", flag: "\u{1F1E6}\u{1F1EB}" },
266
+ { code: "MM", name: "Myanmar", dialCode: "+95", format: "X XXX XXXX", flag: "\u{1F1F2}\u{1F1F2}" },
267
+ { code: "TH", name: "Thailand", dialCode: "+66", format: "XX XXX XXXX", flag: "\u{1F1F9}\u{1F1ED}" },
268
+ { code: "VN", name: "Vietnam", dialCode: "+84", format: "XX XXX XX XX", flag: "\u{1F1FB}\u{1F1F3}" },
269
+ { code: "KH", name: "Cambodia", dialCode: "+855", format: "XX XXX XXX", flag: "\u{1F1F0}\u{1F1ED}" },
270
+ { code: "LA", name: "Laos", dialCode: "+856", format: "XX XX XXX XXX", flag: "\u{1F1F1}\u{1F1E6}" },
271
+ { code: "MY", name: "Malaysia", dialCode: "+60", format: "XX XXXX XXXX", flag: "\u{1F1F2}\u{1F1FE}" },
272
+ { code: "SG", name: "Singapore", dialCode: "+65", format: "XXXX XXXX", flag: "\u{1F1F8}\u{1F1EC}" },
273
+ { code: "ID", name: "Indonesia", dialCode: "+62", format: "XXX XXXX XXXX", flag: "\u{1F1EE}\u{1F1E9}" },
274
+ { code: "PH", name: "Philippines", dialCode: "+63", format: "XXX XXX XXXX", flag: "\u{1F1F5}\u{1F1ED}" },
275
+ { code: "BN", name: "Brunei", dialCode: "+673", format: "XXX XXXX", flag: "\u{1F1E7}\u{1F1F3}" },
276
+ { code: "TL", name: "Timor-Leste", dialCode: "+670", format: "XXXX XXXX", flag: "\u{1F1F9}\u{1F1F1}" },
277
+ { code: "TW", name: "Taiwan", dialCode: "+886", format: "XXX XXX XXX", flag: "\u{1F1F9}\u{1F1FC}" },
278
+ { code: "HK", name: "Hong Kong", dialCode: "+852", format: "XXXX XXXX", flag: "\u{1F1ED}\u{1F1F0}" },
279
+ { code: "MO", name: "Macau", dialCode: "+853", format: "XXXX XXXX", flag: "\u{1F1F2}\u{1F1F4}" },
280
+ { code: "MN", name: "Mongolia", dialCode: "+976", format: "XXXX XXXX", flag: "\u{1F1F2}\u{1F1F3}" },
281
+ { code: "KZ", name: "Kazakhstan", dialCode: "+7", format: "XXX XXX XX XX", flag: "\u{1F1F0}\u{1F1FF}" },
282
+ { code: "UZ", name: "Uzbekistan", dialCode: "+998", format: "XX XXX XX XX", flag: "\u{1F1FA}\u{1F1FF}" },
283
+ { code: "TM", name: "Turkmenistan", dialCode: "+993", format: "XX XXXXXX", flag: "\u{1F1F9}\u{1F1F2}" },
284
+ { code: "KG", name: "Kyrgyzstan", dialCode: "+996", format: "XXX XXX XXX", flag: "\u{1F1F0}\u{1F1EC}" },
285
+ { code: "TJ", name: "Tajikistan", dialCode: "+992", format: "XX XXX XXXX", flag: "\u{1F1F9}\u{1F1EF}" },
286
+ { code: "MV", name: "Maldives", dialCode: "+960", format: "XXX XXXX", flag: "\u{1F1F2}\u{1F1FB}" },
287
+ { code: "BT", name: "Bhutan", dialCode: "+975", format: "XX XXX XXX", flag: "\u{1F1E7}\u{1F1F9}" },
288
+ // ── Middle East ──
289
+ { code: "AE", name: "United Arab Emirates", dialCode: "+971", format: "XX XXX XXXX", flag: "\u{1F1E6}\u{1F1EA}" },
290
+ { code: "SA", name: "Saudi Arabia", dialCode: "+966", format: "XX XXX XXXX", flag: "\u{1F1F8}\u{1F1E6}" },
291
+ { code: "QA", name: "Qatar", dialCode: "+974", format: "XXXX XXXX", flag: "\u{1F1F6}\u{1F1E6}" },
292
+ { code: "KW", name: "Kuwait", dialCode: "+965", format: "XXXX XXXX", flag: "\u{1F1F0}\u{1F1FC}" },
293
+ { code: "BH", name: "Bahrain", dialCode: "+973", format: "XXXX XXXX", flag: "\u{1F1E7}\u{1F1ED}" },
294
+ { code: "OM", name: "Oman", dialCode: "+968", format: "XXXX XXXX", flag: "\u{1F1F4}\u{1F1F2}" },
295
+ { code: "YE", name: "Yemen", dialCode: "+967", format: "XXX XXX XXX", flag: "\u{1F1FE}\u{1F1EA}" },
296
+ { code: "IR", name: "Iran", dialCode: "+98", format: "XXX XXX XXXX", flag: "\u{1F1EE}\u{1F1F7}" },
297
+ { code: "IQ", name: "Iraq", dialCode: "+964", format: "XXX XXX XXXX", flag: "\u{1F1EE}\u{1F1F6}" },
298
+ { code: "JO", name: "Jordan", dialCode: "+962", format: "X XXXX XXXX", flag: "\u{1F1EF}\u{1F1F4}" },
299
+ { code: "LB", name: "Lebanon", dialCode: "+961", format: "XX XXX XXX", flag: "\u{1F1F1}\u{1F1E7}" },
300
+ { code: "SY", name: "Syria", dialCode: "+963", format: "XXX XXX XXX", flag: "\u{1F1F8}\u{1F1FE}" },
301
+ { code: "IL", name: "Israel", dialCode: "+972", format: "XX XXX XXXX", flag: "\u{1F1EE}\u{1F1F1}" },
302
+ { code: "PS", name: "Palestine", dialCode: "+970", format: "XX XXX XXXX", flag: "\u{1F1F5}\u{1F1F8}" },
303
+ // ── Africa ──
304
+ { code: "ZA", name: "South Africa", dialCode: "+27", format: "XX XXX XXXX", flag: "\u{1F1FF}\u{1F1E6}" },
305
+ { code: "NG", name: "Nigeria", dialCode: "+234", format: "XXX XXX XXXX", flag: "\u{1F1F3}\u{1F1EC}" },
306
+ { code: "KE", name: "Kenya", dialCode: "+254", format: "XXX XXXXXX", flag: "\u{1F1F0}\u{1F1EA}" },
307
+ { code: "GH", name: "Ghana", dialCode: "+233", format: "XX XXX XXXX", flag: "\u{1F1EC}\u{1F1ED}" },
308
+ { code: "EG", name: "Egypt", dialCode: "+20", format: "XX XXXX XXXX", flag: "\u{1F1EA}\u{1F1EC}" },
309
+ { code: "MA", name: "Morocco", dialCode: "+212", format: "XX XXXX XXX", flag: "\u{1F1F2}\u{1F1E6}" },
310
+ { code: "DZ", name: "Algeria", dialCode: "+213", format: "XXX XX XX XX", flag: "\u{1F1E9}\u{1F1FF}" },
311
+ { code: "TN", name: "Tunisia", dialCode: "+216", format: "XX XXX XXX", flag: "\u{1F1F9}\u{1F1F3}" },
312
+ { code: "LY", name: "Libya", dialCode: "+218", format: "XX XXX XXXX", flag: "\u{1F1F1}\u{1F1FE}" },
313
+ { code: "ET", name: "Ethiopia", dialCode: "+251", format: "XX XXX XXXX", flag: "\u{1F1EA}\u{1F1F9}" },
314
+ { code: "TZ", name: "Tanzania", dialCode: "+255", format: "XXX XXX XXX", flag: "\u{1F1F9}\u{1F1FF}" },
315
+ { code: "UG", name: "Uganda", dialCode: "+256", format: "XXX XXXXXX", flag: "\u{1F1FA}\u{1F1EC}" },
316
+ { code: "RW", name: "Rwanda", dialCode: "+250", format: "XXX XXX XXX", flag: "\u{1F1F7}\u{1F1FC}" },
317
+ { code: "CD", name: "DR Congo", dialCode: "+243", format: "XXX XXX XXX", flag: "\u{1F1E8}\u{1F1E9}" },
318
+ { code: "CG", name: "Congo", dialCode: "+242", format: "XX XXX XXXX", flag: "\u{1F1E8}\u{1F1EC}" },
319
+ { code: "CI", name: "C\xF4te d'Ivoire", dialCode: "+225", format: "XX XX XX XXXX", flag: "\u{1F1E8}\u{1F1EE}" },
320
+ { code: "SN", name: "Senegal", dialCode: "+221", format: "XX XXX XX XX", flag: "\u{1F1F8}\u{1F1F3}" },
321
+ { code: "CM", name: "Cameroon", dialCode: "+237", format: "XXXX XXXX", flag: "\u{1F1E8}\u{1F1F2}" },
322
+ { code: "MZ", name: "Mozambique", dialCode: "+258", format: "XX XXX XXXX", flag: "\u{1F1F2}\u{1F1FF}" },
323
+ { code: "AO", name: "Angola", dialCode: "+244", format: "XXX XXX XXX", flag: "\u{1F1E6}\u{1F1F4}" },
324
+ { code: "ZW", name: "Zimbabwe", dialCode: "+263", format: "XX XXX XXXX", flag: "\u{1F1FF}\u{1F1FC}" },
325
+ { code: "ZM", name: "Zambia", dialCode: "+260", format: "XX XXXXXXX", flag: "\u{1F1FF}\u{1F1F2}" },
326
+ { code: "BW", name: "Botswana", dialCode: "+267", format: "XX XXX XXX", flag: "\u{1F1E7}\u{1F1FC}" },
327
+ { code: "NA", name: "Namibia", dialCode: "+264", format: "XX XXX XXXX", flag: "\u{1F1F3}\u{1F1E6}" },
328
+ { code: "MU", name: "Mauritius", dialCode: "+230", format: "XXXX XXXX", flag: "\u{1F1F2}\u{1F1FA}" },
329
+ { code: "MG", name: "Madagascar", dialCode: "+261", format: "XX XX XXX XX", flag: "\u{1F1F2}\u{1F1EC}" },
330
+ { code: "MW", name: "Malawi", dialCode: "+265", format: "X XXXX XXXX", flag: "\u{1F1F2}\u{1F1FC}" },
331
+ { code: "ML", name: "Mali", dialCode: "+223", format: "XXXX XXXX", flag: "\u{1F1F2}\u{1F1F1}" },
332
+ { code: "BF", name: "Burkina Faso", dialCode: "+226", format: "XX XX XX XX", flag: "\u{1F1E7}\u{1F1EB}" },
333
+ { code: "NE", name: "Niger", dialCode: "+227", format: "XX XX XX XX", flag: "\u{1F1F3}\u{1F1EA}" },
334
+ { code: "TD", name: "Chad", dialCode: "+235", format: "XX XX XX XX", flag: "\u{1F1F9}\u{1F1E9}" },
335
+ { code: "SD", name: "Sudan", dialCode: "+249", format: "XX XXX XXXX", flag: "\u{1F1F8}\u{1F1E9}" },
336
+ { code: "SS", name: "South Sudan", dialCode: "+211", format: "XX XXX XXXX", flag: "\u{1F1F8}\u{1F1F8}" },
337
+ { code: "SO", name: "Somalia", dialCode: "+252", format: "XX XXX XXX", flag: "\u{1F1F8}\u{1F1F4}" },
338
+ { code: "DJ", name: "Djibouti", dialCode: "+253", format: "XX XX XX XX", flag: "\u{1F1E9}\u{1F1EF}" },
339
+ { code: "ER", name: "Eritrea", dialCode: "+291", format: "X XXX XXX", flag: "\u{1F1EA}\u{1F1F7}" },
340
+ { code: "GM", name: "Gambia", dialCode: "+220", format: "XXX XXXX", flag: "\u{1F1EC}\u{1F1F2}" },
341
+ { code: "GN", name: "Guinea", dialCode: "+224", format: "XXX XX XX XX", flag: "\u{1F1EC}\u{1F1F3}" },
342
+ { code: "GW", name: "Guinea-Bissau", dialCode: "+245", format: "XXX XXXX", flag: "\u{1F1EC}\u{1F1FC}" },
343
+ { code: "LR", name: "Liberia", dialCode: "+231", format: "XX XXX XXXX", flag: "\u{1F1F1}\u{1F1F7}" },
344
+ { code: "SL", name: "Sierra Leone", dialCode: "+232", format: "XX XXXXXX", flag: "\u{1F1F8}\u{1F1F1}" },
345
+ { code: "TG", name: "Togo", dialCode: "+228", format: "XX XXX XXX", flag: "\u{1F1F9}\u{1F1EC}" },
346
+ { code: "BJ", name: "Benin", dialCode: "+229", format: "XX XX XXXX", flag: "\u{1F1E7}\u{1F1EF}" },
347
+ { code: "GA", name: "Gabon", dialCode: "+241", format: "X XX XX XX", flag: "\u{1F1EC}\u{1F1E6}" },
348
+ { code: "GQ", name: "Equatorial Guinea", dialCode: "+240", format: "XXX XXX XXX", flag: "\u{1F1EC}\u{1F1F6}" },
349
+ { code: "ST", name: "S\xE3o Tom\xE9 and Pr\xEDncipe", dialCode: "+239", format: "XXX XXXX", flag: "\u{1F1F8}\u{1F1F9}" },
350
+ { code: "CF", name: "Central African Republic", dialCode: "+236", format: "XX XX XX XX", flag: "\u{1F1E8}\u{1F1EB}" },
351
+ { code: "CV", name: "Cape Verde", dialCode: "+238", format: "XXX XX XX", flag: "\u{1F1E8}\u{1F1FB}" },
352
+ { code: "MR", name: "Mauritania", dialCode: "+222", format: "XXXX XXXX", flag: "\u{1F1F2}\u{1F1F7}" },
353
+ { code: "BI", name: "Burundi", dialCode: "+257", format: "XX XX XXXX", flag: "\u{1F1E7}\u{1F1EE}" },
354
+ { code: "LS", name: "Lesotho", dialCode: "+266", format: "XXXX XXXX", flag: "\u{1F1F1}\u{1F1F8}" },
355
+ { code: "SZ", name: "Eswatini", dialCode: "+268", format: "XXXX XXXX", flag: "\u{1F1F8}\u{1F1FF}" },
356
+ { code: "KM", name: "Comoros", dialCode: "+269", format: "XXX XX XX", flag: "\u{1F1F0}\u{1F1F2}" },
357
+ { code: "SC", name: "Seychelles", dialCode: "+248", format: "X XXX XXX", flag: "\u{1F1F8}\u{1F1E8}" },
358
+ { code: "RE", name: "R\xE9union", dialCode: "+262", format: "XXX XX XX XX", flag: "\u{1F1F7}\u{1F1EA}" },
359
+ { code: "YT", name: "Mayotte", dialCode: "+262", format: "XXX XX XX XX", flag: "\u{1F1FE}\u{1F1F9}" },
360
+ // ── Americas (non-NANP) ──
361
+ { code: "MX", name: "Mexico", dialCode: "+52", format: "XXX XXX XXXX", flag: "\u{1F1F2}\u{1F1FD}" },
362
+ { code: "BR", name: "Brazil", dialCode: "+55", format: "XX XXXXX XXXX", flag: "\u{1F1E7}\u{1F1F7}" },
363
+ { code: "AR", name: "Argentina", dialCode: "+54", format: "XX XXXX XXXX", flag: "\u{1F1E6}\u{1F1F7}" },
364
+ { code: "CO", name: "Colombia", dialCode: "+57", format: "XXX XXX XXXX", flag: "\u{1F1E8}\u{1F1F4}" },
365
+ { code: "CL", name: "Chile", dialCode: "+56", format: "X XXXX XXXX", flag: "\u{1F1E8}\u{1F1F1}" },
366
+ { code: "PE", name: "Peru", dialCode: "+51", format: "XXX XXX XXX", flag: "\u{1F1F5}\u{1F1EA}" },
367
+ { code: "VE", name: "Venezuela", dialCode: "+58", format: "XXX XXX XXXX", flag: "\u{1F1FB}\u{1F1EA}" },
368
+ { code: "EC", name: "Ecuador", dialCode: "+593", format: "XX XXX XXXX", flag: "\u{1F1EA}\u{1F1E8}" },
369
+ { code: "UY", name: "Uruguay", dialCode: "+598", format: "X XXX XX XX", flag: "\u{1F1FA}\u{1F1FE}" },
370
+ { code: "PY", name: "Paraguay", dialCode: "+595", format: "XXX XXX XXX", flag: "\u{1F1F5}\u{1F1FE}" },
371
+ { code: "BO", name: "Bolivia", dialCode: "+591", format: "X XXX XXXX", flag: "\u{1F1E7}\u{1F1F4}" },
372
+ { code: "GY", name: "Guyana", dialCode: "+592", format: "XXX XXXX", flag: "\u{1F1EC}\u{1F1FE}" },
373
+ { code: "SR", name: "Suriname", dialCode: "+597", format: "XXX XXXX", flag: "\u{1F1F8}\u{1F1F7}" },
374
+ { code: "GF", name: "French Guiana", dialCode: "+594", format: "XXX XX XX XX", flag: "\u{1F1EC}\u{1F1EB}" },
375
+ { code: "FK", name: "Falkland Islands", dialCode: "+500", format: "XXXXX", flag: "\u{1F1EB}\u{1F1F0}" },
376
+ { code: "CR", name: "Costa Rica", dialCode: "+506", format: "XXXX XXXX", flag: "\u{1F1E8}\u{1F1F7}" },
377
+ { code: "PA", name: "Panama", dialCode: "+507", format: "XXXX XXXX", flag: "\u{1F1F5}\u{1F1E6}" },
378
+ { code: "GT", name: "Guatemala", dialCode: "+502", format: "XXXX XXXX", flag: "\u{1F1EC}\u{1F1F9}" },
379
+ { code: "HN", name: "Honduras", dialCode: "+504", format: "XXXX XXXX", flag: "\u{1F1ED}\u{1F1F3}" },
380
+ { code: "SV", name: "El Salvador", dialCode: "+503", format: "XXXX XXXX", flag: "\u{1F1F8}\u{1F1FB}" },
381
+ { code: "NI", name: "Nicaragua", dialCode: "+505", format: "XXXX XXXX", flag: "\u{1F1F3}\u{1F1EE}" },
382
+ { code: "BZ", name: "Belize", dialCode: "+501", format: "XXX XXXX", flag: "\u{1F1E7}\u{1F1FF}" },
383
+ { code: "CU", name: "Cuba", dialCode: "+53", format: "X XXX XXXX", flag: "\u{1F1E8}\u{1F1FA}" },
384
+ { code: "HT", name: "Haiti", dialCode: "+509", format: "XX XX XXXX", flag: "\u{1F1ED}\u{1F1F9}" },
385
+ { code: "GP", name: "Guadeloupe", dialCode: "+590", format: "XXX XX XX XX", flag: "\u{1F1EC}\u{1F1F5}" },
386
+ { code: "MQ", name: "Martinique", dialCode: "+596", format: "XXX XX XX XX", flag: "\u{1F1F2}\u{1F1F6}" },
387
+ { code: "PM", name: "Saint Pierre and Miquelon", dialCode: "+508", format: "XX XX XX", flag: "\u{1F1F5}\u{1F1F2}" },
388
+ // ── Oceania ──
389
+ { code: "AU", name: "Australia", dialCode: "+61", format: "XXX XXX XXX", flag: "\u{1F1E6}\u{1F1FA}" },
390
+ { code: "NZ", name: "New Zealand", dialCode: "+64", format: "XX XXX XXXX", flag: "\u{1F1F3}\u{1F1FF}" },
391
+ { code: "FJ", name: "Fiji", dialCode: "+679", format: "XXX XXXX", flag: "\u{1F1EB}\u{1F1EF}" },
392
+ { code: "PG", name: "Papua New Guinea", dialCode: "+675", format: "XXX XXXX", flag: "\u{1F1F5}\u{1F1EC}" },
393
+ { code: "WS", name: "Samoa", dialCode: "+685", format: "XX XXXXX", flag: "\u{1F1FC}\u{1F1F8}" },
394
+ { code: "TO", name: "Tonga", dialCode: "+676", format: "XXX XXXX", flag: "\u{1F1F9}\u{1F1F4}" },
395
+ { code: "VU", name: "Vanuatu", dialCode: "+678", format: "XXX XXXX", flag: "\u{1F1FB}\u{1F1FA}" },
396
+ { code: "SB", name: "Solomon Islands", dialCode: "+677", format: "XXXXX", flag: "\u{1F1F8}\u{1F1E7}" },
397
+ { code: "NC", name: "New Caledonia", dialCode: "+687", format: "XX XX XX", flag: "\u{1F1F3}\u{1F1E8}" },
398
+ { code: "PF", name: "French Polynesia", dialCode: "+689", format: "XX XX XX XX", flag: "\u{1F1F5}\u{1F1EB}" },
399
+ { code: "CK", name: "Cook Islands", dialCode: "+682", format: "XX XXX", flag: "\u{1F1E8}\u{1F1F0}" },
400
+ { code: "NU", name: "Niue", dialCode: "+683", format: "XXXX", flag: "\u{1F1F3}\u{1F1FA}" },
401
+ { code: "NR", name: "Nauru", dialCode: "+674", format: "XXX XXXX", flag: "\u{1F1F3}\u{1F1F7}" },
402
+ { code: "TV", name: "Tuvalu", dialCode: "+688", format: "XXXXX", flag: "\u{1F1F9}\u{1F1FB}" },
403
+ { code: "KI", name: "Kiribati", dialCode: "+686", format: "XXXX XXXX", flag: "\u{1F1F0}\u{1F1EE}" },
404
+ { code: "MH", name: "Marshall Islands", dialCode: "+692", format: "XXX XXXX", flag: "\u{1F1F2}\u{1F1ED}" },
405
+ { code: "FM", name: "Micronesia", dialCode: "+691", format: "XXX XXXX", flag: "\u{1F1EB}\u{1F1F2}" },
406
+ { code: "PW", name: "Palau", dialCode: "+680", format: "XXX XXXX", flag: "\u{1F1F5}\u{1F1FC}" }
407
+ ];
408
+ var SORTED_DIAL_CODES = (() => {
409
+ const entries = [];
410
+ const seen = /* @__PURE__ */ new Set();
411
+ for (const c of COUNTRIES) {
412
+ const dc = c.dialCode.replace("+", "");
413
+ const key = `${dc}-${c.code}`;
414
+ if (!seen.has(key)) {
415
+ seen.add(key);
416
+ entries.push({ dialCode: dc, code: c.code });
417
+ }
418
+ }
419
+ return entries.sort((a, b) => b.dialCode.length - a.dialCode.length);
420
+ })();
421
+ var TWO_DIGIT_CC = /* @__PURE__ */ new Set([
422
+ "20",
423
+ "27",
424
+ "30",
425
+ "31",
426
+ "32",
427
+ "33",
428
+ "34",
429
+ "36",
430
+ "39",
431
+ "40",
432
+ "41",
433
+ "43",
434
+ "44",
435
+ "45",
436
+ "46",
437
+ "47",
438
+ "48",
439
+ "49",
440
+ "51",
441
+ "52",
442
+ "53",
443
+ "54",
444
+ "55",
445
+ "56",
446
+ "57",
447
+ "58",
448
+ "60",
449
+ "61",
450
+ "62",
451
+ "63",
452
+ "64",
453
+ "65",
454
+ "66",
455
+ "81",
456
+ "82",
457
+ "84",
458
+ "86",
459
+ "90",
460
+ "91",
461
+ "92",
462
+ "93",
463
+ "94",
464
+ "95",
465
+ "98"
466
+ ]);
467
+ function getCountryCodeLength(digits) {
468
+ if (!digits || digits.length === 0) return 0;
469
+ const first = digits[0];
470
+ if (first === "1" || first === "7") return 1;
471
+ if (digits.length >= 2 && TWO_DIGIT_CC.has(digits.substring(0, 2))) return 2;
472
+ return 3;
473
+ }
474
+ function normalizePhone(phone) {
475
+ if (!phone) return "";
476
+ let input = phone.replace(
477
+ /[\u200B-\u200F\u202A-\u202E\u2060-\u2069\uFEFF\u00AD\u2028\u2029\u061C\u180E]/g,
478
+ ""
479
+ ).trim();
480
+ if (!input) return "";
481
+ input = input.replace(/\(0\)/g, "");
482
+ let hasPlus = false;
483
+ let digits = "";
484
+ for (let i = 0; i < input.length; i++) {
485
+ const ch = input[i];
486
+ if (ch === "+" && digits.length === 0 && !hasPlus) {
487
+ hasPlus = true;
488
+ } else if (ch >= "0" && ch <= "9") {
489
+ digits += ch;
490
+ }
491
+ }
492
+ if (!digits) return "";
493
+ if (!hasPlus && digits.startsWith("00") && digits.length > 9) {
494
+ hasPlus = true;
495
+ digits = digits.substring(2);
496
+ }
497
+ if (hasPlus) {
498
+ const ccLen = getCountryCodeLength(digits);
499
+ if (ccLen > 0 && digits.length > ccLen && digits[ccLen] === "0") {
500
+ const withoutZero = digits.substring(0, ccLen) + digits.substring(ccLen + 1);
501
+ if (withoutZero.length >= 7 && withoutZero.length <= 15) {
502
+ digits = withoutZero;
503
+ }
504
+ }
505
+ return "+" + digits;
506
+ }
507
+ return "+" + digits;
508
+ }
509
+ function validatePhone(phone) {
510
+ if (!phone || !phone.trim()) {
511
+ return { valid: false, reason: "Phone number is required" };
512
+ }
513
+ const normalized = normalizePhone(phone);
514
+ if (!normalized || normalized === "+") {
515
+ return { valid: false, reason: "Phone number contains no valid digits" };
516
+ }
517
+ const digits = normalized.substring(1);
518
+ if (digits.length < 7) {
519
+ return {
520
+ valid: false,
521
+ reason: `Phone number is too short (${digits.length} digits). International numbers need at least 7 digits including the country code`
522
+ };
523
+ }
524
+ if (digits.length > 15) {
525
+ return {
526
+ valid: false,
527
+ reason: `Phone number is too long (${digits.length} digits). E.164 standard allows at most 15 digits`
528
+ };
529
+ }
530
+ const trimmedInput = phone.trim();
531
+ const hasInternationalPrefix = trimmedInput.startsWith("+") || trimmedInput.startsWith("00") || trimmedInput.replace(/[^\d]/g, "").startsWith("00");
532
+ if (!hasInternationalPrefix) {
533
+ return {
534
+ valid: false,
535
+ reason: "Phone number must include a country code (e.g., +1 for US/Canada, +44 for UK, +33 for France). Use the format: +[country code][number]"
536
+ };
537
+ }
538
+ let detectedCountry;
539
+ for (const { dialCode, code } of SORTED_DIAL_CODES) {
540
+ if (digits.startsWith(dialCode)) {
541
+ detectedCountry = code;
542
+ break;
543
+ }
544
+ }
545
+ if (!detectedCountry) {
546
+ return {
547
+ valid: false,
548
+ reason: "Unrecognized country calling code. Please verify the number includes a valid international dialing code"
549
+ };
550
+ }
551
+ return {
552
+ valid: true,
553
+ normalized,
554
+ countryCode: detectedCountry
555
+ };
556
+ }
557
+ function detectCountry(phone) {
558
+ const normalized = normalizePhone(phone);
559
+ if (!normalized || normalized.length < 2) return null;
560
+ const digits = normalized.substring(1);
561
+ for (const { dialCode, code } of SORTED_DIAL_CODES) {
562
+ if (digits.startsWith(dialCode)) {
563
+ return code;
564
+ }
565
+ }
566
+ return null;
567
+ }
568
+ function formatPhone(phone) {
569
+ const normalized = normalizePhone(phone);
570
+ if (!normalized || normalized.length < 2) return phone;
571
+ const digits = normalized.substring(1);
572
+ const usMatch = digits.match(/^1(\d{3})(\d{3})(\d{4})$/);
573
+ if (usMatch) return `+1 (${usMatch[1]}) ${usMatch[2]}-${usMatch[3]}`;
574
+ const uk1 = digits.match(/^44(\d{4})(\d{6})$/);
575
+ if (uk1) return `+44 ${uk1[1]} ${uk1[2]}`;
576
+ const uk2 = digits.match(/^44(\d{3})(\d{4})(\d{4})$/);
577
+ if (uk2) return `+44 ${uk2[1]} ${uk2[2]} ${uk2[3]}`;
578
+ const fr = digits.match(/^33(\d{1})(\d{2})(\d{2})(\d{2})(\d{2})$/);
579
+ if (fr) return `+33 ${fr[1]} ${fr[2]} ${fr[3]} ${fr[4]} ${fr[5]}`;
580
+ const de1 = digits.match(/^49(\d{3})(\d{7,8})$/);
581
+ if (de1) return `+49 ${de1[1]} ${de1[2]}`;
582
+ const de2 = digits.match(/^49(\d{4})(\d{6,7})$/);
583
+ if (de2) return `+49 ${de2[1]} ${de2[2]}`;
584
+ const it = digits.match(/^39(\d{3})(\d{3})(\d{3,4})$/);
585
+ if (it) return `+39 ${it[1]} ${it[2]} ${it[3]}`;
586
+ const es = digits.match(/^34(\d{3})(\d{3})(\d{3})$/);
587
+ if (es) return `+34 ${es[1]} ${es[2]} ${es[3]}`;
588
+ const nl = digits.match(/^31(\d{1})(\d{4})(\d{4})$/);
589
+ if (nl) return `+31 ${nl[1]} ${nl[2]} ${nl[3]}`;
590
+ const au = digits.match(/^61(\d{3})(\d{3})(\d{3})$/);
591
+ if (au) return `+61 ${au[1]} ${au[2]} ${au[3]}`;
592
+ const ind = digits.match(/^91(\d{5})(\d{5})$/);
593
+ if (ind) return `+91 ${ind[1]} ${ind[2]}`;
594
+ const jp = digits.match(/^81(\d{2})(\d{4})(\d{4})$/);
595
+ if (jp) return `+81 ${jp[1]} ${jp[2]} ${jp[3]}`;
596
+ const cn = digits.match(/^86(\d{3})(\d{4})(\d{4})$/);
597
+ if (cn) return `+86 ${cn[1]} ${cn[2]} ${cn[3]}`;
598
+ const kr = digits.match(/^82(\d{2})(\d{4})(\d{4})$/);
599
+ if (kr) return `+82 ${kr[1]} ${kr[2]} ${kr[3]}`;
600
+ const br = digits.match(/^55(\d{2})(\d{4,5})(\d{4})$/);
601
+ if (br) return `+55 ${br[1]} ${br[2]} ${br[3]}`;
602
+ const mx = digits.match(/^52(\d{3})(\d{3})(\d{4})$/);
603
+ if (mx) return `+52 ${mx[1]} ${mx[2]} ${mx[3]}`;
604
+ const ru = digits.match(/^7(\d{3})(\d{3})(\d{2})(\d{2})$/);
605
+ if (ru) return `+7 ${ru[1]} ${ru[2]}-${ru[3]}-${ru[4]}`;
606
+ const ae = digits.match(/^971(\d{2})(\d{3})(\d{4})$/);
607
+ if (ae) return `+971 ${ae[1]} ${ae[2]} ${ae[3]}`;
608
+ const sa = digits.match(/^966(\d{2})(\d{3})(\d{4})$/);
609
+ if (sa) return `+966 ${sa[1]} ${sa[2]} ${sa[3]}`;
610
+ const za = digits.match(/^27(\d{2})(\d{3})(\d{4})$/);
611
+ if (za) return `+27 ${za[1]} ${za[2]} ${za[3]}`;
612
+ const ng = digits.match(/^234(\d{3})(\d{3})(\d{4})$/);
613
+ if (ng) return `+234 ${ng[1]} ${ng[2]} ${ng[3]}`;
614
+ const ccLen = getCountryCodeLength(digits);
615
+ if (ccLen > 0 && digits.length > ccLen) {
616
+ const cc = digits.substring(0, ccLen);
617
+ const national = digits.substring(ccLen);
618
+ const groups = [];
619
+ let i = 0;
620
+ while (i < national.length) {
621
+ const remaining = national.length - i;
622
+ const chunkSize = remaining > 4 ? remaining % 3 === 0 ? 3 : remaining % 4 === 0 ? 4 : 3 : remaining;
623
+ groups.push(national.substring(i, i + chunkSize));
624
+ i += chunkSize;
625
+ }
626
+ return `+${cc} ${groups.join(" ")}`;
627
+ }
628
+ return normalized;
629
+ }
630
+ function getCountries() {
631
+ return [...COUNTRIES].sort((a, b) => a.name.localeCompare(b.name));
632
+ }
633
+ function getDialCode(countryCode) {
634
+ const country = COUNTRIES.find((c) => c.code === countryCode.toUpperCase());
635
+ return country?.dialCode ?? null;
636
+ }
637
+ function buildPhone(countryCode, nationalNumber) {
638
+ const dialCode = getDialCode(countryCode);
639
+ if (!dialCode) return null;
640
+ const dc = dialCode.replace("+", "");
641
+ let digits = nationalNumber.replace(/[^\d]/g, "");
642
+ if (!digits) return null;
643
+ if (digits.startsWith("0")) {
644
+ digits = digits.substring(1);
645
+ }
646
+ if (digits.startsWith(dc)) {
647
+ return normalizePhone("+" + digits);
648
+ }
649
+ return normalizePhone("+" + dc + digits);
650
+ }
651
+
172
652
  // src/index.ts
173
653
  var TiquoAuthError = class extends Error {
174
654
  constructor(message, code, statusCode) {
@@ -315,14 +795,41 @@ var TiquoAuth = class {
315
795
  }
316
796
  /**
317
797
  * Update the authenticated customer's profile
318
- * Only allows updating the logged-in customer's own data
798
+ * Only allows updating the logged-in customer's own data.
799
+ *
800
+ * Phone numbers are automatically normalized to E.164 format (+digits).
801
+ * For best results, include a country code: "+1 (555) 456-7890" or "+44 7911 123456".
802
+ * Use TiquoPhone.validate() to check before submitting, or TiquoPhone.buildPhone()
803
+ * to construct from a country selector and national number.
319
804
  */
320
805
  async updateProfile(updates) {
321
806
  await this.ensureValidToken();
322
- this.log("Updating customer profile:", updates);
807
+ const normalizedUpdates = { ...updates };
808
+ if (normalizedUpdates.phone !== void 0 && normalizedUpdates.phone !== "") {
809
+ const normalized = normalizePhone(normalizedUpdates.phone);
810
+ const validation = validatePhone(normalizedUpdates.phone);
811
+ if (!validation.valid) {
812
+ this.log("\u26A0\uFE0F Phone validation warning:", validation.reason, "- Original:", normalizedUpdates.phone);
813
+ } else {
814
+ this.log("Phone normalized:", normalizedUpdates.phone, "\u2192", normalized);
815
+ }
816
+ normalizedUpdates.phone = normalized || normalizedUpdates.phone;
817
+ }
818
+ if (normalizedUpdates.phones) {
819
+ normalizedUpdates.phones = normalizedUpdates.phones.map((p) => {
820
+ if (!p.number) return p;
821
+ const normalized = normalizePhone(p.number);
822
+ const validation = validatePhone(p.number);
823
+ if (!validation.valid) {
824
+ this.log("\u26A0\uFE0F Phone validation warning:", validation.reason, "- Original:", p.number);
825
+ }
826
+ return { ...p, number: normalized || p.number };
827
+ });
828
+ }
829
+ this.log("Updating customer profile:", normalizedUpdates);
323
830
  const response = await this.request("/api/client/v1/profile", {
324
831
  method: "PATCH",
325
- body: JSON.stringify(updates)
832
+ body: JSON.stringify(normalizedUpdates)
326
833
  });
327
834
  if (!response.ok) {
328
835
  const error = await response.json().catch(() => ({ error: "Failed to update profile" }));
@@ -940,16 +1447,33 @@ function useTiquoAuth(auth) {
940
1447
  onAuthStateChange: (cb) => auth.onAuthStateChange(cb)
941
1448
  };
942
1449
  }
1450
+ var TiquoPhone = class {
1451
+ };
1452
+ /** Normalize a phone number to E.164 format (+digits). */
1453
+ TiquoPhone.normalize = normalizePhone;
1454
+ /** Validate a phone number with detailed result. */
1455
+ TiquoPhone.validate = validatePhone;
1456
+ /** Detect the country from a phone number's calling code. */
1457
+ TiquoPhone.detectCountry = detectCountry;
1458
+ /** Format a phone number for display using country-specific patterns. */
1459
+ TiquoPhone.format = formatPhone;
1460
+ /** Get the full list of countries with phone info for building UI selectors. */
1461
+ TiquoPhone.getCountries = getCountries;
1462
+ /** Get the dial code for a specific country (e.g. "US" → "+1"). */
1463
+ TiquoPhone.getDialCode = getDialCode;
1464
+ /** Build an E.164 phone number from a country code and national number. */
1465
+ TiquoPhone.buildPhone = buildPhone;
943
1466
  var index_default = TiquoAuth;
944
1467
  // Annotate the CommonJS export names for ESM import in node:
945
1468
  0 && (module.exports = {
946
1469
  TiquoAuth,
947
1470
  TiquoAuthError,
1471
+ TiquoPhone,
948
1472
  addCustomerUserId,
949
1473
  clearCachedEmail,
950
1474
  getCustomerUserIds,
951
1475
  getPrefilledEmailFromCookie,
952
- isClerkAuthenticated,
1476
+ isDashboardSession,
953
1477
  trackCustomerPresence,
954
1478
  useTiquoAuth
955
1479
  });