Socket
Socket
Sign inDemoInstall

libphonenumber-js

Package Overview
Dependencies
Maintainers
1
Versions
392
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

libphonenumber-js - npm Package Compare versions

Comparing version 0.2.19 to 0.2.20

custom.es6.js

1256

build/as you type.js

@@ -19,591 +19,521 @@ 'use strict';

exports.close_dangling_braces = close_dangling_braces;
exports.count_occurences = count_occurences;
exports.repeat = repeat;
exports.default = function (metadata) {
var as_you_type = function () {
function as_you_type(country_code) {
(0, _classCallCheck3.default)(this, as_you_type);
var _metadata = require('../metadata.min');
if (country_code && metadata.countries[country_code]) {
this.default_country = country_code;
}
var _metadata2 = _interopRequireDefault(_metadata);
this.reset();
}
var _metadata3 = require('./metadata');
(0, _createClass3.default)(as_you_type, [{
key: 'input',
value: function input(text) {
// Parse input
var _parse = require('./parse');
var extracted_number = (0, _parse.extract_formatted_phone_number)(text);
var _format = require('./format');
// Special case for a lone '+' sign
// since it's not considered a possible phone number.
if (!extracted_number) {
if (text && text.indexOf('+') >= 0) {
extracted_number = '+';
}
}
var _common = require('./common');
// Validate possible first part of a phone number
if (!(0, _common.matches_entirely)(extracted_number, VALID_INCOMPLETE_PHONE_NUMBER_PATTERN)) {
return this.current_output;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
return this.process_input((0, _parse.parse_phone_number)(extracted_number));
}
}, {
key: 'process_input',
value: function process_input(input) {
// If an out of position '+' sign detected
// (or a second '+' sign),
// then just drop it from the input.
if (input[0] === '+') {
if (!this.parsed_input) {
this.parsed_input += '+';
// Used in phone number format template creation.
// Could be any digit, I guess.
var DUMMY_DIGIT = '9'; // This is an enhanced port of Google Android `libphonenumber`'s
// `asyoutypeformatter.js` of 17th November, 2016.
//
// https://github.com/googlei18n/libphonenumber/blob/8d21a365061de2ba0675c878a710a7b24f74d2ae/javascript/i18n/phonenumbers/asyoutypeformatter.js
// If a default country was set
// then reset it because an explicitly international
// phone number is being entered
this.reset_countriness();
}
var DUMMY_DIGIT_MATCHER = new RegExp(DUMMY_DIGIT, 'g');
// I don't know why is it exactly `15`
var LONGEST_NATIONAL_PHONE_NUMBER_LENGTH = 15;
// Create a phone number consisting only of the digit 9 that matches the
// `number_pattern` by applying the pattern to the "longest phone number" string.
var LONGEST_DUMMY_PHONE_NUMBER = repeat(DUMMY_DIGIT, LONGEST_NATIONAL_PHONE_NUMBER_LENGTH);
input = input.slice(1);
}
// The digits that have not been entered yet will be represented by a \u2008,
// the punctuation space.
var DIGIT_PLACEHOLDER = 'x'; // '\u2008' (punctuation space)
var DIGIT_PLACEHOLDER_MATCHER = new RegExp(DIGIT_PLACEHOLDER);
var DIGIT_PLACEHOLDER_MATCHER_GLOBAL = new RegExp(DIGIT_PLACEHOLDER, 'g');
// Raw phone number
this.parsed_input += input;
// A pattern that is used to match character classes in regular expressions.
// An example of a character class is "[1-4]".
var CHARACTER_CLASS_PATTERN = /\[([^\[\]])*\]/g;
// Reset phone number validation state
this.valid = false;
// Any digit in a regular expression that actually denotes a digit. For
// example, in the regular expression "80[0-2]\d{6,10}", the first 2 digits
// (8 and 0) are standalone digits, but the rest are not.
// Two look-aheads are needed because the number following \\d could be a
// two-digit number, since the phone number can be as long as 15 digits.
var STANDALONE_DIGIT_PATTERN = /\d(?=[^,}][^,}])/g;
// Add digits to the national number
this.national_number += input;
// A pattern that is used to determine if a `format` is eligible
// to be used by the "as you type formatter".
// It is eligible when the `format` contains groups of the dollar sign
// followed by a single digit, separated by valid phone number punctuation.
// This prevents invalid punctuation (such as the star sign in Israeli star numbers)
// getting into the output of the "as you type formatter".
var ELIGIBLE_FORMAT_PATTERN = new RegExp('^' + '[' + _parse.VALID_PUNCTUATION + ']*' + '(\\$\\d[' + _parse.VALID_PUNCTUATION + ']*)+' + '$');
// Try to format the parsed input
// This is the minimum length of the leading digits of a phone number
// to guarantee the first "leading digits pattern" for a phone number format
// to be preemptive.
var MIN_LEADING_DIGITS_LENGTH = 3;
if (this.is_international()) {
if (!this.country_phone_code) {
// If one looks at country phone codes
// then he can notice that no one country phone code
// is ever a (leftmost) substring of another country phone code.
// So if a valid country code is extracted so far
// then it means that this is the country code.
var VALID_INCOMPLETE_PHONE_NUMBER = '[' + _parse.PLUS_CHARS + ']{0,1}' + '[' + _parse.VALID_PUNCTUATION + _parse.VALID_DIGITS + ']*';
// If no country phone code could be extracted so far,
// then just return the raw phone number,
// because it has no way of knowing
// how to format the phone number so far.
if (!this.extract_country_phone_code()) {
// Return raw phone number
return this.parsed_input;
}
var VALID_INCOMPLETE_PHONE_NUMBER_PATTERN = new RegExp('^' + VALID_INCOMPLETE_PHONE_NUMBER + '$', 'i');
// Initialize country-specific data
this.initialize_phone_number_formats_for_this_country_phone_code();
this.reset_format();
this.determine_the_country();
}
// `this.country` could be `undefined`,
// for instance, when there is ambiguity
// in a form of several different countries
// each corresponding to the same country phone code
// (e.g. NANPA: USA, Canada, etc),
// and there's not enough digits entered
// to reliably determine the country
// the phone number belongs to.
// Therefore, in cases of such ambiguity,
// each time something is input,
// try to determine the country
// (if it's not determined yet).
else if (!this.country) {
this.determine_the_country();
}
} else {
// Some national prefixes are substrings of other national prefixes
// (for the same country), therefore try to extract national prefix each time
// because a longer national prefix might be available at some point in time.
var as_you_type = function () {
function as_you_type(country_code) {
(0, _classCallCheck3.default)(this, as_you_type);
var previous_national_prefix = this.national_prefix;
this.national_number = this.national_prefix + this.national_number;
if (country_code && _metadata2.default.countries[country_code]) {
this.default_country = country_code;
}
// Possibly extract a national prefix
this.extract_national_prefix();
this.reset();
}
if (this.national_prefix !== previous_national_prefix) {
// National number has changed
// (due to another national prefix been extracted)
// therefore national number has changed
// therefore reset all previous formatting data.
// (and leading digits matching state)
this.matching_formats = this.available_formats;
this.reset_format();
}
}
(0, _createClass3.default)(as_you_type, [{
key: 'input',
value: function input(text) {
// Parse input
// Format the phone number (given the next digits)
var formatted_national_phone_number = this.format_national_phone_number(input);
var extracted_number = (0, _parse.extract_formatted_phone_number)(text);
// Special case for a lone '+' sign
// since it's not considered a possible phone number.
if (!extracted_number) {
if (text && text.indexOf('+') >= 0) {
extracted_number = '+';
// If the phone number could be formatted,
// then return it, possibly prepending with country phone code
// (for international phone numbers only)
if (formatted_national_phone_number) {
return this.full_phone_number(formatted_national_phone_number);
}
}
// Validate possible first part of a phone number
if (!(0, _common.matches_entirely)(extracted_number, VALID_INCOMPLETE_PHONE_NUMBER_PATTERN)) {
return this.current_output;
// If the phone number couldn't be formatted,
// then just fall back to the raw phone number.
return this.parsed_input;
}
return this.process_input((0, _parse.parse_phone_number)(extracted_number));
}
}, {
key: 'process_input',
value: function process_input(input) {
// If an out of position '+' sign detected
// (or a second '+' sign),
// then just drop it from the input.
if (input[0] === '+') {
if (!this.parsed_input) {
this.parsed_input += '+';
// If a default country was set
// then reset it because an explicitly international
// phone number is being entered
this.reset_countriness();
}, {
key: 'format_national_phone_number',
value: function format_national_phone_number(next_digits) {
// Format the next phone number digits
// using the previously chosen phone number format.
//
// This is done here because if `attempt_to_format_complete_phone_number`
// was placed before this call then the `template`
// wouldn't reflect the situation correctly (and would therefore be inconsistent)
//
var national_number_formatted_with_previous_format = void 0;
if (this.chosen_format) {
national_number_formatted_with_previous_format = this.format_next_national_number_digits(next_digits);
}
input = input.slice(1);
}
// See if the input digits can be formatted properly already. If not,
// use the results from format_next_national_number_digits(), which does formatting
// based on the formatting pattern chosen.
// Raw phone number
this.parsed_input += input;
var formatted_number = this.attempt_to_format_complete_phone_number();
// Reset phone number validation state
this.valid = false;
if (formatted_number) {
this.valid = true;
return formatted_number;
}
// Add digits to the national number
this.national_number += input;
// Check if the previously chosen phone number format still holds
this.match_formats_by_leading_digits();
// Try to format the parsed input
// If the previously chosen phone number format
// didn't match the next (current) digit being input
// (leading digits pattern didn't match).
if (this.choose_another_format()) {
// And a more appropriate phone number format
// has been chosen for these `leading digits`,
// then format the national phone number (so far)
// using the newly selected phone number pattern.
if (this.is_international()) {
if (!this.country_phone_code) {
// If one looks at country phone codes
// then he can notice that no one country phone code
// is ever a (leftmost) substring of another country phone code.
// So if a valid country code is extracted so far
// then it means that this is the country code.
// Will return `undefined` if it couldn't format
// the supplied national number
// using the selected phone number pattern.
// If no country phone code could be extracted so far,
// then just return the raw phone number,
// because it has no way of knowing
// how to format the phone number so far.
if (!this.extract_country_phone_code()) {
// Return raw phone number
return this.parsed_input;
}
// Initialize country-specific data
this.initialize_phone_number_formats_for_this_country_phone_code();
this.reset_format();
this.determine_the_country();
return this.reformat_national_number();
}
// `this.country` could be `undefined`,
// for instance, when there is ambiguity
// in a form of several different countries
// each corresponding to the same country phone code
// (e.g. NANPA: USA, Canada, etc),
// and there's not enough digits entered
// to reliably determine the country
// the phone number belongs to.
// Therefore, in cases of such ambiguity,
// each time something is input,
// try to determine the country
// (if it's not determined yet).
else if (!this.country) {
this.determine_the_country();
}
} else {
// Some national prefixes are substrings of other national prefixes
// (for the same country), therefore try to extract national prefix each time
// because a longer national prefix might be available at some point in time.
var previous_national_prefix = this.national_prefix;
this.national_number = this.national_prefix + this.national_number;
// If could format the next (current) digit
// using the previously chosen phone number format
// then return the formatted number so far.
// Possibly extract a national prefix
this.extract_national_prefix();
// If no new phone number format could be chosen,
// and couldn't format the supplied national number
// using the selected phone number pattern,
// then it will return `undefined`.
if (this.national_prefix !== previous_national_prefix) {
// National number has changed
// (due to another national prefix been extracted)
// therefore national number has changed
// therefore reset all previous formatting data.
// (and leading digits matching state)
this.matching_formats = this.available_formats;
this.reset_format();
}
return national_number_formatted_with_previous_format;
}
}, {
key: 'reset',
value: function reset() {
// Input stripped of non-phone-number characters.
// Can only contain a possible leading '+' sign and digits.
this.parsed_input = '';
// Format the phone number (given the next digits)
var formatted_national_phone_number = this.format_national_phone_number(input);
this.current_output = '';
// If the phone number could be formatted,
// then return it, possibly prepending with country phone code
// (for international phone numbers only)
if (formatted_national_phone_number) {
return this.full_phone_number(formatted_national_phone_number);
}
// This contains the national prefix that has been extracted. It contains only
// digits without formatting.
this.national_prefix = '';
// If the phone number couldn't be formatted,
// then just fall back to the raw phone number.
return this.parsed_input;
}
}, {
key: 'format_national_phone_number',
value: function format_national_phone_number(next_digits) {
// Format the next phone number digits
// using the previously chosen phone number format.
//
// This is done here because if `attempt_to_format_complete_phone_number`
// was placed before this call then the `template`
// wouldn't reflect the situation correctly (and would therefore be inconsistent)
//
var national_number_formatted_with_previous_format = void 0;
if (this.chosen_format) {
national_number_formatted_with_previous_format = this.format_next_national_number_digits(next_digits);
}
this.national_number = '';
// See if the input digits can be formatted properly already. If not,
// use the results from format_next_national_number_digits(), which does formatting
// based on the formatting pattern chosen.
this.reset_countriness();
var formatted_number = this.attempt_to_format_complete_phone_number();
this.reset_format();
if (formatted_number) {
this.valid = true;
return formatted_number;
this.valid = false;
return this;
}
}, {
key: 'reset_country',
value: function reset_country() {
if (this.default_country && !this.is_international()) {
this.country = this.default_country;
} else {
this.country = undefined;
}
}
}, {
key: 'reset_countriness',
value: function reset_countriness() {
this.reset_country();
// Check if the previously chosen phone number format still holds
this.match_formats_by_leading_digits();
if (this.default_country && !this.is_international()) {
this.country_metadata = metadata.countries[this.default_country];
this.country_phone_code = this.country_metadata.phone_code;
// If the previously chosen phone number format
// didn't match the next (current) digit being input
// (leading digits pattern didn't match).
if (this.choose_another_format()) {
// And a more appropriate phone number format
// has been chosen for these `leading digits`,
// then format the national phone number (so far)
// using the newly selected phone number pattern.
this.initialize_phone_number_formats_for_this_country_phone_code();
} else {
this.country_metadata = undefined;
this.country_phone_code = undefined;
// Will return `undefined` if it couldn't format
// the supplied national number
// using the selected phone number pattern.
return this.reformat_national_number();
this.available_formats = [];
this.matching_formats = this.available_formats;
}
}
}, {
key: 'reset_format',
value: function reset_format() {
this.chosen_format = undefined;
this.template = undefined;
this.partially_populated_template = undefined;
this.last_match_position = -1;
}
// If could format the next (current) digit
// using the previously chosen phone number format
// then return the formatted number so far.
// Format each digit of national phone number (so far)
// using the newly selected phone number pattern.
// If no new phone number format could be chosen,
// and couldn't format the supplied national number
// using the selected phone number pattern,
// then it will return `undefined`.
return national_number_formatted_with_previous_format;
}
}, {
key: 'reset',
value: function reset() {
// Input stripped of non-phone-number characters.
// Can only contain a possible leading '+' sign and digits.
this.parsed_input = '';
this.current_output = '';
// This contains the national prefix that has been extracted. It contains only
// digits without formatting.
this.national_prefix = '';
this.national_number = '';
this.reset_countriness();
this.reset_format();
this.valid = false;
return this;
}
}, {
key: 'reset_country',
value: function reset_country() {
if (this.default_country && !this.is_international()) {
this.country = this.default_country;
} else {
this.country = undefined;
}, {
key: 'reformat_national_number',
value: function reformat_national_number() {
// Format each digit of national phone number (so far)
// using the selected phone number pattern.
return this.format_next_national_number_digits(this.national_number);
}
}
}, {
key: 'reset_countriness',
value: function reset_countriness() {
this.reset_country();
}, {
key: 'initialize_phone_number_formats_for_this_country_phone_code',
value: function initialize_phone_number_formats_for_this_country_phone_code() {
// Get all "eligible" phone number formats for this country
this.available_formats = (0, _metadata.get_formats)(this.country_metadata).filter(function (format) {
return ELIGIBLE_FORMAT_PATTERN.test((0, _metadata.get_format_international_format)(format));
})
// Try the formats with "leading digits" defined first
.sort(function (a, b) {
// Leading digits are defined for most formats
/* istanbul ignore next */
if ((0, _metadata.get_format_leading_digits_patterns)(a).length === 0 && (0, _metadata.get_format_leading_digits_patterns)(b).length > 0) {
return -1;
}
if (this.default_country && !this.is_international()) {
this.country_metadata = _metadata2.default.countries[this.default_country];
this.country_phone_code = this.country_metadata.phone_code;
// Leading digits are defined for most formats
/* istanbul ignore next */
if ((0, _metadata.get_format_leading_digits_patterns)(a).length > 0 && (0, _metadata.get_format_leading_digits_patterns)(b).length === 0) {
return 1;
}
this.initialize_phone_number_formats_for_this_country_phone_code();
} else {
this.country_metadata = undefined;
this.country_phone_code = undefined;
return 0;
});
this.available_formats = [];
this.matching_formats = this.available_formats;
}
}
}, {
key: 'reset_format',
value: function reset_format() {
this.chosen_format = undefined;
this.template = undefined;
this.partially_populated_template = undefined;
this.last_match_position = -1;
}
}, {
key: 'match_formats_by_leading_digits',
value: function match_formats_by_leading_digits() {
var leading_digits = this.national_number;
// Format each digit of national phone number (so far)
// using the newly selected phone number pattern.
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
}, {
key: 'reformat_national_number',
value: function reformat_national_number() {
// Format each digit of national phone number (so far)
// using the selected phone number pattern.
return this.format_next_national_number_digits(this.national_number);
}
}, {
key: 'initialize_phone_number_formats_for_this_country_phone_code',
value: function initialize_phone_number_formats_for_this_country_phone_code() {
// Get all "eligible" phone number formats for this country
this.available_formats = (0, _metadata3.get_formats)(this.country_metadata).filter(function (format) {
return ELIGIBLE_FORMAT_PATTERN.test((0, _metadata3.get_format_international_format)(format));
})
// Try the formats with "leading digits" defined first
.sort(function (a, b) {
// Leading digits are defined for most formats
/* istanbul ignore next */
if ((0, _metadata3.get_format_leading_digits_patterns)(a).length === 0 && (0, _metadata3.get_format_leading_digits_patterns)(b).length > 0) {
return -1;
}
var index_of_leading_digits_pattern = leading_digits.length - MIN_LEADING_DIGITS_LENGTH;
// Leading digits are defined for most formats
/* istanbul ignore next */
if ((0, _metadata3.get_format_leading_digits_patterns)(a).length > 0 && (0, _metadata3.get_format_leading_digits_patterns)(b).length === 0) {
return 1;
if (index_of_leading_digits_pattern < 0) {
index_of_leading_digits_pattern = 0;
}
return 0;
});
this.matching_formats = this.get_relevant_phone_number_formats().filter(function (format) {
var leading_digits_pattern_count = (0, _metadata.get_format_leading_digits_patterns)(format).length;
this.matching_formats = this.available_formats;
}
}, {
key: 'match_formats_by_leading_digits',
value: function match_formats_by_leading_digits() {
var leading_digits = this.national_number;
// Keep everything that isn't restricted by leading digits.
if (leading_digits_pattern_count === 0) {
return true;
}
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
var index_of_leading_digits_pattern = leading_digits.length - MIN_LEADING_DIGITS_LENGTH;
if (index_of_leading_digits_pattern < 0) {
index_of_leading_digits_pattern = 0;
var leading_digits_pattern_index = Math.min(index_of_leading_digits_pattern, leading_digits_pattern_count - 1);
var leading_digits_pattern = (0, _metadata.get_format_leading_digits_patterns)(format)[leading_digits_pattern_index];
return new RegExp('^' + leading_digits_pattern).test(leading_digits);
});
}
}, {
key: 'get_relevant_phone_number_formats',
value: function get_relevant_phone_number_formats() {
var leading_digits = this.national_number;
this.matching_formats = this.get_relevant_phone_number_formats().filter(function (format) {
var leading_digits_pattern_count = (0, _metadata3.get_format_leading_digits_patterns)(format).length;
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
// Keep everything that isn't restricted by leading digits.
if (leading_digits_pattern_count === 0) {
return true;
if (leading_digits.length <= MIN_LEADING_DIGITS_LENGTH) {
return this.available_formats;
}
var leading_digits_pattern_index = Math.min(index_of_leading_digits_pattern, leading_digits_pattern_count - 1);
var leading_digits_pattern = (0, _metadata3.get_format_leading_digits_patterns)(format)[leading_digits_pattern_index];
return new RegExp('^' + leading_digits_pattern).test(leading_digits);
});
}
}, {
key: 'get_relevant_phone_number_formats',
value: function get_relevant_phone_number_formats() {
var leading_digits = this.national_number;
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
if (leading_digits.length <= MIN_LEADING_DIGITS_LENGTH) {
return this.available_formats;
return this.matching_formats;
}
return this.matching_formats;
}
// Check to see if there is an exact pattern match for these digits. If so, we
// should use this instead of any other formatting template whose
// leadingDigitsPattern also matches the input.
// Check to see if there is an exact pattern match for these digits. If so, we
// should use this instead of any other formatting template whose
// leadingDigitsPattern also matches the input.
}, {
key: 'attempt_to_format_complete_phone_number',
value: function attempt_to_format_complete_phone_number() {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
}, {
key: 'attempt_to_format_complete_phone_number',
value: function attempt_to_format_complete_phone_number() {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(this.get_relevant_phone_number_formats()), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var format = _step.value;
try {
for (var _iterator = (0, _getIterator3.default)(this.get_relevant_phone_number_formats()), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var format = _step.value;
var matcher = new RegExp('^(?:' + (0, _metadata.get_format_pattern)(format) + ')$');
var matcher = new RegExp('^(?:' + (0, _metadata3.get_format_pattern)(format) + ')$');
var matches = false;
var discard_national_prefix = false;
if (!matcher.test(this.national_number)) {
// If the national prefix is optional
// then also try to format the phone number
// without the national prefix being extracted.
if (this.national_prefix && (0, _metadata.get_format_national_prefix_is_optional_when_formatting)(format, this.country_metadata)) {
if (!matcher.test(this.national_prefix + this.national_number)) {
continue;
}
// If the national prefix is optional
// then also try to format the phone number
// without the national prefix being extracted.
if (this.national_prefix && (0, _metadata3.get_format_national_prefix_is_optional_when_formatting)(format, this.country_metadata)) {
matches = matcher.test(this.national_prefix + this.national_number);
this.national_number = this.national_prefix + this.national_number;
this.national_prefix = '';
}
if (matches) {
discard_national_prefix = true;
continue;
}
}
matches = matches || matcher.test(this.national_number);
if (!this.validate_format(format)) {
continue;
}
if (!matches) {
continue;
}
// To leave the formatter in a consistent state
this.reset_format();
this.chosen_format = format;
if (discard_national_prefix) {
this.national_number = this.national_prefix + this.national_number;
this.national_prefix = '';
}
var formatted_number = (0, _format.format_national_number_using_format)(this.national_number, format, this.is_international(), this.national_prefix.length > 0, this.country_metadata);
if (!this.validate_format(format)) {
continue;
}
// To leave the formatter in a consistent state
this.reset_format();
this.chosen_format = format;
var number_pattern = this.validate_format_for_template(format);
var formatted_number = (0, _format.format_national_number_using_format)(this.national_number, format, this.is_international(), this.national_prefix.length > 0, this.country_metadata);
if (number_pattern) {
// Set `this.template` and `this.partially_populated_template`
this.create_formatting_template(format, number_pattern);
// Populate `this.partially_populated_template`
this.reformat_national_number();
} else {
var full_number = this.full_phone_number(formatted_number);
//
// `else` case doesn't ever happen
// with the current metadata,
// but just in case.
//
/* istanbul ignore else */
if (this.create_formatting_template(format)) {
// Populate `this.partially_populated_template`
this.reformat_national_number();
} else {
var full_number = this.full_phone_number(formatted_number);
this.template = full_number.replace(/[\d\+]/g, DIGIT_PLACEHOLDER);
this.partially_populated_template = full_number;
}
this.template = full_number.replace(/[\d\+]/g, DIGIT_PLACEHOLDER);
this.partially_populated_template = full_number;
}
return formatted_number;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
return formatted_number;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
if (_didIteratorError) {
throw _iteratorError;
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}
// Combines the national number with the appropriate prefix
// Combines the national number with the appropriate prefix
}, {
key: 'full_phone_number',
value: function full_phone_number(formatted_national_number) {
if (this.is_international()) {
return '+' + this.country_phone_code + ' ' + formatted_national_number;
}, {
key: 'full_phone_number',
value: function full_phone_number(formatted_national_number) {
if (this.is_international()) {
return '+' + this.country_phone_code + ' ' + formatted_national_number;
}
return formatted_national_number;
}
return formatted_national_number;
}
// Extracts the country calling code from the beginning
// of the entered `national_number` (so far),
// and places the remaining input into the `national_number`.
// Extracts the country calling code from the beginning
// of the entered `national_number` (so far),
// and places the remaining input into the `national_number`.
}, {
key: 'extract_country_phone_code',
value: function extract_country_phone_code() {
if (!this.national_number) {
return;
}
}, {
key: 'extract_country_phone_code',
value: function extract_country_phone_code() {
if (!this.national_number) {
return;
}
var _parse_phone_number_a = (0, _parse.parse_phone_number_and_country_phone_code)(this.parsed_input, metadata);
var _parse_phone_number_a = (0, _parse.parse_phone_number_and_country_phone_code)(this.parsed_input);
var country_phone_code = _parse_phone_number_a.country_phone_code;
var number = _parse_phone_number_a.number;
var country_phone_code = _parse_phone_number_a.country_phone_code;
var number = _parse_phone_number_a.number;
if (!country_phone_code) {
return;
}
if (!country_phone_code) {
return;
this.country_phone_code = country_phone_code;
this.national_number = number;
return this.country_metadata = (0, _metadata.get_metadata_by_country_phone_code)(country_phone_code, metadata);
}
}, {
key: 'extract_national_prefix',
value: function extract_national_prefix() {
this.national_prefix = '';
this.country_phone_code = country_phone_code;
this.national_number = number;
if (!this.country_metadata) {
return;
}
return this.country_metadata = (0, _metadata3.get_metadata_by_country_phone_code)(country_phone_code, _metadata2.default);
}
}, {
key: 'extract_national_prefix',
value: function extract_national_prefix() {
this.national_prefix = '';
var national_prefix_for_parsing = (0, _metadata.get_national_prefix_for_parsing)(this.country_metadata);
if (!this.country_metadata) {
return;
}
if (!national_prefix_for_parsing) {
return;
}
var national_prefix_for_parsing = (0, _metadata3.get_national_prefix_for_parsing)(this.country_metadata);
var matches = this.national_number.match(new RegExp('^(?:' + national_prefix_for_parsing + ')'));
if (!national_prefix_for_parsing) {
return;
}
// Since some national prefix patterns are entirely optional, check that a
// national prefix could actually be extracted.
if (!matches || !matches[0]) {
return;
}
var matches = this.national_number.match(new RegExp('^(?:' + national_prefix_for_parsing + ')'));
var national_number_starts_at = matches[0].length;
// Since some national prefix patterns are entirely optional, check that a
// national prefix could actually be extracted.
if (!matches || !matches[0]) {
return;
this.national_prefix = this.national_number.slice(0, national_number_starts_at);
this.national_number = this.national_number.slice(national_number_starts_at);
return this.national_prefix;
}
}, {
key: 'choose_another_format',
value: function choose_another_format() {
// When there are multiple available formats, the formatter uses the first
// format where a formatting template could be created.
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
var national_number_starts_at = matches[0].length;
try {
for (var _iterator2 = (0, _getIterator3.default)(this.get_relevant_phone_number_formats()), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var format = _step2.value;
this.national_prefix = this.national_number.slice(0, national_number_starts_at);
this.national_number = this.national_number.slice(national_number_starts_at);
// If this format is currently being used
// and is still possible, then stick to it.
if (this.chosen_format === format) {
return;
}
return this.national_prefix;
}
}, {
key: 'choose_another_format',
value: function choose_another_format() {
// When there are multiple available formats, the formatter uses the first
// format where a formatting template could be created.
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
// If this `format` is suitable for "as you type",
// then extract the template from this format
// and use it to format the phone number being input.
try {
for (var _iterator2 = (0, _getIterator3.default)(this.get_relevant_phone_number_formats()), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var format = _step2.value;
if (!this.validate_format(format)) {
continue;
}
// If this format is currently being used
// and is still possible, then stick to it.
if (this.chosen_format === format) {
return;
}
if (!this.create_formatting_template(format)) {
continue;
}
// If this `format` is suitable for "as you type",
// then extract the template from this format
// and use it to format the phone number being input.
if (!this.validate_format(format)) {
continue;
}
var number_pattern = this.validate_format_for_template(format);
if (number_pattern) {
this.create_formatting_template(format, number_pattern);
this.chosen_format = format;

@@ -617,207 +547,259 @@

}
}
// No format matches the phone number,
// therefore set `country` to `undefined`
// (or to the default country).
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
// No format matches the phone number,
// therefore set `country` to `undefined`
// (or to the default country).
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
this.reset_country();
this.reset_country();
// No format matches the national phone number entered
this.reset_format();
}
}, {
key: 'validate_format',
value: function validate_format(format) {
// If national prefix is mandatory for this phone number format
// and the user didn't input the national prefix,
// then this phone number format isn't suitable.
if (!this.is_international() && !this.national_prefix && (0, _metadata3.get_format_national_prefix_is_mandatory_when_formatting)(format, this.country_metadata)) {
return;
// No format matches the national phone number entered
this.reset_format();
}
}, {
key: 'validate_format',
value: function validate_format(format) {
// If national prefix is mandatory for this phone number format
// and the user didn't input the national prefix,
// then this phone number format isn't suitable.
if (!this.is_international() && !this.national_prefix && (0, _metadata.get_format_national_prefix_is_mandatory_when_formatting)(format, this.country_metadata)) {
return;
}
return true;
}
}, {
key: 'validate_format_for_template',
value: function validate_format_for_template(format) {
// The formatter doesn't format numbers when numberPattern contains '|', e.g.
// (20|3)\d{4}. In those cases we quickly return.
// (Though there's no such format in current metadata)
/* istanbul ignore if */
if ((0, _metadata3.get_format_pattern)(format).indexOf('|') >= 0) {
return;
return true;
}
}, {
key: 'create_formatting_template',
value: function create_formatting_template(format) {
// The formatter doesn't format numbers when numberPattern contains '|', e.g.
// (20|3)\d{4}. In those cases we quickly return.
// (Though there's no such format in current metadata)
/* istanbul ignore if */
if ((0, _metadata.get_format_pattern)(format).indexOf('|') >= 0) {
return;
}
var national_prefix_formatting_rule = (0, _metadata3.get_format_national_prefix_formatting_rule)(format, this.country_metadata);
var national_prefix_formatting_rule = (0, _metadata.get_format_national_prefix_formatting_rule)(format, this.country_metadata);
// A very smart trick by the guys at Google
var number_pattern = (0, _metadata3.get_format_pattern)(format)
// Replace anything in the form of [..] with \d
.replace(CHARACTER_CLASS_PATTERN, '\\d')
// Replace any standalone digit (not the one in `{}`) with \d
.replace(STANDALONE_DIGIT_PATTERN, '\\d');
// A very smart trick by the guys at Google
var number_pattern = (0, _metadata.get_format_pattern)(format)
// Replace anything in the form of [..] with \d
.replace(CHARACTER_CLASS_PATTERN, '\\d')
// Replace any standalone digit (not the one in `{}`) with \d
.replace(STANDALONE_DIGIT_PATTERN, '\\d');
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
var dummy_phone_number_matching_format_pattern = LONGEST_DUMMY_PHONE_NUMBER.match(number_pattern)[0];
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
var dummy_phone_number_matching_format_pattern = LONGEST_DUMMY_PHONE_NUMBER.match(number_pattern)[0];
// If the national number entered is too long
// for any phone number format, then abort.
if (this.national_number.length > dummy_phone_number_matching_format_pattern.length) {
return;
}
// If the national number entered is too long
// for any phone number format, then abort.
if (this.national_number.length > dummy_phone_number_matching_format_pattern.length) {
return;
}
return number_pattern;
}
}, {
key: 'create_formatting_template',
value: function create_formatting_template(format, number_pattern) {
var number_format = this.get_format_format(format);
// Now prepare phone number format
var number_format = this.get_format_format(format);
// If the user did input the national prefix
// then maybe make it a part of the phone number template
if (this.national_prefix) {
var national_prefix_formatting_rule = (0, _metadata3.get_format_national_prefix_formatting_rule)(format, this.country_metadata);
// If the user did input the national prefix
// then maybe make it a part of the phone number template
if (this.national_prefix) {
var _national_prefix_formatting_rule = (0, _metadata.get_format_national_prefix_formatting_rule)(format, this.country_metadata);
// If national prefix formatting rule is set
// for this phone number format
if (national_prefix_formatting_rule) {
// Make the national prefix a part of the phone number template
number_format = number_format.replace(_format.FIRST_GROUP_PATTERN, national_prefix_formatting_rule);
// If national prefix formatting rule is set
// for this phone number format
if (_national_prefix_formatting_rule) {
// Make the national prefix a part of the phone number template
number_format = number_format.replace(_format.FIRST_GROUP_PATTERN, _national_prefix_formatting_rule);
}
}
}
// Get a formatting template which can be used to efficiently format
// a partial number where digits are added one by one.
// Get a formatting template which can be used to efficiently format
// a partial number where digits are added one by one.
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
var dummy_phone_number_matching_format_pattern = LONGEST_DUMMY_PHONE_NUMBER.match(number_pattern)[0];
// Create formatting template for this phone number format
var template = dummy_phone_number_matching_format_pattern
// Format the dummy phone number according to the format
.replace(new RegExp(number_pattern, 'g'), number_format)
// Replace each dummy digit with a DIGIT_PLACEHOLDER
.replace(DUMMY_DIGIT_MATCHER, DIGIT_PLACEHOLDER);
// Create formatting template for this phone number format
var template = dummy_phone_number_matching_format_pattern
// Format the dummy phone number according to the format
.replace(new RegExp(number_pattern, 'g'), number_format)
// Replace each dummy digit with a DIGIT_PLACEHOLDER
.replace(DUMMY_DIGIT_MATCHER, DIGIT_PLACEHOLDER);
// This one is for national number only
this.partially_populated_template = template;
// This one is for national number only
this.partially_populated_template = template;
// For convenience, the public `.template` property
// is gonna contain the whole international number
// if the phone number being input is international.
if (this.is_international()) {
template = DIGIT_PLACEHOLDER + repeat(DIGIT_PLACEHOLDER, this.country_phone_code.length) + ' ' + template;
}
// For local numbers, replace national prefix
// with a digit placeholder.
else {
template = template.replace(/\d/g, DIGIT_PLACEHOLDER);
}
// For convenience, the public `.template` property
// is gonna contain the whole international number
// if the phone number being input is international.
if (this.is_international()) {
template = DIGIT_PLACEHOLDER + repeat(DIGIT_PLACEHOLDER, this.country_phone_code.length) + ' ' + template;
// This one is for the full phone number
return this.template = template;
}
// For local numbers, replace national prefix
// with a digit placeholder.
else {
template = template.replace(/\d/g, DIGIT_PLACEHOLDER);
}
}, {
key: 'format_next_national_number_digits',
value: function format_next_national_number_digits(digits) {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
// This one is for the full phone number
this.template = template;
}
}, {
key: 'format_next_national_number_digits',
value: function format_next_national_number_digits(digits) {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = (0, _getIterator3.default)(digits), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var digit = _step3.value;
try {
for (var _iterator3 = (0, _getIterator3.default)(digits), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var digit = _step3.value;
// If there is room for more digits in current `template`,
// then set the next digit in the `template`,
// and return the formatted digits so far.
// If there is room for more digits in current `template`,
// then set the next digit in the `template`,
// and return the formatted digits so far.
// If more digits are entered than the current format could handle
if (this.partially_populated_template.slice(this.last_match_position + 1).search(DIGIT_PLACEHOLDER_MATCHER) === -1) {
// Reset the current format,
// so that the new format will be chosen
// in a subsequent `this.choose_another_format()` call
// later in code.
this.chosen_format = undefined;
this.template = undefined;
this.partially_populated_template = undefined;
return;
}
// If more digits are entered than the current format could handle
if (this.partially_populated_template.slice(this.last_match_position + 1).search(DIGIT_PLACEHOLDER_MATCHER) === -1) {
// Reset the current format,
// so that the new format will be chosen
// in a subsequent `this.choose_another_format()` call
// later in code.
this.chosen_format = undefined;
this.template = undefined;
this.partially_populated_template = undefined;
return;
this.last_match_position = this.partially_populated_template.search(DIGIT_PLACEHOLDER_MATCHER);
this.partially_populated_template = this.partially_populated_template.replace(DIGIT_PLACEHOLDER_MATCHER, digit);
}
this.last_match_position = this.partially_populated_template.search(DIGIT_PLACEHOLDER_MATCHER);
this.partially_populated_template = this.partially_populated_template.replace(DIGIT_PLACEHOLDER_MATCHER, digit);
}
// Return the formatted phone number so far
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
// Return the formatted phone number so far
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
return close_dangling_braces(this.partially_populated_template, this.last_match_position + 1).replace(DIGIT_PLACEHOLDER_MATCHER_GLOBAL, ' ');
}
}, {
key: 'is_international',
value: function is_international() {
return this.parsed_input && this.parsed_input[0] === '+';
}
}, {
key: 'get_format_format',
value: function get_format_format(format) {
if (this.is_international()) {
return (0, _format.local_to_international_style)((0, _metadata.get_format_international_format)(format));
}
return close_dangling_braces(this.partially_populated_template, this.last_match_position + 1).replace(DIGIT_PLACEHOLDER_MATCHER_GLOBAL, ' ');
}
}, {
key: 'is_international',
value: function is_international() {
return this.parsed_input && this.parsed_input[0] === '+';
}
}, {
key: 'get_format_format',
value: function get_format_format(format) {
if (this.is_international()) {
return (0, _format.local_to_international_style)((0, _metadata3.get_format_international_format)(format));
return (0, _metadata.get_format_format)(format);
}
return (0, _metadata3.get_format_format)(format);
}
// Determines the country of the phone number
// entered so far based on the country phone code
// and the national phone number.
// Determines the country of the phone number
// entered so far based on the country phone code
// and the national phone number.
}, {
key: 'determine_the_country',
value: function determine_the_country() {
this.country = (0, _parse.find_country_code)(this.country_phone_code, this.national_number, metadata);
}
}]);
return as_you_type;
}();
}, {
key: 'determine_the_country',
value: function determine_the_country() {
this.country = (0, _parse.find_country_code)(this.country_phone_code, this.national_number);
}
}]);
as_you_type.DIGIT_PLACEHOLDER = DIGIT_PLACEHOLDER;
return as_you_type;
}();
};
exports.default = as_you_type;
exports.close_dangling_braces = close_dangling_braces;
exports.count_occurences = count_occurences;
exports.repeat = repeat;
var _metadata = require('./metadata');
as_you_type.DIGIT_PLACEHOLDER = DIGIT_PLACEHOLDER;
var _parse = require('./parse');
var _format = require('./format');
var _common = require('./common');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Used in phone number format template creation.
// Could be any digit, I guess.
// This is an enhanced port of Google Android `libphonenumber`'s
// `asyoutypeformatter.js` of 17th November, 2016.
//
// https://github.com/googlei18n/libphonenumber/blob/8d21a365061de2ba0675c878a710a7b24f74d2ae/javascript/i18n/phonenumbers/asyoutypeformatter.js
var DUMMY_DIGIT = '9';
var DUMMY_DIGIT_MATCHER = new RegExp(DUMMY_DIGIT, 'g');
// I don't know why is it exactly `15`
var LONGEST_NATIONAL_PHONE_NUMBER_LENGTH = 15;
// Create a phone number consisting only of the digit 9 that matches the
// `number_pattern` by applying the pattern to the "longest phone number" string.
var LONGEST_DUMMY_PHONE_NUMBER = repeat(DUMMY_DIGIT, LONGEST_NATIONAL_PHONE_NUMBER_LENGTH);
// The digits that have not been entered yet will be represented by a \u2008,
// the punctuation space.
var DIGIT_PLACEHOLDER = 'x'; // '\u2008' (punctuation space)
var DIGIT_PLACEHOLDER_MATCHER = new RegExp(DIGIT_PLACEHOLDER);
var DIGIT_PLACEHOLDER_MATCHER_GLOBAL = new RegExp(DIGIT_PLACEHOLDER, 'g');
// A pattern that is used to match character classes in regular expressions.
// An example of a character class is "[1-4]".
var CHARACTER_CLASS_PATTERN = /\[([^\[\]])*\]/g;
// Any digit in a regular expression that actually denotes a digit. For
// example, in the regular expression "80[0-2]\d{6,10}", the first 2 digits
// (8 and 0) are standalone digits, but the rest are not.
// Two look-aheads are needed because the number following \\d could be a
// two-digit number, since the phone number can be as long as 15 digits.
var STANDALONE_DIGIT_PATTERN = /\d(?=[^,}][^,}])/g;
// A pattern that is used to determine if a `format` is eligible
// to be used by the "as you type formatter".
// It is eligible when the `format` contains groups of the dollar sign
// followed by a single digit, separated by valid phone number punctuation.
// This prevents invalid punctuation (such as the star sign in Israeli star numbers)
// getting into the output of the "as you type formatter".
var ELIGIBLE_FORMAT_PATTERN = new RegExp('^' + '[' + _parse.VALID_PUNCTUATION + ']*' + '(\\$\\d[' + _parse.VALID_PUNCTUATION + ']*)+' + '$');
// This is the minimum length of the leading digits of a phone number
// to guarantee the first "leading digits pattern" for a phone number format
// to be preemptive.
var MIN_LEADING_DIGITS_LENGTH = 3;
var VALID_INCOMPLETE_PHONE_NUMBER = '[' + _parse.PLUS_CHARS + ']{0,1}' + '[' + _parse.VALID_PUNCTUATION + _parse.VALID_DIGITS + ']*';
var VALID_INCOMPLETE_PHONE_NUMBER_PATTERN = new RegExp('^' + VALID_INCOMPLETE_PHONE_NUMBER + '$', 'i');
function close_dangling_braces(template, cut_before) {

@@ -824,0 +806,0 @@ var retained_template = template.slice(0, cut_before);

@@ -19,17 +19,8 @@ 'use strict';

var _metadata = require('../metadata.min');
var _metadata2 = _interopRequireDefault(_metadata);
var _parse = require('./parse');
var _metadata3 = require('./metadata');
var _metadata = require('./metadata');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// 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
function format() {

@@ -54,6 +45,6 @@ var input = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];

if (input.country) {
country_metadata = _metadata2.default.countries[input.country];
country_metadata = this.metadata.countries[input.country];
}
var _parse_phone_number_a = (0, _parse.parse_phone_number_and_country_phone_code)(input.phone);
var _parse_phone_number_a = (0, _parse.parse_phone_number_and_country_phone_code)(input.phone, this.metadata);

@@ -66,7 +57,7 @@ var country_phone_code = _parse_phone_number_a.country_phone_code;

// Check country restriction
if (input.country && country_phone_code !== (0, _metadata3.get_phone_code)(country_metadata)) {
if (input.country && country_phone_code !== (0, _metadata.get_phone_code)(country_metadata)) {
return input.phone;
}
country_metadata = (0, _metadata3.get_metadata_by_country_phone_code)(country_phone_code, _metadata2.default);
country_metadata = (0, _metadata.get_metadata_by_country_phone_code)(country_phone_code, this.metadata);
}

@@ -81,9 +72,9 @@

if (!number) {
return '+' + (0, _metadata3.get_phone_code)(country_metadata);
return '+' + (0, _metadata.get_phone_code)(country_metadata);
}
var national_number = format_national_number(number, 'International', false, country_metadata);
return '+' + (0, _metadata3.get_phone_code)(country_metadata) + ' ' + national_number;
return '+' + (0, _metadata.get_phone_code)(country_metadata) + ' ' + national_number;
case 'International_plaintext':
return '+' + (0, _metadata3.get_phone_code)(country_metadata) + input.phone;
return '+' + (0, _metadata.get_phone_code)(country_metadata) + input.phone;

@@ -102,8 +93,13 @@ case 'National':

// group actually used in the pattern will be matched.
// 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
var FIRST_GROUP_PATTERN = exports.FIRST_GROUP_PATTERN = /(\$\d)/;
function format_national_number_using_format(number, format, international, enforce_national_prefix, country_metadata) {
var format_pattern_matcher = new RegExp((0, _metadata3.get_format_pattern)(format));
var format_pattern_matcher = new RegExp((0, _metadata.get_format_pattern)(format));
var national_prefix_formatting_rule = (0, _metadata3.get_format_national_prefix_formatting_rule)(format, country_metadata);
var national_prefix_formatting_rule = (0, _metadata.get_format_national_prefix_formatting_rule)(format, country_metadata);

@@ -114,14 +110,9 @@ // National prefix is omitted if there's no national prefix formatting rule

// (and it is not enforced explicitly)
var national_prefix_may_be_omitted = !national_prefix_formatting_rule || national_prefix_formatting_rule && (0, _metadata3.get_format_national_prefix_is_optional_when_formatting)(format, country_metadata) && !enforce_national_prefix;
var national_prefix_may_be_omitted = !national_prefix_formatting_rule || national_prefix_formatting_rule && (0, _metadata.get_format_national_prefix_is_optional_when_formatting)(format, country_metadata) && !enforce_national_prefix;
if (!international && !national_prefix_may_be_omitted) {
// If national prefix formatting rule is set
// (e.g. it is not set for US)
if (national_prefix_formatting_rule) {
return number.replace(format_pattern_matcher, (0, _metadata3.get_format_format)(format).replace(FIRST_GROUP_PATTERN, national_prefix_formatting_rule));
}
return number.replace(format_pattern_matcher, (0, _metadata.get_format_format)(format).replace(FIRST_GROUP_PATTERN, national_prefix_formatting_rule));
}
var formatted_number = number.replace(format_pattern_matcher, international ? (0, _metadata3.get_format_international_format)(format) : (0, _metadata3.get_format_format)(format));
var formatted_number = number.replace(format_pattern_matcher, international ? (0, _metadata.get_format_international_format)(format) : (0, _metadata.get_format_format)(format));

@@ -136,3 +127,3 @@ if (international) {

function format_national_number(number, format_as, enforce_national_prefix, country_metadata) {
var format = choose_format_for_number((0, _metadata3.get_formats)(country_metadata), number);
var format = choose_format_for_number((0, _metadata.get_formats)(country_metadata), number);

@@ -155,5 +146,5 @@ if (!format) {

if ((0, _metadata3.get_format_leading_digits_patterns)(_format).length > 0) {
if ((0, _metadata.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 = (0, _metadata3.get_format_leading_digits_patterns)(_format)[(0, _metadata3.get_format_leading_digits_patterns)(_format).length - 1];
var last_leading_digits_pattern = (0, _metadata.get_format_leading_digits_patterns)(_format)[(0, _metadata.get_format_leading_digits_patterns)(_format).length - 1];

@@ -165,3 +156,3 @@ if (national_number.search(last_leading_digits_pattern) !== 0) {

if ((0, _common.matches_entirely)(national_number, new RegExp((0, _metadata3.get_format_pattern)(_format)))) {
if ((0, _common.matches_entirely)(national_number, new RegExp((0, _metadata.get_format_pattern)(_format)))) {
return _format;

@@ -168,0 +159,0 @@ }

@@ -30,14 +30,6 @@ 'use strict';

var _metadata = require('../metadata.min');
var _metadata = require('./metadata');
var _metadata2 = _interopRequireDefault(_metadata);
var _metadata3 = require('./metadata');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var PLUS_CHARS = exports.PLUS_CHARS = '++';
// Digits accepted in phone numbers
// (ascii, fullwidth, arabic-indic, and eastern arabic digits).
// This is a port of Google Android `libphonenumber`'s

@@ -48,2 +40,6 @@ // `phonenumberutil.js` of 17th November, 2016.

var PLUS_CHARS = exports.PLUS_CHARS = '++';
// Digits accepted in phone numbers
// (ascii, fullwidth, arabic-indic, and eastern arabic digits).
var VALID_DIGITS = exports.VALID_DIGITS = '0-90-9٠-٩۰-۹';

@@ -211,3 +207,3 @@

var _parse_phone_number_a = parse_phone_number_and_country_phone_code(formatted_phone_number);
var _parse_phone_number_a = parse_phone_number_and_country_phone_code(formatted_phone_number, this.metadata);

@@ -228,7 +224,7 @@ var country_phone_code = _parse_phone_number_a.country_phone_code;

// Check country restriction
if (options.country.restrict && country_phone_code !== (0, _metadata3.get_phone_code)(_metadata2.default.countries[options.country.restrict])) {
if (options.country.restrict && country_phone_code !== (0, _metadata.get_phone_code)(this.metadata.countries[options.country.restrict])) {
return {};
}
country_metadata = (0, _metadata3.get_metadata_by_country_phone_code)(country_phone_code, _metadata2.default);
country_metadata = (0, _metadata.get_metadata_by_country_phone_code)(country_phone_code, this.metadata);

@@ -243,3 +239,3 @@ // `country` will be set later,

country = options.country.default || options.country.restrict;
country_metadata = _metadata2.default.countries[country];
country_metadata = this.metadata.countries[country];

@@ -262,3 +258,3 @@ number = normalize(text);

if (!country) {
country = find_country_code(country_phone_code, national_number);
country = find_country_code(country_phone_code, national_number, this.metadata);

@@ -285,3 +281,3 @@ // Just in case there's a bug in Google's metadata

var national_number_rule = new RegExp((0, _metadata3.get_national_number_pattern)(country_metadata));
var national_number_rule = new RegExp((0, _metadata.get_national_number_pattern)(country_metadata));

@@ -395,3 +391,3 @@ if (!(0, _common.matches_entirely)(national_number, national_number_rule)) {

//
function parse_phone_number_and_country_phone_code(number) {
function parse_phone_number_and_country_phone_code(number, metadata) {
number = parse_phone_number(number);

@@ -430,3 +426,3 @@

if (_metadata2.default.country_phone_code_to_countries[country_phone_code]) {
if (metadata.country_phone_code_to_countries[country_phone_code]) {
return { country_phone_code: country_phone_code, number: number.slice(i) };

@@ -443,3 +439,3 @@ }

function strip_national_prefix(number, country_metadata) {
var national_prefix_for_parsing = (0, _metadata3.get_national_prefix_for_parsing)(country_metadata);
var national_prefix_for_parsing = (0, _metadata.get_national_prefix_for_parsing)(country_metadata);

@@ -458,3 +454,3 @@ if (!number || !national_prefix_for_parsing) {

var national_prefix_transform_rule = (0, _metadata3.get_national_prefix_transform_rule)(country_metadata);
var national_prefix_transform_rule = (0, _metadata.get_national_prefix_transform_rule)(country_metadata);

@@ -474,3 +470,3 @@ var national_significant_number = void 0;

var national_number_rule = new RegExp((0, _metadata3.get_national_number_pattern)(country_metadata));
var national_number_rule = new RegExp((0, _metadata.get_national_number_pattern)(country_metadata));

@@ -485,5 +481,5 @@ // If the original number was viable, and the resultant number is not, then return.

function find_country_code(country_phone_code, national_phone_number) {
function find_country_code(country_phone_code, national_phone_number, metadata) {
// Is always non-empty, because `country_phone_code` is always valid
var possible_countries = _metadata2.default.country_phone_code_to_countries[country_phone_code];
var possible_countries = metadata.country_phone_code_to_countries[country_phone_code];

@@ -504,7 +500,7 @@ // If there's just one country corresponding to the country code,

var country = _metadata2.default.countries[country_code];
var country = metadata.countries[country_code];
// Leading digits check would be the simplest one
if ((0, _metadata3.get_leading_digits)(country)) {
if (national_phone_number && national_phone_number.search((0, _metadata3.get_leading_digits)(country)) === 0) {
if ((0, _metadata.get_leading_digits)(country)) {
if (national_phone_number && national_phone_number.search((0, _metadata.get_leading_digits)(country)) === 0) {
return country_code;

@@ -538,7 +534,7 @@ }

// Is this national number even valid for this country
if (!is_of_type(national_number, (0, _metadata3.get_national_number_pattern)(country_metadata))) {
if (!is_of_type(national_number, (0, _metadata.get_national_number_pattern)(country_metadata))) {
return;
}
if (is_of_type(national_number, (0, _metadata3.get_type_mobile)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_mobile)(country_metadata))) {
// Because duplicate regular expressions are removed

@@ -550,3 +546,3 @@ // to reduce metadata size, if there's no "fixed line" pattern

/* istanbul ignore if */
if (!(0, _metadata3.get_type_fixed_line)(country_metadata)) {
if (!(0, _metadata.get_type_fixed_line)(country_metadata)) {
return 'FIXED_LINE_OR_MOBILE';

@@ -559,7 +555,7 @@ }

// Is it fixed line number
if (is_of_type(national_number, (0, _metadata3.get_type_fixed_line)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_fixed_line)(country_metadata))) {
// Because duplicate regular expressions are removed
// to reduce metadata size, if there's no "mobile" pattern
// then it means it was removed due to being a duplicate of some other pattern.
if (!(0, _metadata3.get_type_mobile)(country_metadata)) {
if (!(0, _metadata.get_type_mobile)(country_metadata)) {
return 'FIXED_LINE_OR_MOBILE';

@@ -571,11 +567,11 @@ }

if (is_of_type(national_number, (0, _metadata3.get_type_toll_free)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_toll_free)(country_metadata))) {
return 'TOLL_FREE';
}
if (is_of_type(national_number, (0, _metadata3.get_type_premium_rate)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_premium_rate)(country_metadata))) {
return 'PREMIUM_RATE';
}
if (is_of_type(national_number, (0, _metadata3.get_type_personal_number)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_personal_number)(country_metadata))) {
return 'PERSONAL_NUMBER';

@@ -585,3 +581,3 @@ }

/* istanbul ignore if */
if (is_of_type(national_number, (0, _metadata3.get_type_voice_mail)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_voice_mail)(country_metadata))) {
return 'VOICEMAIL';

@@ -591,3 +587,3 @@ }

/* istanbul ignore if */
if (is_of_type(national_number, (0, _metadata3.get_type_uan)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_uan)(country_metadata))) {
return 'UAN';

@@ -597,3 +593,3 @@ }

/* istanbul ignore if */
if (is_of_type(national_number, (0, _metadata3.get_type_pager)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_pager)(country_metadata))) {
return 'PAGER';

@@ -603,3 +599,3 @@ }

/* istanbul ignore if */
if (is_of_type(national_number, (0, _metadata3.get_type_voip)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_voip)(country_metadata))) {
return 'VOIP';

@@ -609,3 +605,3 @@ }

/* istanbul ignore if */
if (is_of_type(national_number, (0, _metadata3.get_type_shared_cost)(country_metadata))) {
if (is_of_type(national_number, (0, _metadata.get_type_shared_cost)(country_metadata))) {
return 'SHARED_COST';

@@ -612,0 +608,0 @@ }

@@ -20,5 +20,5 @@ 'use strict';

function is_valid(number, country_code) {
return (0, _keys2.default)((0, _parse2.default)(number, country_code)).length > 0;
return (0, _keys2.default)(_parse2.default.call(this, number, country_code)).length > 0;
}
module.exports = exports['default'];
//# sourceMappingURL=validate.js.map

@@ -0,1 +1,6 @@

0.2.20 / 28.12.2016
===================
* Added the ability to use custom-countries generated metadata as a parameter for the functions exported from this library
0.2.19 / 25.12.2016

@@ -2,0 +7,0 @@ ===================

'use strict'
var metadata = require('./metadata.min')
var custom = require('./custom')
exports = module.exports = {}
exports.parse = require('./build/parse').default
exports.format = require('./build/format').default
var context = { metadata: metadata }
exports.is_valid_number = require('./build/validate')
exports.isValidNumber = require('./build/validate')
exports.parse = custom.parse.bind(context)
exports.format = custom.format.bind(context)
exports.as_you_type = require('./build/as you type').default
exports.asYouType = require('./build/as you type').default
exports.is_valid_number = custom.is_valid_number.bind(context)
exports.isValidNumber = exports.is_valid_number
exports.metadata = require('./metadata.min')
exports.as_you_type = custom.as_you_type(metadata)
exports.asYouType = exports.as_you_type
exports.get_phone_code = require('./build/metadata').get_phone_code
exports.getPhoneCode = require('./build/metadata').get_phone_code
// exports['default'] = ...

@@ -1,38 +0,19 @@

export
{
default as parse
}
from './source/parse'
import metadata from './metadata.min'
export
import
{
default as format
parse as _parse,
format as _format,
is_valid_number as _is_valid_number,
as_you_type as _as_you_type
}
from './source/format'
from './custom.es6'
export
{
default as is_valid_number,
default as isValidNumber
}
from './source/validate'
export const parse = _parse.bind({ metadata })
export const format = _format.bind({ metadata })
export
{
default as as_you_type,
default as asYouType
}
from './source/as you type'
export const is_valid_number = _is_valid_number.bind({ metadata })
export const isValidNumber = is_valid_number
export
{
default as metadata
}
from './metadata.min'
export
{
get_phone_code,
get_phone_code as getPhoneCode
}
from './source/metadata'
export const as_you_type = _as_you_type(metadata)
export const asYouType = as_you_type
{
"name": "libphonenumber-js",
"version": "0.2.19",
"version": "0.2.20",
"description": "A simpler (and smaller) rewrite of Google Android's popular libphonenumber library",

@@ -5,0 +5,0 @@ "main": "index.common.js",

@@ -196,5 +196,18 @@ # libphonenumber-js

npm run metadata:generate NL,BE,FR,DE,LU,AT
# The resulting `metadata.min.json` will only contain those countries
```
Then use the generated `metadata.min.json` with the `libphonenumber-js/custom` functions
```js
import { parse, format, isValidNumber, asYouType } from 'libphonenumber-js/custom'
import metadata from './metadata.min.json'
const parseCustomCountries = parse.bind({ metadata })
const formatCustomCountries = format.bind({ metadata })
const isValidNumberCustomCountries = isValidNumber.bind({ metadata })
const asYouTypeCustomCountries = asYouType(metadata)
```
For utilizing "tree-shaking" in ES6-capable bundlers (e.g. Webpack 2) `libphonenumber-js/custom.es6` may be used.
## Contributing

@@ -201,0 +214,0 @@

@@ -6,4 +6,2 @@ // This is an enhanced port of Google Android `libphonenumber`'s

import metadata from '../metadata.min'
import

@@ -108,544 +106,540 @@ {

export default class as_you_type
export default function(metadata)
{
constructor(country_code)
class as_you_type
{
if (country_code && metadata.countries[country_code])
constructor(country_code)
{
this.default_country = country_code
if (country_code && metadata.countries[country_code])
{
this.default_country = country_code
}
this.reset()
}
this.reset()
}
input(text)
{
// Parse input
input(text)
{
// Parse input
let extracted_number = extract_formatted_phone_number(text)
let extracted_number = extract_formatted_phone_number(text)
// Special case for a lone '+' sign
// since it's not considered a possible phone number.
if (!extracted_number)
{
if (text && text.indexOf('+') >= 0)
{
extracted_number = '+'
}
}
// Special case for a lone '+' sign
// since it's not considered a possible phone number.
if (!extracted_number)
{
if (text && text.indexOf('+') >= 0)
// Validate possible first part of a phone number
if (!matches_entirely(extracted_number, VALID_INCOMPLETE_PHONE_NUMBER_PATTERN))
{
extracted_number = '+'
return this.current_output
}
}
// Validate possible first part of a phone number
if (!matches_entirely(extracted_number, VALID_INCOMPLETE_PHONE_NUMBER_PATTERN))
{
return this.current_output
return this.process_input(parse_phone_number(extracted_number))
}
return this.process_input(parse_phone_number(extracted_number))
}
process_input(input)
{
// If an out of position '+' sign detected
// (or a second '+' sign),
// then just drop it from the input.
if (input[0] === '+')
process_input(input)
{
if (!this.parsed_input)
// If an out of position '+' sign detected
// (or a second '+' sign),
// then just drop it from the input.
if (input[0] === '+')
{
this.parsed_input += '+'
if (!this.parsed_input)
{
this.parsed_input += '+'
// If a default country was set
// then reset it because an explicitly international
// phone number is being entered
this.reset_countriness()
// If a default country was set
// then reset it because an explicitly international
// phone number is being entered
this.reset_countriness()
}
input = input.slice(1)
}
input = input.slice(1)
}
// Raw phone number
this.parsed_input += input
// Raw phone number
this.parsed_input += input
// Reset phone number validation state
this.valid = false
// Reset phone number validation state
this.valid = false
// Add digits to the national number
this.national_number += input
// Add digits to the national number
this.national_number += input
// Try to format the parsed input
// Try to format the parsed input
if (this.is_international())
{
if (!this.country_phone_code)
{
// If one looks at country phone codes
// then he can notice that no one country phone code
// is ever a (leftmost) substring of another country phone code.
// So if a valid country code is extracted so far
// then it means that this is the country code.
if (this.is_international())
{
if (!this.country_phone_code)
// If no country phone code could be extracted so far,
// then just return the raw phone number,
// because it has no way of knowing
// how to format the phone number so far.
if (!this.extract_country_phone_code())
{
// Return raw phone number
return this.parsed_input
}
// Initialize country-specific data
this.initialize_phone_number_formats_for_this_country_phone_code()
this.reset_format()
this.determine_the_country()
}
// `this.country` could be `undefined`,
// for instance, when there is ambiguity
// in a form of several different countries
// each corresponding to the same country phone code
// (e.g. NANPA: USA, Canada, etc),
// and there's not enough digits entered
// to reliably determine the country
// the phone number belongs to.
// Therefore, in cases of such ambiguity,
// each time something is input,
// try to determine the country
// (if it's not determined yet).
else if (!this.country)
{
this.determine_the_country()
}
}
else
{
// If one looks at country phone codes
// then he can notice that no one country phone code
// is ever a (leftmost) substring of another country phone code.
// So if a valid country code is extracted so far
// then it means that this is the country code.
// Some national prefixes are substrings of other national prefixes
// (for the same country), therefore try to extract national prefix each time
// because a longer national prefix might be available at some point in time.
// If no country phone code could be extracted so far,
// then just return the raw phone number,
// because it has no way of knowing
// how to format the phone number so far.
if (!this.extract_country_phone_code())
const previous_national_prefix = this.national_prefix
this.national_number = this.national_prefix + this.national_number
// Possibly extract a national prefix
this.extract_national_prefix()
if (this.national_prefix !== previous_national_prefix)
{
// Return raw phone number
return this.parsed_input
// National number has changed
// (due to another national prefix been extracted)
// therefore national number has changed
// therefore reset all previous formatting data.
// (and leading digits matching state)
this.matching_formats = this.available_formats
this.reset_format()
}
}
// Initialize country-specific data
this.initialize_phone_number_formats_for_this_country_phone_code()
this.reset_format()
this.determine_the_country()
}
// `this.country` could be `undefined`,
// for instance, when there is ambiguity
// in a form of several different countries
// each corresponding to the same country phone code
// (e.g. NANPA: USA, Canada, etc),
// and there's not enough digits entered
// to reliably determine the country
// the phone number belongs to.
// Therefore, in cases of such ambiguity,
// each time something is input,
// try to determine the country
// (if it's not determined yet).
else if (!this.country)
// Format the phone number (given the next digits)
const formatted_national_phone_number = this.format_national_phone_number(input)
// If the phone number could be formatted,
// then return it, possibly prepending with country phone code
// (for international phone numbers only)
if (formatted_national_phone_number)
{
this.determine_the_country()
return this.full_phone_number(formatted_national_phone_number)
}
// If the phone number couldn't be formatted,
// then just fall back to the raw phone number.
return this.parsed_input
}
else
format_national_phone_number(next_digits)
{
// Some national prefixes are substrings of other national prefixes
// (for the same country), therefore try to extract national prefix each time
// because a longer national prefix might be available at some point in time.
// Format the next phone number digits
// using the previously chosen phone number format.
//
// This is done here because if `attempt_to_format_complete_phone_number`
// was placed before this call then the `template`
// wouldn't reflect the situation correctly (and would therefore be inconsistent)
//
let national_number_formatted_with_previous_format
if (this.chosen_format)
{
national_number_formatted_with_previous_format = this.format_next_national_number_digits(next_digits)
}
const previous_national_prefix = this.national_prefix
this.national_number = this.national_prefix + this.national_number
// See if the input digits can be formatted properly already. If not,
// use the results from format_next_national_number_digits(), which does formatting
// based on the formatting pattern chosen.
// Possibly extract a national prefix
this.extract_national_prefix()
const formatted_number = this.attempt_to_format_complete_phone_number()
if (this.national_prefix !== previous_national_prefix)
if (formatted_number)
{
// National number has changed
// (due to another national prefix been extracted)
// therefore national number has changed
// therefore reset all previous formatting data.
// (and leading digits matching state)
this.matching_formats = this.available_formats
this.reset_format()
this.valid = true
return formatted_number
}
}
// Format the phone number (given the next digits)
const formatted_national_phone_number = this.format_national_phone_number(input)
// Check if the previously chosen phone number format still holds
this.match_formats_by_leading_digits()
// If the phone number could be formatted,
// then return it, possibly prepending with country phone code
// (for international phone numbers only)
if (formatted_national_phone_number)
{
return this.full_phone_number(formatted_national_phone_number)
}
// If the previously chosen phone number format
// didn't match the next (current) digit being input
// (leading digits pattern didn't match).
if (this.choose_another_format())
{
// And a more appropriate phone number format
// has been chosen for these `leading digits`,
// then format the national phone number (so far)
// using the newly selected phone number pattern.
// If the phone number couldn't be formatted,
// then just fall back to the raw phone number.
return this.parsed_input
}
// Will return `undefined` if it couldn't format
// the supplied national number
// using the selected phone number pattern.
format_national_phone_number(next_digits)
{
// Format the next phone number digits
// using the previously chosen phone number format.
//
// This is done here because if `attempt_to_format_complete_phone_number`
// was placed before this call then the `template`
// wouldn't reflect the situation correctly (and would therefore be inconsistent)
//
let national_number_formatted_with_previous_format
if (this.chosen_format)
{
national_number_formatted_with_previous_format = this.format_next_national_number_digits(next_digits)
}
return this.reformat_national_number()
}
// See if the input digits can be formatted properly already. If not,
// use the results from format_next_national_number_digits(), which does formatting
// based on the formatting pattern chosen.
// If could format the next (current) digit
// using the previously chosen phone number format
// then return the formatted number so far.
const formatted_number = this.attempt_to_format_complete_phone_number()
// If no new phone number format could be chosen,
// and couldn't format the supplied national number
// using the selected phone number pattern,
// then it will return `undefined`.
if (formatted_number)
{
this.valid = true
return formatted_number
return national_number_formatted_with_previous_format
}
// Check if the previously chosen phone number format still holds
this.match_formats_by_leading_digits()
// If the previously chosen phone number format
// didn't match the next (current) digit being input
// (leading digits pattern didn't match).
if (this.choose_another_format())
reset()
{
// And a more appropriate phone number format
// has been chosen for these `leading digits`,
// then format the national phone number (so far)
// using the newly selected phone number pattern.
// Input stripped of non-phone-number characters.
// Can only contain a possible leading '+' sign and digits.
this.parsed_input = ''
// Will return `undefined` if it couldn't format
// the supplied national number
// using the selected phone number pattern.
this.current_output = ''
return this.reformat_national_number()
}
// This contains the national prefix that has been extracted. It contains only
// digits without formatting.
this.national_prefix = ''
// If could format the next (current) digit
// using the previously chosen phone number format
// then return the formatted number so far.
this.national_number = ''
// If no new phone number format could be chosen,
// and couldn't format the supplied national number
// using the selected phone number pattern,
// then it will return `undefined`.
this.reset_countriness()
return national_number_formatted_with_previous_format
}
this.reset_format()
reset()
{
// Input stripped of non-phone-number characters.
// Can only contain a possible leading '+' sign and digits.
this.parsed_input = ''
this.valid = false
this.current_output = ''
return this
}
// This contains the national prefix that has been extracted. It contains only
// digits without formatting.
this.national_prefix = ''
reset_country()
{
if (this.default_country && !this.is_international())
{
this.country = this.default_country
}
else
{
this.country = undefined
}
}
this.national_number = ''
reset_countriness()
{
this.reset_country()
this.reset_countriness()
if (this.default_country && !this.is_international())
{
this.country_metadata = metadata.countries[this.default_country]
this.country_phone_code = this.country_metadata.phone_code
this.reset_format()
this.initialize_phone_number_formats_for_this_country_phone_code()
}
else
{
this.country_metadata = undefined
this.country_phone_code = undefined
this.valid = false
this.available_formats = []
this.matching_formats = this.available_formats
}
}
return this
}
reset_country()
{
if (this.default_country && !this.is_international())
reset_format()
{
this.country = this.default_country
this.chosen_format = undefined
this.template = undefined
this.partially_populated_template = undefined
this.last_match_position = -1
}
else
// Format each digit of national phone number (so far)
// using the newly selected phone number pattern.
reformat_national_number()
{
this.country = undefined
// Format each digit of national phone number (so far)
// using the selected phone number pattern.
return this.format_next_national_number_digits(this.national_number)
}
}
reset_countriness()
{
this.reset_country()
if (this.default_country && !this.is_international())
initialize_phone_number_formats_for_this_country_phone_code()
{
this.country_metadata = metadata.countries[this.default_country]
this.country_phone_code = this.country_metadata.phone_code
// Get all "eligible" phone number formats for this country
this.available_formats = get_formats(this.country_metadata).filter((format) =>
{
return ELIGIBLE_FORMAT_PATTERN.test(get_format_international_format(format))
})
// Try the formats with "leading digits" defined first
.sort((a, b) =>
{
// Leading digits are defined for most formats
/* istanbul ignore next */
if (get_format_leading_digits_patterns(a).length === 0
&& get_format_leading_digits_patterns(b).length > 0)
{
return -1
}
this.initialize_phone_number_formats_for_this_country_phone_code()
}
else
{
this.country_metadata = undefined
this.country_phone_code = undefined
// Leading digits are defined for most formats
/* istanbul ignore next */
if (get_format_leading_digits_patterns(a).length > 0
&& get_format_leading_digits_patterns(b).length === 0)
{
return 1
}
this.available_formats = []
return 0
})
this.matching_formats = this.available_formats
}
}
reset_format()
{
this.chosen_format = undefined
this.template = undefined
this.partially_populated_template = undefined
this.last_match_position = -1
}
match_formats_by_leading_digits()
{
const leading_digits = this.national_number
// Format each digit of national phone number (so far)
// using the newly selected phone number pattern.
reformat_national_number()
{
// Format each digit of national phone number (so far)
// using the selected phone number pattern.
return this.format_next_national_number_digits(this.national_number)
}
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
initialize_phone_number_formats_for_this_country_phone_code()
{
// Get all "eligible" phone number formats for this country
this.available_formats = get_formats(this.country_metadata).filter((format) =>
{
return ELIGIBLE_FORMAT_PATTERN.test(get_format_international_format(format))
})
// Try the formats with "leading digits" defined first
.sort((a, b) =>
{
// Leading digits are defined for most formats
/* istanbul ignore next */
if (get_format_leading_digits_patterns(a).length === 0
&& get_format_leading_digits_patterns(b).length > 0)
let index_of_leading_digits_pattern = leading_digits.length - MIN_LEADING_DIGITS_LENGTH
if (index_of_leading_digits_pattern < 0)
{
return -1
index_of_leading_digits_pattern = 0
}
// Leading digits are defined for most formats
/* istanbul ignore next */
if (get_format_leading_digits_patterns(a).length > 0
&& get_format_leading_digits_patterns(b).length === 0)
this.matching_formats = this.get_relevant_phone_number_formats().filter((format) =>
{
return 1
}
const leading_digits_pattern_count = get_format_leading_digits_patterns(format).length
return 0
})
// Keep everything that isn't restricted by leading digits.
if (leading_digits_pattern_count === 0)
{
return true
}
this.matching_formats = this.available_formats
}
const leading_digits_pattern_index = Math.min(index_of_leading_digits_pattern, leading_digits_pattern_count - 1)
const leading_digits_pattern = get_format_leading_digits_patterns(format)[leading_digits_pattern_index]
return new RegExp('^' + leading_digits_pattern).test(leading_digits)
})
}
match_formats_by_leading_digits()
{
const leading_digits = this.national_number
get_relevant_phone_number_formats()
{
const leading_digits = this.national_number
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
let index_of_leading_digits_pattern = leading_digits.length - MIN_LEADING_DIGITS_LENGTH
if (leading_digits.length <= MIN_LEADING_DIGITS_LENGTH)
{
return this.available_formats
}
if (index_of_leading_digits_pattern < 0)
{
index_of_leading_digits_pattern = 0
return this.matching_formats
}
this.matching_formats = this.get_relevant_phone_number_formats().filter((format) =>
// Check to see if there is an exact pattern match for these digits. If so, we
// should use this instead of any other formatting template whose
// leadingDigitsPattern also matches the input.
attempt_to_format_complete_phone_number()
{
const leading_digits_pattern_count = get_format_leading_digits_patterns(format).length
// Keep everything that isn't restricted by leading digits.
if (leading_digits_pattern_count === 0)
for (let format of this.get_relevant_phone_number_formats())
{
return true
}
const matcher = new RegExp('^(?:' + get_format_pattern(format) + ')$')
const leading_digits_pattern_index = Math.min(index_of_leading_digits_pattern, leading_digits_pattern_count - 1)
const leading_digits_pattern = get_format_leading_digits_patterns(format)[leading_digits_pattern_index]
return new RegExp('^' + leading_digits_pattern).test(leading_digits)
})
}
if (!matcher.test(this.national_number))
{
// If the national prefix is optional
// then also try to format the phone number
// without the national prefix being extracted.
if (this.national_prefix
&& get_format_national_prefix_is_optional_when_formatting(format, this.country_metadata))
{
if (!matcher.test(this.national_prefix + this.national_number))
{
continue
}
get_relevant_phone_number_formats()
{
const leading_digits = this.national_number
this.national_number = this.national_prefix + this.national_number
this.national_prefix = ''
}
// "leading digits" patterns start with a maximum 3 digits,
// and then with each additional digit
// a more precise "leading digits" pattern is specified.
// They could make "leading digits" patterns start
// with a maximum of a single digit, but they didn't,
// so it's possible that some phone number formats
// will be falsely rejected until there are at least
// 3 digits in the national (significant) number being input.
continue
}
if (leading_digits.length <= MIN_LEADING_DIGITS_LENGTH)
{
return this.available_formats
}
if (!this.validate_format(format))
{
continue
}
return this.matching_formats
}
// To leave the formatter in a consistent state
this.reset_format()
this.chosen_format = format
// Check to see if there is an exact pattern match for these digits. If so, we
// should use this instead of any other formatting template whose
// leadingDigitsPattern also matches the input.
attempt_to_format_complete_phone_number()
{
for (let format of this.get_relevant_phone_number_formats())
{
const matcher = new RegExp('^(?:' + get_format_pattern(format) + ')$')
let matches = false
let discard_national_prefix = false
const formatted_number = format_national_number_using_format
(
this.national_number,
format,
this.is_international(),
this.national_prefix.length > 0,
this.country_metadata
)
// If the national prefix is optional
// then also try to format the phone number
// without the national prefix being extracted.
if (this.national_prefix
&& get_format_national_prefix_is_optional_when_formatting(format, this.country_metadata))
{
matches = matcher.test(this.national_prefix + this.national_number)
if (matches)
// Set `this.template` and `this.partially_populated_template`
//
// `else` case doesn't ever happen
// with the current metadata,
// but just in case.
//
/* istanbul ignore else */
if (this.create_formatting_template(format))
{
discard_national_prefix = true
// Populate `this.partially_populated_template`
this.reformat_national_number()
}
}
else
{
const full_number = this.full_phone_number(formatted_number)
matches = matches || matcher.test(this.national_number)
this.template = full_number.replace(/[\d\+]/g, DIGIT_PLACEHOLDER)
this.partially_populated_template = full_number
}
if (!matches)
{
continue
return formatted_number
}
}
if (discard_national_prefix)
// Combines the national number with the appropriate prefix
full_phone_number(formatted_national_number)
{
if (this.is_international())
{
this.national_number = this.national_prefix + this.national_number
this.national_prefix = ''
return `+${this.country_phone_code} ${formatted_national_number}`
}
if (!this.validate_format(format))
return formatted_national_number
}
// Extracts the country calling code from the beginning
// of the entered `national_number` (so far),
// and places the remaining input into the `national_number`.
extract_country_phone_code()
{
if (!this.national_number)
{
continue
return
}
// To leave the formatter in a consistent state
this.reset_format()
this.chosen_format = format
const { country_phone_code, number } = parse_phone_number_and_country_phone_code(this.parsed_input, metadata)
const number_pattern = this.validate_format_for_template(format)
const formatted_number = format_national_number_using_format
(
this.national_number,
format,
this.is_international(),
this.national_prefix.length > 0,
this.country_metadata
)
if (number_pattern)
if (!country_phone_code)
{
// Set `this.template` and `this.partially_populated_template`
this.create_formatting_template(format, number_pattern)
// Populate `this.partially_populated_template`
this.reformat_national_number()
return
}
else
{
const full_number = this.full_phone_number(formatted_number)
this.template = full_number.replace(/[\d\+]/g, DIGIT_PLACEHOLDER)
this.partially_populated_template = full_number
}
this.country_phone_code = country_phone_code
this.national_number = number
return formatted_number
return this.country_metadata = get_metadata_by_country_phone_code(country_phone_code, metadata)
}
}
// Combines the national number with the appropriate prefix
full_phone_number(formatted_national_number)
{
if (this.is_international())
extract_national_prefix()
{
return `+${this.country_phone_code} ${formatted_national_number}`
}
this.national_prefix = ''
return formatted_national_number
}
if (!this.country_metadata)
{
return
}
// Extracts the country calling code from the beginning
// of the entered `national_number` (so far),
// and places the remaining input into the `national_number`.
extract_country_phone_code()
{
if (!this.national_number)
{
return
}
const national_prefix_for_parsing = get_national_prefix_for_parsing(this.country_metadata)
const { country_phone_code, number } = parse_phone_number_and_country_phone_code(this.parsed_input)
if (!national_prefix_for_parsing)
{
return
}
if (!country_phone_code)
{
return
}
const matches = this.national_number.match(new RegExp('^(?:' + national_prefix_for_parsing + ')'))
this.country_phone_code = country_phone_code
this.national_number = number
// Since some national prefix patterns are entirely optional, check that a
// national prefix could actually be extracted.
if (!matches || !matches[0])
{
return
}
return this.country_metadata = get_metadata_by_country_phone_code(country_phone_code, metadata)
}
const national_number_starts_at = matches[0].length
extract_national_prefix()
{
this.national_prefix = ''
this.national_prefix = this.national_number.slice(0, national_number_starts_at)
this.national_number = this.national_number.slice(national_number_starts_at)
if (!this.country_metadata)
{
return
return this.national_prefix
}
const national_prefix_for_parsing = get_national_prefix_for_parsing(this.country_metadata)
if (!national_prefix_for_parsing)
choose_another_format()
{
return
}
const matches = this.national_number.match(new RegExp('^(?:' + national_prefix_for_parsing + ')'))
// Since some national prefix patterns are entirely optional, check that a
// national prefix could actually be extracted.
if (!matches || !matches[0])
{
return
}
const national_number_starts_at = matches[0].length
this.national_prefix = this.national_number.slice(0, national_number_starts_at)
this.national_number = this.national_number.slice(national_number_starts_at)
return this.national_prefix
}
choose_another_format()
{
// When there are multiple available formats, the formatter uses the first
// format where a formatting template could be created.
for (let format of this.get_relevant_phone_number_formats())
{
// If this format is currently being used
// and is still possible, then stick to it.
if (this.chosen_format === format)
// When there are multiple available formats, the formatter uses the first
// format where a formatting template could be created.
for (let format of this.get_relevant_phone_number_formats())
{
return
}
// If this format is currently being used
// and is still possible, then stick to it.
if (this.chosen_format === format)
{
return
}
// If this `format` is suitable for "as you type",
// then extract the template from this format
// and use it to format the phone number being input.
// If this `format` is suitable for "as you type",
// then extract the template from this format
// and use it to format the phone number being input.
if (!this.validate_format(format))
{
continue
}
if (!this.validate_format(format))
{
continue
}
const number_pattern = this.validate_format_for_template(format)
if (!this.create_formatting_template(format))
{
continue
}
if (number_pattern)
{
this.create_formatting_template(format, number_pattern)
this.chosen_format = format

@@ -659,174 +653,166 @@

}
}
// No format matches the phone number,
// therefore set `country` to `undefined`
// (or to the default country).
this.reset_country()
// No format matches the phone number,
// therefore set `country` to `undefined`
// (or to the default country).
this.reset_country()
// No format matches the national phone number entered
this.reset_format()
}
// No format matches the national phone number entered
this.reset_format()
}
validate_format(format)
{
// If national prefix is mandatory for this phone number format
// and the user didn't input the national prefix,
// then this phone number format isn't suitable.
if (!this.is_international() && !this.national_prefix && get_format_national_prefix_is_mandatory_when_formatting(format, this.country_metadata))
validate_format(format)
{
return
// If national prefix is mandatory for this phone number format
// and the user didn't input the national prefix,
// then this phone number format isn't suitable.
if (!this.is_international() && !this.national_prefix && get_format_national_prefix_is_mandatory_when_formatting(format, this.country_metadata))
{
return
}
return true
}
return true
}
validate_format_for_template(format)
{
// The formatter doesn't format numbers when numberPattern contains '|', e.g.
// (20|3)\d{4}. In those cases we quickly return.
// (Though there's no such format in current metadata)
/* istanbul ignore if */
if (get_format_pattern(format).indexOf('|') >= 0)
create_formatting_template(format)
{
return
}
// The formatter doesn't format numbers when numberPattern contains '|', e.g.
// (20|3)\d{4}. In those cases we quickly return.
// (Though there's no such format in current metadata)
/* istanbul ignore if */
if (get_format_pattern(format).indexOf('|') >= 0)
{
return
}
const national_prefix_formatting_rule = get_format_national_prefix_formatting_rule(format, this.country_metadata)
const national_prefix_formatting_rule = get_format_national_prefix_formatting_rule(format, this.country_metadata)
// A very smart trick by the guys at Google
const number_pattern = get_format_pattern(format)
// Replace anything in the form of [..] with \d
.replace(CHARACTER_CLASS_PATTERN, '\\d')
// Replace any standalone digit (not the one in `{}`) with \d
.replace(STANDALONE_DIGIT_PATTERN, '\\d')
// A very smart trick by the guys at Google
const number_pattern = get_format_pattern(format)
// Replace anything in the form of [..] with \d
.replace(CHARACTER_CLASS_PATTERN, '\\d')
// Replace any standalone digit (not the one in `{}`) with \d
.replace(STANDALONE_DIGIT_PATTERN, '\\d')
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
const dummy_phone_number_matching_format_pattern = LONGEST_DUMMY_PHONE_NUMBER.match(number_pattern)[0]
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
const dummy_phone_number_matching_format_pattern = LONGEST_DUMMY_PHONE_NUMBER.match(number_pattern)[0]
// If the national number entered is too long
// for any phone number format, then abort.
if (this.national_number.length > dummy_phone_number_matching_format_pattern.length)
{
return
}
// If the national number entered is too long
// for any phone number format, then abort.
if (this.national_number.length > dummy_phone_number_matching_format_pattern.length)
{
return
}
return number_pattern
}
// Now prepare phone number format
let number_format = this.get_format_format(format)
create_formatting_template(format, number_pattern)
{
let number_format = this.get_format_format(format)
// If the user did input the national prefix
// then maybe make it a part of the phone number template
if (this.national_prefix)
{
const national_prefix_formatting_rule = get_format_national_prefix_formatting_rule(format, this.country_metadata)
// If the user did input the national prefix
// then maybe make it a part of the phone number template
if (this.national_prefix)
{
const national_prefix_formatting_rule = get_format_national_prefix_formatting_rule(format, this.country_metadata)
// If national prefix formatting rule is set
// for this phone number format
if (national_prefix_formatting_rule)
{
// Make the national prefix a part of the phone number template
number_format = number_format.replace(FIRST_GROUP_PATTERN, national_prefix_formatting_rule)
}
}
// If national prefix formatting rule is set
// for this phone number format
if (national_prefix_formatting_rule)
// Get a formatting template which can be used to efficiently format
// a partial number where digits are added one by one.
// Create formatting template for this phone number format
let template = dummy_phone_number_matching_format_pattern
// Format the dummy phone number according to the format
.replace(new RegExp(number_pattern, 'g'), number_format)
// Replace each dummy digit with a DIGIT_PLACEHOLDER
.replace(DUMMY_DIGIT_MATCHER, DIGIT_PLACEHOLDER)
// This one is for national number only
this.partially_populated_template = template
// For convenience, the public `.template` property
// is gonna contain the whole international number
// if the phone number being input is international.
if (this.is_international())
{
// Make the national prefix a part of the phone number template
number_format = number_format.replace(FIRST_GROUP_PATTERN, national_prefix_formatting_rule)
template = DIGIT_PLACEHOLDER + repeat(DIGIT_PLACEHOLDER, this.country_phone_code.length) + ' ' + template
}
// For local numbers, replace national prefix
// with a digit placeholder.
else
{
template = template.replace(/\d/g, DIGIT_PLACEHOLDER)
}
// This one is for the full phone number
return this.template = template
}
// Get a formatting template which can be used to efficiently format
// a partial number where digits are added one by one.
format_next_national_number_digits(digits)
{
for (let digit of digits)
{
// If there is room for more digits in current `template`,
// then set the next digit in the `template`,
// and return the formatted digits so far.
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
const dummy_phone_number_matching_format_pattern = LONGEST_DUMMY_PHONE_NUMBER.match(number_pattern)[0]
// If more digits are entered than the current format could handle
if (this.partially_populated_template.slice(this.last_match_position + 1).search(DIGIT_PLACEHOLDER_MATCHER) === -1)
{
// Reset the current format,
// so that the new format will be chosen
// in a subsequent `this.choose_another_format()` call
// later in code.
this.chosen_format = undefined
this.template = undefined
this.partially_populated_template = undefined
return
}
// Create formatting template for this phone number format
let template = dummy_phone_number_matching_format_pattern
// Format the dummy phone number according to the format
.replace(new RegExp(number_pattern, 'g'), number_format)
// Replace each dummy digit with a DIGIT_PLACEHOLDER
.replace(DUMMY_DIGIT_MATCHER, DIGIT_PLACEHOLDER)
this.last_match_position = this.partially_populated_template.search(DIGIT_PLACEHOLDER_MATCHER)
this.partially_populated_template = this.partially_populated_template.replace(DIGIT_PLACEHOLDER_MATCHER, digit)
}
// This one is for national number only
this.partially_populated_template = template
// Return the formatted phone number so far
return close_dangling_braces(this.partially_populated_template, this.last_match_position + 1)
.replace(DIGIT_PLACEHOLDER_MATCHER_GLOBAL, ' ')
}
// For convenience, the public `.template` property
// is gonna contain the whole international number
// if the phone number being input is international.
if (this.is_international())
is_international()
{
template = DIGIT_PLACEHOLDER + repeat(DIGIT_PLACEHOLDER, this.country_phone_code.length) + ' ' + template
return this.parsed_input && this.parsed_input[0] === '+'
}
// For local numbers, replace national prefix
// with a digit placeholder.
else
{
template = template.replace(/\d/g, DIGIT_PLACEHOLDER)
}
// This one is for the full phone number
this.template = template
}
format_next_national_number_digits(digits)
{
for (let digit of digits)
get_format_format(format)
{
// If there is room for more digits in current `template`,
// then set the next digit in the `template`,
// and return the formatted digits so far.
// If more digits are entered than the current format could handle
if (this.partially_populated_template.slice(this.last_match_position + 1).search(DIGIT_PLACEHOLDER_MATCHER) === -1)
if (this.is_international())
{
// Reset the current format,
// so that the new format will be chosen
// in a subsequent `this.choose_another_format()` call
// later in code.
this.chosen_format = undefined
this.template = undefined
this.partially_populated_template = undefined
return
return local_to_international_style(get_format_international_format(format))
}
this.last_match_position = this.partially_populated_template.search(DIGIT_PLACEHOLDER_MATCHER)
this.partially_populated_template = this.partially_populated_template.replace(DIGIT_PLACEHOLDER_MATCHER, digit)
return get_format_format(format)
}
// Return the formatted phone number so far
return close_dangling_braces(this.partially_populated_template, this.last_match_position + 1)
.replace(DIGIT_PLACEHOLDER_MATCHER_GLOBAL, ' ')
}
is_international()
{
return this.parsed_input && this.parsed_input[0] === '+'
}
get_format_format(format)
{
if (this.is_international())
// Determines the country of the phone number
// entered so far based on the country phone code
// and the national phone number.
determine_the_country()
{
return local_to_international_style(get_format_international_format(format))
this.country = find_country_code(this.country_phone_code, this.national_number, metadata)
}
return get_format_format(format)
}
// Determines the country of the phone number
// entered so far based on the country phone code
// and the national phone number.
determine_the_country()
{
this.country = find_country_code(this.country_phone_code, this.national_number)
}
as_you_type.DIGIT_PLACEHOLDER = DIGIT_PLACEHOLDER
return as_you_type
}
as_you_type.DIGIT_PLACEHOLDER = DIGIT_PLACEHOLDER
export function close_dangling_braces(template, cut_before)

@@ -833,0 +819,0 @@ {

@@ -7,3 +7,2 @@ // This is a port of Google Android `libphonenumber`'s

import { matches_entirely } from './common'
import metadata from '../metadata.min'

@@ -51,6 +50,6 @@ import

{
country_metadata = metadata.countries[input.country]
country_metadata = this.metadata.countries[input.country]
}
const { country_phone_code, number } = parse_phone_number_and_country_phone_code(input.phone)
const { country_phone_code, number } = parse_phone_number_and_country_phone_code(input.phone, this.metadata)

@@ -65,3 +64,3 @@ if (country_phone_code)

country_metadata = get_metadata_by_country_phone_code(country_phone_code, metadata)
country_metadata = get_metadata_by_country_phone_code(country_phone_code, this.metadata)
}

@@ -117,17 +116,11 @@

{
// If national prefix formatting rule is set
// (e.g. it is not set for US)
if (national_prefix_formatting_rule)
{
return number.replace
return number.replace
(
format_pattern_matcher,
get_format_format(format).replace
(
format_pattern_matcher,
get_format_format(format).replace
(
FIRST_GROUP_PATTERN,
national_prefix_formatting_rule
)
FIRST_GROUP_PATTERN,
national_prefix_formatting_rule
)
}
)
}

@@ -134,0 +127,0 @@

@@ -7,3 +7,2 @@ // This is a port of Google Android `libphonenumber`'s

import { matches_entirely } from './common'
import metadata from '../metadata.min'

@@ -224,3 +223,3 @@ import

let { country_phone_code, number } = parse_phone_number_and_country_phone_code(formatted_phone_number)
let { country_phone_code, number } = parse_phone_number_and_country_phone_code(formatted_phone_number, this.metadata)

@@ -240,3 +239,3 @@ // Maybe invalid country phone code encountered

if (options.country.restrict &&
country_phone_code !== get_phone_code(metadata.countries[options.country.restrict]))
country_phone_code !== get_phone_code(this.metadata.countries[options.country.restrict]))
{

@@ -246,3 +245,3 @@ return {}

country_metadata = get_metadata_by_country_phone_code(country_phone_code, metadata)
country_metadata = get_metadata_by_country_phone_code(country_phone_code, this.metadata)

@@ -259,3 +258,3 @@ // `country` will be set later,

country = options.country.default || options.country.restrict
country_metadata = metadata.countries[country]
country_metadata = this.metadata.countries[country]

@@ -280,3 +279,3 @@ number = normalize(text)

{
country = find_country_code(country_phone_code, national_number)
country = find_country_code(country_phone_code, national_number, this.metadata)

@@ -406,3 +405,3 @@ // Just in case there's a bug in Google's metadata

//
export function parse_phone_number_and_country_phone_code(number)
export function parse_phone_number_and_country_phone_code(number, metadata)
{

@@ -506,3 +505,3 @@ number = parse_phone_number(number)

export function find_country_code(country_phone_code, national_phone_number)
export function find_country_code(country_phone_code, national_phone_number, metadata)
{

@@ -509,0 +508,0 @@ // Is always non-empty, because `country_phone_code` is always valid

@@ -5,3 +5,3 @@ import parse from './parse'

{
return Object.keys(parse(number, country_code)).length > 0
return Object.keys(parse.call(this, number, country_code)).length > 0
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc