international-phone-validator
Version:
A comprehensive phone number validation and formatting library for international phone numbers
2 lines (1 loc) • 8.93 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PhoneValidator=t()}(this,function(){"use strict";class e{constructor(){this.countryCodes={US:{code:"1",pattern:/^(\+?1)?[\s\-\.]?(\([0-9]{3}\)|[0-9]{3})[\s\-\.]?[0-9]{3}[\s\-\.]?[0-9]{4}$/,length:10,format:"+1 (XXX) XXX-XXXX"},CA:{code:"1",pattern:/^(\+?1)?[\s\-\.]?(\([0-9]{3}\)|[0-9]{3})[\s\-\.]?[0-9]{3}[\s\-\.]?[0-9]{4}$/,length:10,format:"+1 (XXX) XXX-XXXX"},UK:{code:"44",pattern:/^(\+?44)?[\s\-\.]?[0-9]{10,11}$/,length:10,format:"+44 XXXX XXX XXX"},DE:{code:"49",pattern:/^(\+?49)?[\s\-\.]?[0-9]{10,12}$/,length:11,format:"+49 XXX XXXXXXXX"},FR:{code:"33",pattern:/^(\+?33)?[\s\-\.]?[0-9]{9,10}$/,length:10,format:"+33 X XX XX XX XX"},IT:{code:"39",pattern:/^(\+?39)?[\s\-\.]?[0-9]{10,11}$/,length:10,format:"+39 XXX XXX XXXX"},ES:{code:"34",pattern:/^(\+?34)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+34 XXX XXX XXX"},NL:{code:"31",pattern:/^(\+?31)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+31 X XXXX XXXX"},AU:{code:"61",pattern:/^(\+?61)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+61 XXX XXX XXX"},IN:{code:"91",pattern:/^(\+?91)?[\s\-\.]?[0-9]{10}$/,length:10,format:"+91 XXXXX XXXXX"},CN:{code:"86",pattern:/^(\+?86)?[\s\-\.]?[0-9]{11}$/,length:11,format:"+86 XXX XXXX XXXX"},JP:{code:"81",pattern:/^(\+?81)?[\s\-\.]?[0-9]{10,11}$/,length:11,format:"+81 XXX XXXX XXXX"},KR:{code:"82",pattern:/^(\+?82)?[\s\-\.]?[0-9]{9,10}$/,length:10,format:"+82 XX XXXX XXXX"},BR:{code:"55",pattern:/^(\+?55)?[\s\-\.]?[0-9]{10,11}$/,length:11,format:"+55 XX XXXXX-XXXX"},MX:{code:"52",pattern:/^(\+?52)?[\s\-\.]?[0-9]{10}$/,length:10,format:"+52 XXX XXX XXXX"},SL:{code:"232",pattern:/^(\+?232)?[\s\-\.]?[0-9]{8}$/,length:8,format:"+232 XX XXX XXX"},NG:{code:"234",pattern:/^(\+?234)?[\s\-\.]?[0-9]{10}$/,length:10,format:"+234 XXX XXX XXXX"},GH:{code:"233",pattern:/^(\+?233)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+233 XX XXX XXXX"},LR:{code:"231",pattern:/^(\+?231)?[\s\-\.]?[0-9]{7,8}$/,length:8,format:"+231 XX XXX XXX"},GN:{code:"224",pattern:/^(\+?224)?[\s\-\.]?[0-9]{8,9}$/,length:9,format:"+224 XXX XXX XXX"},CI:{code:"225",pattern:/^(\+?225)?[\s\-\.]?[0-9]{8}$/,length:8,format:"+225 XX XX XX XX"},SN:{code:"221",pattern:/^(\+?221)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+221 XX XXX XX XX"},ML:{code:"223",pattern:/^(\+?223)?[\s\-\.]?[0-9]{8}$/,length:8,format:"+223 XX XX XX XX"},BF:{code:"226",pattern:/^(\+?226)?[\s\-\.]?[0-9]{8}$/,length:8,format:"+226 XX XX XX XX"},GW:{code:"245",pattern:/^(\+?245)?[\s\-\.]?[0-9]{7}$/,length:7,format:"+245 XXX XXXX"},KE:{code:"254",pattern:/^(\+?254)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+254 XXX XXX XXX"},TZ:{code:"255",pattern:/^(\+?255)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+255 XXX XXX XXX"},UG:{code:"256",pattern:/^(\+?256)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+256 XXX XXX XXX"},RW:{code:"250",pattern:/^(\+?250)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+250 XXX XXX XXX"},ET:{code:"251",pattern:/^(\+?251)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+251 XXX XXX XXX"},ZA:{code:"27",pattern:/^(\+?27)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+27 XX XXX XXXX"},ZW:{code:"263",pattern:/^(\+?263)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+263 XX XXX XXXX"},BW:{code:"267",pattern:/^(\+?267)?[\s\-\.]?[0-9]{8}$/,length:8,format:"+267 XX XXX XXX"},ZM:{code:"260",pattern:/^(\+?260)?[\s\-\.]?[0-9]{9}$/,length:9,format:"+260 XX XXX XXXX"}}}clean(e){return e&&"string"==typeof e?e.replace(/[^\d+]/g,""):""}detectCountry(e){const t=this.clean(e);if(t.startsWith("+"))for(const[e,X]of Object.entries(this.countryCodes))if(t.startsWith(`+${X.code}`)){const n=t.substring(`+${X.code}`.length);if(n.length===X.length||"UK"===e&&n.length>=10&&n.length<=11||"DE"===e&&n.length>=10&&n.length<=12||"BR"===e&&n.length>=10&&n.length<=11)return e}for(const[e,X]of Object.entries(this.countryCodes))if(t.startsWith(X.code)){const n=t.substring(X.code.length);if(n.length===X.length||"UK"===e&&n.length>=10&&n.length<=11||"DE"===e&&n.length>=10&&n.length<=12||"BR"===e&&n.length>=10&&n.length<=11)return e}return null}validate(e,t=null){if(!e)return{valid:!1,error:"Phone number is required"};const X=this.clean(e);if(!t&&!(t=this.detectCountry(e)))return{valid:!1,error:"Could not detect country. Please provide country code or use international format."};const n=t.toUpperCase();if(!this.countryCodes[n])return{valid:!1,error:`Country ${t} is not supported`};const s=this.countryCodes[n],r=e.replace(/[^\d]/g,"");let a=!1,c="";if(r.startsWith(s.code)){const e=r.substring(s.code.length);c=e,a="UK"===n?10===e.length||11===e.length:"DE"===n?e.length>=10&&e.length<=12:"BR"===n?10===e.length||11===e.length:"LR"===n?7===e.length||8===e.length:"GN"===n?8===e.length||9===e.length:e.length===s.length}else c=r,r.startsWith("0")&&r.length>s.length&&(c=r.substring(1)),a="UK"===n?10===c.length||11===c.length:"DE"===n?c.length>=10&&c.length<=12:"BR"===n?10===c.length||11===c.length:"LR"===n?7===c.length||8===c.length:"GN"===n?8===c.length||9===c.length:c.length===s.length;return{valid:a,country:n,cleaned:X,formatted:a?this.format(e,t):null,nationalFormat:a?this.formatNational(e,t):null,internationalFormat:a?this.formatInternational(e,t):null,error:a?null:"Invalid phone number format"}}formatInternational(e,t){if(!e||!t)return e||"";const X=this.clean(e),n=t.toUpperCase(),s=this.countryCodes[n];if(!s)return e;let r=X;switch(r.startsWith(`+${s.code}`)?r=r.substring(`+${s.code}`.length):r.startsWith(s.code)&&(r=r.substring(s.code.length)),r.startsWith("0")&&(r=r.substring(1)),n){case"US":case"CA":if(10===r.length)return`+${s.code} (${r.slice(0,3)}) ${r.slice(3,6)}-${r.slice(6)}`;break;case"UK":return`+${s.code} ${r.slice(0,4)} ${r.slice(4,7)} ${r.slice(7)}`;case"DE":case"GW":return`+${s.code} ${r.slice(0,3)} ${r.slice(3)}`;case"FR":if(9===r.length)return`+${s.code} ${r.slice(0,1)} ${r.slice(1,3)} ${r.slice(3,5)} ${r.slice(5,7)} ${r.slice(7)}`;break;case"IN":return`+${s.code} ${r.slice(0,5)} ${r.slice(5)}`;case"BR":if(11===r.length)return`+${s.code} ${r.slice(0,2)} ${r.slice(2,7)}-${r.slice(7)}`;break;case"SL":case"GH":case"LR":case"ZA":case"ZW":case"BW":case"ZM":return`+${s.code} ${r.slice(0,2)} ${r.slice(2,5)} ${r.slice(5)}`;case"NG":case"GN":case"KE":case"TZ":case"UG":case"RW":case"ET":return`+${s.code} ${r.slice(0,3)} ${r.slice(3,6)} ${r.slice(6)}`;case"CI":case"ML":case"BF":return`+${s.code} ${r.slice(0,2)} ${r.slice(2,4)} ${r.slice(4,6)} ${r.slice(6)}`;case"SN":return`+${s.code} ${r.slice(0,2)} ${r.slice(2,5)} ${r.slice(5,7)} ${r.slice(7)}`;default:return`+${s.code} ${r}`}return`+${s.code} ${r}`}formatNational(e,t){if(!e||!t)return e||"";const X=this.clean(e),n=t.toUpperCase(),s=this.countryCodes[n];if(!s)return e;let r=X;switch(r.startsWith(`+${s.code}`)?r=r.substring(`+${s.code}`.length):r.startsWith(s.code)&&(r=r.substring(s.code.length)),r.startsWith("0")&&(r=r.substring(1)),n){case"US":case"CA":if(10===r.length)return`(${r.slice(0,3)}) ${r.slice(3,6)}-${r.slice(6)}`;break;case"UK":return`0${r.slice(0,4)} ${r.slice(4,7)} ${r.slice(7)}`;case"DE":return`0${r.slice(0,3)} ${r.slice(3)}`;case"FR":if(9===r.length)return`0${r.slice(0,1)} ${r.slice(1,3)} ${r.slice(3,5)} ${r.slice(5,7)} ${r.slice(7)}`;break;case"SL":case"GH":case"ZA":return`0${r.slice(0,2)} ${r.slice(2,5)} ${r.slice(5)}`;case"NG":case"KE":case"TZ":case"UG":case"RW":case"ET":return`0${r.slice(0,3)} ${r.slice(3,6)} ${r.slice(6)}`;case"LR":default:return r;case"GN":return r.slice(0,3)+" "+r.slice(3,6)+" "+r.slice(6);case"CI":case"ML":case"BF":return`${r.slice(0,2)} ${r.slice(2,4)} ${r.slice(4,6)} ${r.slice(6)}`;case"SN":return`${r.slice(0,2)} ${r.slice(2,5)} ${r.slice(5,7)} ${r.slice(7)}`;case"GW":return r.slice(0,3)+" "+r.slice(3);case"ZW":case"BW":case"ZM":return r.slice(0,2)+" "+r.slice(2,5)+" "+r.slice(5)}return r}format(e,t){return this.formatInternational(e,t)}getSupportedCountries(){return Object.keys(this.countryCodes).map(e=>({code:e,name:this.getCountryName(e),callingCode:this.countryCodes[e].code,format:this.countryCodes[e].format}))}getCountryName(e){return{US:"United States",CA:"Canada",UK:"United Kingdom",DE:"Germany",FR:"France",IT:"Italy",ES:"Spain",NL:"Netherlands",AU:"Australia",IN:"India",CN:"China",JP:"Japan",KR:"South Korea",BR:"Brazil",MX:"Mexico",SL:"Sierra Leone",NG:"Nigeria",GH:"Ghana",LR:"Liberia",GN:"Guinea",CI:"Côte d'Ivoire",SN:"Senegal",ML:"Mali",BF:"Burkina Faso",GW:"Guinea-Bissau",KE:"Kenya",TZ:"Tanzania",UG:"Uganda",RW:"Rwanda",ET:"Ethiopia",ZA:"South Africa",ZW:"Zimbabwe",BW:"Botswana",ZM:"Zambia"}[e]||e}validateBatch(e){return e.map(e=>"string"==typeof e?this.validate(e):e&&"object"==typeof e&&e.phone?this.validate(e.phone,e.country):{valid:!1,error:"Invalid input format"})}}return"undefined"!=typeof module&&module.exports?module.exports=e:"function"==typeof define&&define.amd?define([],function(){return e}):"undefined"!=typeof window&&(window.PhoneValidator=e),e});