extractNationalNumberFromPossiblyIncompleteNumber.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /**
  2. * Strips any national prefix (such as 0, 1) present in a
  3. * (possibly incomplete) number provided.
  4. * "Carrier codes" are only used in Colombia and Brazil,
  5. * and only when dialing within those countries from a mobile phone to a fixed line number.
  6. * Sometimes it won't actually strip national prefix
  7. * and will instead prepend some digits to the `number`:
  8. * for example, when number `2345678` is passed with `VI` country selected,
  9. * it will return `{ number: "3402345678" }`, because `340` area code is prepended.
  10. * @param {string} number — National number digits.
  11. * @param {object} metadata — Metadata with country selected.
  12. * @return {object} `{ nationalNumber: string, nationalPrefix: string? carrierCode: string? }`. Even if a national prefix was extracted, it's not necessarily present in the returned object, so don't rely on its presence in the returned object in order to find out whether a national prefix has been extracted or not.
  13. */
  14. export default function extractNationalNumberFromPossiblyIncompleteNumber(number, metadata) {
  15. if (number && metadata.numberingPlan.nationalPrefixForParsing()) {
  16. // See METADATA.md for the description of
  17. // `national_prefix_for_parsing` and `national_prefix_transform_rule`.
  18. // Attempt to parse the first digits as a national prefix.
  19. var prefixPattern = new RegExp('^(?:' + metadata.numberingPlan.nationalPrefixForParsing() + ')');
  20. var prefixMatch = prefixPattern.exec(number);
  21. if (prefixMatch) {
  22. var nationalNumber;
  23. var carrierCode; // https://gitlab.com/catamphetamine/libphonenumber-js/-/blob/master/METADATA.md#national_prefix_for_parsing--national_prefix_transform_rule
  24. // If a `national_prefix_for_parsing` has any "capturing groups"
  25. // then it means that the national (significant) number is equal to
  26. // those "capturing groups" transformed via `national_prefix_transform_rule`,
  27. // and nothing could be said about the actual national prefix:
  28. // what is it and was it even there.
  29. // If a `national_prefix_for_parsing` doesn't have any "capturing groups",
  30. // then everything it matches is a national prefix.
  31. // To determine whether `national_prefix_for_parsing` matched any
  32. // "capturing groups", the value of the result of calling `.exec()`
  33. // is looked at, and if it has non-undefined values where there're
  34. // "capturing groups" in the regular expression, then it means
  35. // that "capturing groups" have been matched.
  36. // It's not possible to tell whether there'll be any "capturing gropus"
  37. // before the matching process, because a `national_prefix_for_parsing`
  38. // could exhibit both behaviors.
  39. var capturedGroupsCount = prefixMatch.length - 1;
  40. var hasCapturedGroups = capturedGroupsCount > 0 && prefixMatch[capturedGroupsCount];
  41. if (metadata.nationalPrefixTransformRule() && hasCapturedGroups) {
  42. nationalNumber = number.replace(prefixPattern, metadata.nationalPrefixTransformRule()); // If there's more than one captured group,
  43. // then carrier code is the second one.
  44. if (capturedGroupsCount > 1) {
  45. carrierCode = prefixMatch[1];
  46. }
  47. } // If there're no "capturing groups",
  48. // or if there're "capturing groups" but no
  49. // `national_prefix_transform_rule`,
  50. // then just strip the national prefix from the number,
  51. // and possibly a carrier code.
  52. // Seems like there could be more.
  53. else {
  54. // `prefixBeforeNationalNumber` is the whole substring matched by
  55. // the `national_prefix_for_parsing` regular expression.
  56. // There seem to be no guarantees that it's just a national prefix.
  57. // For example, if there's a carrier code, it's gonna be a
  58. // part of `prefixBeforeNationalNumber` too.
  59. var prefixBeforeNationalNumber = prefixMatch[0];
  60. nationalNumber = number.slice(prefixBeforeNationalNumber.length); // If there's at least one captured group,
  61. // then carrier code is the first one.
  62. if (hasCapturedGroups) {
  63. carrierCode = prefixMatch[1];
  64. }
  65. } // Tries to guess whether a national prefix was present in the input.
  66. // This is not something copy-pasted from Google's library:
  67. // they don't seem to have an equivalent for that.
  68. // So this isn't an "officially approved" way of doing something like that.
  69. // But since there seems no other existing method, this library uses it.
  70. var nationalPrefix;
  71. if (hasCapturedGroups) {
  72. var possiblePositionOfTheFirstCapturedGroup = number.indexOf(prefixMatch[1]);
  73. var possibleNationalPrefix = number.slice(0, possiblePositionOfTheFirstCapturedGroup); // Example: an Argentinian (AR) phone number `0111523456789`.
  74. // `prefixMatch[0]` is `01115`, and `$1` is `11`,
  75. // and the rest of the phone number is `23456789`.
  76. // The national number is transformed via `9$1` to `91123456789`.
  77. // National prefix `0` is detected being present at the start.
  78. // if (possibleNationalPrefix.indexOf(metadata.numberingPlan.nationalPrefix()) === 0) {
  79. if (possibleNationalPrefix === metadata.numberingPlan.nationalPrefix()) {
  80. nationalPrefix = metadata.numberingPlan.nationalPrefix();
  81. }
  82. } else {
  83. nationalPrefix = prefixMatch[0];
  84. }
  85. return {
  86. nationalNumber: nationalNumber,
  87. nationalPrefix: nationalPrefix,
  88. carrierCode: carrierCode
  89. };
  90. }
  91. }
  92. return {
  93. nationalNumber: number
  94. };
  95. }
  96. //# sourceMappingURL=extractNationalNumberFromPossiblyIncompleteNumber.js.map