extractCountryCallingCodeFromInternationalNumberWithoutPlusSign.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import Metadata from '../metadata.js'
  2. import matchesEntirely from './matchesEntirely.js'
  3. import extractNationalNumber from './extractNationalNumber.js'
  4. import checkNumberLength from './checkNumberLength.js'
  5. import getCountryCallingCode from '../getCountryCallingCode.js'
  6. /**
  7. * Sometimes some people incorrectly input international phone numbers
  8. * without the leading `+`. This function corrects such input.
  9. * @param {string} number — Phone number digits.
  10. * @param {string?} country
  11. * @param {string?} callingCode
  12. * @param {object} metadata
  13. * @return {object} `{ countryCallingCode: string?, number: string }`.
  14. */
  15. export default function extractCountryCallingCodeFromInternationalNumberWithoutPlusSign(
  16. number,
  17. country,
  18. callingCode,
  19. metadata
  20. ) {
  21. const countryCallingCode = country ? getCountryCallingCode(country, metadata) : callingCode
  22. if (number.indexOf(countryCallingCode) === 0) {
  23. metadata = new Metadata(metadata)
  24. metadata.selectNumberingPlan(country, callingCode)
  25. const possibleShorterNumber = number.slice(countryCallingCode.length)
  26. const {
  27. nationalNumber: possibleShorterNationalNumber,
  28. } = extractNationalNumber(
  29. possibleShorterNumber,
  30. metadata
  31. )
  32. const {
  33. nationalNumber
  34. } = extractNationalNumber(
  35. number,
  36. metadata
  37. )
  38. // If the number was not valid before but is valid now,
  39. // or if it was too long before, we consider the number
  40. // with the country calling code stripped to be a better result
  41. // and keep that instead.
  42. // For example, in Germany (+49), `49` is a valid area code,
  43. // so if a number starts with `49`, it could be both a valid
  44. // national German number or an international number without
  45. // a leading `+`.
  46. if (
  47. (
  48. !matchesEntirely(nationalNumber, metadata.nationalNumberPattern())
  49. &&
  50. matchesEntirely(possibleShorterNationalNumber, metadata.nationalNumberPattern())
  51. )
  52. ||
  53. checkNumberLength(nationalNumber, metadata) === 'TOO_LONG'
  54. ) {
  55. return {
  56. countryCallingCode,
  57. number: possibleShorterNumber
  58. }
  59. }
  60. }
  61. return { number }
  62. }