1 | import checkNumberLength from './helpers/checkNumberLength'
|
2 | import parseDigits from './helpers/parseDigits'
|
3 | import formatNationalNumberUsingFormat from './helpers/formatNationalNumberUsingFormat'
|
4 |
|
5 | export default function formatCompleteNumber(state, format, {
|
6 | metadata,
|
7 | shouldTryNationalPrefixFormattingRule,
|
8 | getSeparatorAfterNationalPrefix
|
9 | }) {
|
10 | const matcher = new RegExp(`^(?:${format.pattern()})$`)
|
11 | if (matcher.test(state.nationalSignificantNumber)) {
|
12 | return formatNationalNumberWithAndWithoutNationalPrefixFormattingRule(
|
13 | state,
|
14 | format,
|
15 | {
|
16 | metadata,
|
17 | shouldTryNationalPrefixFormattingRule,
|
18 | getSeparatorAfterNationalPrefix
|
19 | }
|
20 | )
|
21 | }
|
22 | }
|
23 |
|
24 | export function canFormatCompleteNumber(nationalSignificantNumber, metadata) {
|
25 | return checkNumberLength(nationalSignificantNumber, metadata) === 'IS_POSSIBLE'
|
26 | }
|
27 |
|
28 | function formatNationalNumberWithAndWithoutNationalPrefixFormattingRule(state, format, {
|
29 | metadata,
|
30 | shouldTryNationalPrefixFormattingRule,
|
31 | getSeparatorAfterNationalPrefix
|
32 | }) {
|
33 | // `format` has already been checked for `nationalPrefix` requirement.
|
34 |
|
35 | const {
|
36 | nationalSignificantNumber,
|
37 | international,
|
38 | nationalPrefix,
|
39 | carrierCode
|
40 | } = state
|
41 |
|
42 | // Format the number with using `national_prefix_formatting_rule`.
|
43 | // If the resulting formatted number is a valid formatted number, then return it.
|
44 | //
|
45 | // Google's AsYouType formatter is different in a way that it doesn't try
|
46 | // to format using the "national prefix formatting rule", and instead it
|
47 | // simply prepends a national prefix followed by a " " character.
|
48 | // This code does that too, but as a fallback.
|
49 | // The reason is that "national prefix formatting rule" may use parentheses,
|
50 | // which wouldn't be included has it used the simpler Google's way.
|
51 | //
|
52 | if (shouldTryNationalPrefixFormattingRule(format)) {
|
53 | const formattedNumber = formatNationalNumber(state, format, {
|
54 | useNationalPrefixFormattingRule: true,
|
55 | getSeparatorAfterNationalPrefix,
|
56 | metadata
|
57 | })
|
58 | if (formattedNumber) {
|
59 | return formattedNumber
|
60 | }
|
61 | }
|
62 |
|
63 | // Format the number without using `national_prefix_formatting_rule`.
|
64 | return formatNationalNumber(state, format, {
|
65 | useNationalPrefixFormattingRule: false,
|
66 | getSeparatorAfterNationalPrefix,
|
67 | metadata
|
68 | })
|
69 | }
|
70 |
|
71 | function formatNationalNumber(state, format, {
|
72 | metadata,
|
73 | useNationalPrefixFormattingRule,
|
74 | getSeparatorAfterNationalPrefix
|
75 | }) {
|
76 | let formattedNationalNumber = formatNationalNumberUsingFormat(
|
77 | state.nationalSignificantNumber,
|
78 | format,
|
79 | {
|
80 | carrierCode: state.carrierCode,
|
81 | useInternationalFormat: state.international,
|
82 | withNationalPrefix: useNationalPrefixFormattingRule,
|
83 | metadata
|
84 | }
|
85 | )
|
86 | if (!useNationalPrefixFormattingRule) {
|
87 | if (state.nationalPrefix) {
|
88 | // If a national prefix was extracted, then just prepend it,
|
89 | // followed by a " " character.
|
90 | formattedNationalNumber = state.nationalPrefix +
|
91 | getSeparatorAfterNationalPrefix(format) +
|
92 | formattedNationalNumber
|
93 | } else if (state.complexPrefixBeforeNationalSignificantNumber) {
|
94 | formattedNationalNumber = state.complexPrefixBeforeNationalSignificantNumber +
|
95 | ' ' +
|
96 | formattedNationalNumber
|
97 | }
|
98 | }
|
99 | if (isValidFormattedNationalNumber(formattedNationalNumber, state)) {
|
100 | return formattedNationalNumber
|
101 | }
|
102 | }
|
103 |
|
104 | // Check that the formatted phone number contains exactly
|
105 | // the same digits that have been input by the user.
|
106 | // For example, when "0111523456789" is input for `AR` country,
|
107 | // the extracted `this.nationalSignificantNumber` is "91123456789",
|
108 | // which means that the national part of `this.digits` isn't simply equal to
|
109 | // `this.nationalPrefix` + `this.nationalSignificantNumber`.
|
110 | //
|
111 | // Also, a `format` can add extra digits to the `this.nationalSignificantNumber`
|
112 | // being formatted via `metadata[country].national_prefix_transform_rule`.
|
113 | // For example, for `VI` country, it prepends `340` to the national number,
|
114 | // and if this check hasn't been implemented, then there would be a bug
|
115 | // when `340` "area coude" is "duplicated" during input for `VI` country:
|
116 | // https://github.com/catamphetamine/libphonenumber-js/issues/318
|
117 | //
|
118 | // So, all these "gotchas" are filtered out.
|
119 | //
|
120 | // In the original Google's code, the comments say:
|
121 | // "Check that we didn't remove nor add any extra digits when we matched
|
122 | // this formatting pattern. This usually happens after we entered the last
|
123 | // digit during AYTF. Eg: In case of MX, we swallow mobile token (1) when
|
124 | // formatted but AYTF should retain all the number entered and not change
|
125 | // in order to match a format (of same leading digits and length) display
|
126 | // in that way."
|
127 | // "If it's the same (i.e entered number and format is same), then it's
|
128 | // safe to return this in formatted number as nothing is lost / added."
|
129 | // Otherwise, don't use this format.
|
130 | // https://github.com/google/libphonenumber/commit/3e7c1f04f5e7200f87fb131e6f85c6e99d60f510#diff-9149457fa9f5d608a11bb975c6ef4bc5
|
131 | // https://github.com/google/libphonenumber/commit/3ac88c7106e7dcb553bcc794b15f19185928a1c6#diff-2dcb77e833422ee304da348b905cde0b
|
132 | //
|
133 | function isValidFormattedNationalNumber(formattedNationalNumber, state) {
|
134 | return parseDigits(formattedNationalNumber) === state.getNationalDigits()
|
135 | } |
\ | No newline at end of file |