15815213711
2024-08-26 67b8b6731811983447e053d4396b3708c14dfe3c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import extractNationalNumberFromPossiblyIncompleteNumber from './extractNationalNumberFromPossiblyIncompleteNumber.js'
import matchesEntirely from './matchesEntirely.js'
import checkNumberLength from './checkNumberLength.js'
 
/**
 * Strips national prefix and carrier code from a complete phone number.
 * The difference from the non-"FromCompleteNumber" function is that
 * it won't extract national prefix if the resultant number is too short
 * to be a complete number for the selected phone numbering plan.
 * @param  {string} number — Complete phone number digits.
 * @param  {Metadata} metadata — Metadata with a phone numbering plan selected.
 * @return {object} `{ nationalNumber: string, carrierCode: string? }`.
 */
export default function extractNationalNumber(number, metadata) {
    // Parsing national prefixes and carrier codes
    // is only required for local phone numbers
    // but some people don't understand that
    // and sometimes write international phone numbers
    // with national prefixes (or maybe even carrier codes).
    // http://ucken.blogspot.ru/2016/03/trunk-prefixes-in-skype4b.html
    // Google's original library forgives such mistakes
    // and so does this library, because it has been requested:
    // https://github.com/catamphetamine/libphonenumber-js/issues/127
    const {
        carrierCode,
        nationalNumber
    } = extractNationalNumberFromPossiblyIncompleteNumber(
        number,
        metadata
    )
 
    if (nationalNumber !== number) {
        if (!shouldHaveExtractedNationalPrefix(number, nationalNumber, metadata)) {
            // Don't strip the national prefix.
            return { nationalNumber: number }
        }
        // Check the national (significant) number length after extracting national prefix and carrier code.
        // Legacy generated metadata (before `1.0.18`) didn't support the "possible lengths" feature.
        if (metadata.possibleLengths()) {
            // The number remaining after stripping the national prefix and carrier code
            // should be long enough to have a possible length for the country.
            // Otherwise, don't strip the national prefix and carrier code,
            // since the original number could be a valid number.
            // This check has been copy-pasted "as is" from Google's original library:
            // https://github.com/google/libphonenumber/blob/876268eb1ad6cdc1b7b5bef17fc5e43052702d57/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java#L3236-L3250
            // It doesn't check for the "possibility" of the original `number`.
            // I guess it's fine not checking that one. It works as is anyway.
            if (!isPossibleIncompleteNationalNumber(nationalNumber, metadata)) {
                // Don't strip the national prefix.
                return { nationalNumber: number }
            }
        }
    }
 
    return { nationalNumber, carrierCode }
}
 
// In some countries, the same digit could be a national prefix
// or a leading digit of a valid phone number.
// For example, in Russia, national prefix is `8`,
// and also `800 555 35 35` is a valid number
// in which `8` is not a national prefix, but the first digit
// of a national (significant) number.
// Same's with Belarus:
// `82004910060` is a valid national (significant) number,
// but `2004910060` is not.
// To support such cases (to prevent the code from always stripping
// national prefix), a condition is imposed: a national prefix
// is not extracted when the original number is "viable" and the
// resultant number is not, a "viable" national number being the one
// that matches `national_number_pattern`.
function shouldHaveExtractedNationalPrefix(nationalNumberBefore, nationalNumberAfter, metadata) {
    // The equivalent in Google's code is:
    // https://github.com/google/libphonenumber/blob/e326fa1fc4283bb05eb35cb3c15c18f98a31af33/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java#L2969-L3004
    if (matchesEntirely(nationalNumberBefore, metadata.nationalNumberPattern()) &&
        !matchesEntirely(nationalNumberAfter, metadata.nationalNumberPattern())) {
        return false
    }
    // This "is possible" national number (length) check has been commented out
    // because it's superceded by the (effectively) same check done in the
    // `extractNationalNumber()` function after it calls `shouldHaveExtractedNationalPrefix()`.
    // In other words, why run the same check twice if it could only be run once.
    // // Check the national (significant) number length after extracting national prefix and carrier code.
    // // Fixes a minor "weird behavior" bug: https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/57
    // // (Legacy generated metadata (before `1.0.18`) didn't support the "possible lengths" feature).
    // if (metadata.possibleLengths()) {
    //     if (isPossibleIncompleteNationalNumber(nationalNumberBefore, metadata) &&
    //         !isPossibleIncompleteNationalNumber(nationalNumberAfter, metadata)) {
    //         return false
    //     }
    // }
    return true
}
 
function isPossibleIncompleteNationalNumber(nationalNumber, metadata) {
    switch (checkNumberLength(nationalNumber, metadata)) {
        case 'TOO_SHORT':
        case 'INVALID_LENGTH':
        // This library ignores "local-only" phone numbers (for simplicity).
        // See the readme for more info on what are "local-only" phone numbers.
        // case 'IS_POSSIBLE_LOCAL_ONLY':
            return false
        default:
            return true
    }
}