UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

109 lines (97 loc) 3.55 kB
let phoneUtil: any = null; export const getPhoneUtil = async () => { if (!phoneUtil) { const result = await import(/* webpackChunkName: "phone-util" */ 'google-libphonenumber'); const PhoneNumberUtil = (result.default || result)?.PhoneNumberUtil; if (!PhoneNumberUtil) { throw new Error('PhoneNumberUtil not found'); } phoneUtil = PhoneNumberUtil.getInstance(); } return phoneUtil; }; export const validatePhoneNumber = async (phoneNumber: string) => { if (!phoneNumber) return true; try { let util: any = null; try { util = await getPhoneUtil(); } catch (err) { const pattern = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/im; return pattern.test(phoneNumber); } const parsed = util.parseAndKeepRawInput(phoneNumber); return util.isValidNumber(parsed); } catch (err) { console.error('Phone validation error:', err); return false; } }; /** * Format a phone number to international format * @param phoneNumber The original phone number * @param defaultCountry Default country code (ISO 3166-1 alpha-2) * @returns Formatted phone number */ export const formatPhone = (phoneNumber: string | undefined, defaultCountry = 'US') => { if (!phoneNumber || phoneNumber.trim() === '') { return ''; } // Remove all non-digit characters (preserve plus sign) const cleanedNumber = phoneNumber.replace(/[^\d+]/g, ''); // If already in international format (starting with +), return cleaned number if (cleanedNumber.startsWith('+')) { return cleanedNumber; } // Country code mapping const COUNTRY_CODES: Record<string, string> = { US: '1', // United States CA: '1', // Canada CN: '86', // China HK: '852', // Hong Kong IN: '91', // India UK: '44', // United Kingdom GB: '44', // United Kingdom JP: '81', // Japan KR: '82', // South Korea AU: '61', // Australia DE: '49', // Germany FR: '33', // France IT: '39', // Italy ES: '34', // Spain BR: '55', // Brazil RU: '7', // Russia MX: '52', // Mexico SG: '65', // Singapore AE: '971', // UAE }; // Country-specific patterns const COUNTRY_PATTERNS: [RegExp, string][] = [ [/^1[3-9]\d{9}$/, '86'], // China mobile: 11 digits, starts with 1 [/^\d{10}$/, '1'], // US/Canada: 10 digits [/^[6-9]\d{9}$/, '91'], // India: 10 digits, starts with 6-9 [/^0[1-9]\d{8,9}$/, '81'], // Japan: 10-11 digits, starts with 0 [/^07\d{9}$/, '44'], // UK mobile: 11 digits, starts with 07 [/^04\d{8}$/, '61'], // Australia mobile: 10 digits, starts with 04 [/^01[0-9]\d{7,8}$/, '82'], // Korea mobile: 10-11 digits, starts with 01 [/^[0-9]\d{8}$/, '86'], // China landline: 9 digits ]; // Remove leading zero (common in many countries) let numberToFormat = cleanedNumber; if (numberToFormat.startsWith('0')) { numberToFormat = numberToFormat.substring(1); } // Try to match with country-specific patterns for (const [pattern, countryCode] of COUNTRY_PATTERNS) { if (pattern.test(cleanedNumber)) { // For numbers starting with 0 that need the zero removed if (cleanedNumber.startsWith('0') && !['1', '86'].includes(countryCode)) { return `+${countryCode}${cleanedNumber.substring(1)}`; } return `+${countryCode}${cleanedNumber}`; } } // If no pattern matched, use default country code const countryCode = COUNTRY_CODES[defaultCountry.toUpperCase()] || defaultCountry; return `+${countryCode}${numberToFormat}`; };