2025-10-03 14:26:55 +09:00
|
|
|
/**
|
|
|
|
|
* Toolkit - Phone Number Formatting
|
|
|
|
|
*
|
|
|
|
|
* Utilities for formatting phone numbers.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Format a phone number for display
|
|
|
|
|
* Handles basic international formats
|
|
|
|
|
*/
|
|
|
|
|
export function formatPhoneNumber(phone: string): string {
|
|
|
|
|
// Remove all non-digit characters
|
|
|
|
|
const digits = phone.replace(/\D/g, "");
|
|
|
|
|
|
|
|
|
|
// Handle common formats
|
|
|
|
|
if (digits.length === 10) {
|
|
|
|
|
// US/Canada format: (123) 456-7890
|
|
|
|
|
return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
|
|
|
|
|
} else if (digits.length === 11 && digits.startsWith("1")) {
|
|
|
|
|
// US/Canada with country code: +1 (123) 456-7890
|
|
|
|
|
return `+1 (${digits.slice(1, 4)}) ${digits.slice(4, 7)}-${digits.slice(7)}`;
|
|
|
|
|
} else if (digits.length >= 10) {
|
|
|
|
|
// International format: +XX XXX XXX XXXX
|
|
|
|
|
const countryCode = digits.slice(0, digits.length - 10);
|
|
|
|
|
const areaCode = digits.slice(-10, -7);
|
|
|
|
|
const localPrefix = digits.slice(-7, -4);
|
|
|
|
|
const localNumber = digits.slice(-4);
|
|
|
|
|
return `+${countryCode} ${areaCode} ${localPrefix} ${localNumber}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return original if no known format matches
|
|
|
|
|
return phone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Normalize a phone number to E.164 format (+XXXXXXXXXXX)
|
|
|
|
|
*/
|
|
|
|
|
export function normalizePhoneNumber(phone: string, defaultCountryCode = "1"): string {
|
|
|
|
|
const digits = phone.replace(/\D/g, "");
|
|
|
|
|
|
|
|
|
|
// If already has country code, return with +
|
|
|
|
|
if (digits.length >= 10 && !digits.startsWith(defaultCountryCode)) {
|
|
|
|
|
return `+${digits}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add default country code
|
|
|
|
|
return `+${defaultCountryCode}${digits}`;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 18:56:38 +09:00
|
|
|
/**
|
|
|
|
|
* Format phone number for WHMCS API
|
|
|
|
|
* WHMCS accepts format: +CC.NNNNNNNNNN (country code dot number)
|
|
|
|
|
* Example: +81.335601006 or +1.2125551234
|
|
|
|
|
*/
|
|
|
|
|
export function formatPhoneForWhmcs(phone: string): string {
|
|
|
|
|
// Remove all non-digit characters except leading +
|
|
|
|
|
const hasPlus = phone.startsWith("+");
|
|
|
|
|
const digits = phone.replace(/\D/g, "");
|
|
|
|
|
|
|
|
|
|
if (digits.length === 0) {
|
|
|
|
|
return phone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For Japanese numbers (starts with 81), format as +81.XXXXXXXXX
|
|
|
|
|
if (digits.startsWith("81") && digits.length >= 11) {
|
|
|
|
|
return `+81.${digits.slice(2)}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For US/Canada numbers (10 digits or 11 starting with 1)
|
|
|
|
|
if (digits.length === 10) {
|
|
|
|
|
return `+1.${digits}`;
|
|
|
|
|
}
|
|
|
|
|
if (digits.length === 11 && digits.startsWith("1")) {
|
|
|
|
|
return `+1.${digits.slice(1)}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For other international numbers, assume first 1-3 digits are country code
|
|
|
|
|
// Use dot separator after country code
|
|
|
|
|
if (digits.length >= 10) {
|
|
|
|
|
// Try to detect country code length (most are 1-3 digits)
|
|
|
|
|
const numberWithoutCountry = digits.length - 10;
|
|
|
|
|
const countryCodeLength = Math.min(Math.max(numberWithoutCountry, 1), 3);
|
|
|
|
|
const countryCode = digits.slice(0, countryCodeLength);
|
|
|
|
|
const localNumber = digits.slice(countryCodeLength);
|
|
|
|
|
return `+${countryCode}.${localNumber}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return with + prefix if it had one, otherwise as-is
|
|
|
|
|
return hasPlus ? `+${digits}` : digits;
|
|
|
|
|
}
|
|
|
|
|
|