UNPKG

libphonenumber-js

Version:

A simpler (and smaller) rewrite of Google Android's popular libphonenumber library

227 lines (188 loc) 7.7 kB
import _getIterator from 'babel-runtime/core-js/get-iterator'; // This is a port of Google Android `libphonenumber`'s // `phonenumberutil.js` of 17th November, 2016. // // https://github.com/googlei18n/libphonenumber/commits/master/javascript/i18n/phonenumbers/phonenumberutil.js import { matches_entirely } from './common'; import { parse_phone_number_and_country_phone_code } from './parse'; import { get_phone_code, get_formats, get_format_pattern, get_format_format, get_format_leading_digits_patterns, get_format_national_prefix_formatting_rule, get_format_national_prefix_is_optional_when_formatting, get_format_international_format, get_metadata_by_country_phone_code } from './metadata'; // Formats a phone number // // Example use cases: // // ```js // format('8005553535', 'RU', 'International') // format('8005553535', 'RU', 'International', metadata) // format({ phone: '8005553535', country: 'RU' }, 'International') // format({ phone: '8005553535', country: 'RU' }, 'International', metadata) // format('+78005553535', 'National') // format('+78005553535', 'National', metadata) // ``` // export default function format(first_argument, second_argument, third_argument, fourth_argument) { var _sort_out_arguments = sort_out_arguments(first_argument, second_argument, third_argument, fourth_argument), input = _sort_out_arguments.input, format_type = _sort_out_arguments.format_type, metadata = _sort_out_arguments.metadata; var country_metadata = void 0; if (input.country) { country_metadata = metadata.countries[input.country]; } var _parse_phone_number_a = parse_phone_number_and_country_phone_code(input.phone, metadata), country_phone_code = _parse_phone_number_a.country_phone_code, number = _parse_phone_number_a.number; if (country_phone_code) { // Check country restriction if (input.country && country_metadata && country_phone_code !== get_phone_code(country_metadata)) { return input.phone; } country_metadata = get_metadata_by_country_phone_code(country_phone_code, metadata); } if (!country_metadata) { return input.phone; } switch (format_type) { case 'International': if (!number) { return '+' + get_phone_code(country_metadata); } var national_number = format_national_number(number, 'International', false, country_metadata); return '+' + get_phone_code(country_metadata) + ' ' + national_number; case 'International_plaintext': return '+' + get_phone_code(country_metadata) + input.phone; case 'National': if (!number) { return ''; } return format_national_number(number, 'National', false, country_metadata); } } // This was originally set to $1 but there are some countries for which the // first group is not used in the national pattern (e.g. Argentina) so the $1 // group does not match correctly. Therefore, we use \d, so that the first // group actually used in the pattern will be matched. export var FIRST_GROUP_PATTERN = /(\$\d)/; export function format_national_number_using_format(number, format, international, enforce_national_prefix, country_metadata) { var format_pattern_matcher = new RegExp(get_format_pattern(format)); var national_prefix_formatting_rule = get_format_national_prefix_formatting_rule(format, country_metadata); // National prefix is omitted if there's no national prefix formatting rule // set for this country, or when this rule is set but // national prefix is optional for this phone number format // (and it is not enforced explicitly) var national_prefix_may_be_omitted = !national_prefix_formatting_rule || national_prefix_formatting_rule && get_format_national_prefix_is_optional_when_formatting(format, country_metadata) && !enforce_national_prefix; if (!international && !national_prefix_may_be_omitted) { return number.replace(format_pattern_matcher, get_format_format(format).replace(FIRST_GROUP_PATTERN, national_prefix_formatting_rule)); } var formatted_number = number.replace(format_pattern_matcher, international ? get_format_international_format(format) : get_format_format(format)); if (international) { return local_to_international_style(formatted_number); } return formatted_number; } export function format_national_number(number, format_as, enforce_national_prefix, country_metadata) { var format = choose_format_for_number(get_formats(country_metadata), number); if (!format) { return number; } return format_national_number_using_format(number, format, format_as === 'International', enforce_national_prefix, country_metadata); } export function choose_format_for_number(available_formats, national_number) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = _getIterator(available_formats), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _format = _step.value; // Validate leading digits if (get_format_leading_digits_patterns(_format).length > 0) { // The last leading_digits_pattern is used here, as it is the most detailed var last_leading_digits_pattern = get_format_leading_digits_patterns(_format)[get_format_leading_digits_patterns(_format).length - 1]; // If leading digits don't match then move on to the next phone number format if (national_number.search(last_leading_digits_pattern) !== 0) { continue; } } // Check that the national number matches the phone number format regular expression if (matches_entirely(national_number, new RegExp(get_format_pattern(_format)))) { return _format; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } // Removes brackets and replaces dashes with spaces. // // E.g. "(999) 111-22-33" -> "999 111 22 33" // export function local_to_international_style(local) { return local // Remove brackets .replace(/[\(\)]/g, '') // Replace dashes with spaces .replace(/\-/g, ' ').trim(); } // Sort out arguments function sort_out_arguments() { var first_argument = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var second_argument = arguments[1]; var third_argument = arguments[2]; var fourth_argument = arguments[3]; var input = void 0; var format_type = void 0; var metadata = void 0; // Sort out arguments if (typeof first_argument === 'string') { // If country code is supplied if (typeof third_argument === 'string') { // Will be `parse()`d later in code input = { phone: first_argument, country: second_argument }; format_type = third_argument; metadata = fourth_argument; } // Just an international phone number is supplied else { // Will be `parse()`d later in code input = { phone: first_argument }; if (typeof second_argument !== 'string') { throw new Error('Format type argument not passed for `format()`'); } format_type = second_argument; metadata = third_argument; } } else { input = first_argument; format_type = second_argument; metadata = third_argument; } // Sanity check if (!metadata) { throw new Error('Metadata not passed'); } switch (format_type) { case 'International': case 'International_plaintext': case 'National': break; default: throw new Error('Unknown format type argument passed to "format()": "' + format_type + '"'); } return { input: input, format_type: format_type, metadata: metadata }; } //# sourceMappingURL=format.js.map