You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					106 lines
				
				5.2 KiB
			
		
		
			
		
	
	
					106 lines
				
				5.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								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
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |