You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					222 lines
				
				8.1 KiB
			
		
		
			
		
	
	
					222 lines
				
				8.1 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Object.defineProperty(exports, "__esModule", {
							 | 
						||
| 
								 | 
							
								  value: true
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								exports.PhoneNumberSearch = exports.EXTN_PATTERNS_FOR_PARSING = void 0;
							 | 
						||
| 
								 | 
							
								exports["default"] = findPhoneNumbers;
							 | 
						||
| 
								 | 
							
								exports.searchPhoneNumbers = searchPhoneNumbers;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _constants = require("./constants.js");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _parse_ = _interopRequireDefault(require("./parse_.js"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _isViablePhoneNumber = require("./helpers/isViablePhoneNumber.js");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _createExtensionPattern = _interopRequireDefault(require("./helpers/extension/createExtensionPattern.js"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _parsePreCandidate = _interopRequireDefault(require("./findNumbers/parsePreCandidate.js"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _isValidPreCandidate = _interopRequireDefault(require("./findNumbers/isValidPreCandidate.js"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _isValidCandidate = _interopRequireDefault(require("./findNumbers/isValidCandidate.js"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Regexp of all possible ways to write extensions, for use when parsing. This
							 | 
						||
| 
								 | 
							
								 * will be run as a case-insensitive regexp match. Wide character versions are
							 | 
						||
| 
								 | 
							
								 * also provided after each ASCII version. There are three regular expressions
							 | 
						||
| 
								 | 
							
								 * here. The first covers RFC 3966 format, where the extension is added using
							 | 
						||
| 
								 | 
							
								 * ';ext='. The second more generic one starts with optional white space and
							 | 
						||
| 
								 | 
							
								 * ends with an optional full stop (.), followed by zero or more spaces/tabs
							 | 
						||
| 
								 | 
							
								 * /commas and then the numbers themselves. The other one covers the special
							 | 
						||
| 
								 | 
							
								 * case of American numbers where the extension is written with a hash at the
							 | 
						||
| 
								 | 
							
								 * end, such as '- 503#'. Note that the only capturing groups should be around
							 | 
						||
| 
								 | 
							
								 * the digits that you want to capture as part of the extension, or else parsing
							 | 
						||
| 
								 | 
							
								 * will fail! We allow two options for representing the accented o - the
							 | 
						||
| 
								 | 
							
								 * character itself, and one in the unicode decomposed form with the combining
							 | 
						||
| 
								 | 
							
								 * acute accent.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var EXTN_PATTERNS_FOR_PARSING = (0, _createExtensionPattern["default"])('parsing');
							 | 
						||
| 
								 | 
							
								exports.EXTN_PATTERNS_FOR_PARSING = EXTN_PATTERNS_FOR_PARSING;
							 | 
						||
| 
								 | 
							
								var WHITESPACE_IN_THE_BEGINNING_PATTERN = new RegExp('^[' + _constants.WHITESPACE + ']+');
							 | 
						||
| 
								 | 
							
								var PUNCTUATION_IN_THE_END_PATTERN = new RegExp('[' + _constants.VALID_PUNCTUATION + ']+$'); // // Regular expression for getting opening brackets for a valid number
							 | 
						||
| 
								 | 
							
								// // found using `PHONE_NUMBER_START_PATTERN` for prepending those brackets to the number.
							 | 
						||
| 
								 | 
							
								// const BEFORE_NUMBER_DIGITS_PUNCTUATION = new RegExp('[' + OPENING_BRACKETS + ']+' + '[' + WHITESPACE + ']*' + '$')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var VALID_PRECEDING_CHARACTER_PATTERN = /[^a-zA-Z0-9]/;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function findPhoneNumbers(text, options, metadata) {
							 | 
						||
| 
								 | 
							
								  /* istanbul ignore if */
							 | 
						||
| 
								 | 
							
								  if (options === undefined) {
							 | 
						||
| 
								 | 
							
								    options = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var search = new PhoneNumberSearch(text, options, metadata);
							 | 
						||
| 
								 | 
							
								  var phones = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (search.hasNext()) {
							 | 
						||
| 
								 | 
							
								    phones.push(search.next());
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return phones;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @return ES6 `for ... of` iterator.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function searchPhoneNumbers(text, options, metadata) {
							 | 
						||
| 
								 | 
							
								  /* istanbul ignore if */
							 | 
						||
| 
								 | 
							
								  if (options === undefined) {
							 | 
						||
| 
								 | 
							
								    options = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var search = new PhoneNumberSearch(text, options, metadata);
							 | 
						||
| 
								 | 
							
								  return _defineProperty({}, Symbol.iterator, function () {
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      next: function next() {
							 | 
						||
| 
								 | 
							
								        if (search.hasNext()) {
							 | 
						||
| 
								 | 
							
								          return {
							 | 
						||
| 
								 | 
							
								            done: false,
							 | 
						||
| 
								 | 
							
								            value: search.next()
							 | 
						||
| 
								 | 
							
								          };
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return {
							 | 
						||
| 
								 | 
							
								          done: true
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Extracts a parseable phone number including any opening brackets, etc.
							 | 
						||
| 
								 | 
							
								 * @param  {string} text - Input.
							 | 
						||
| 
								 | 
							
								 * @return {object} `{ ?number, ?startsAt, ?endsAt }`.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var PhoneNumberSearch = /*#__PURE__*/function () {
							 | 
						||
| 
								 | 
							
								  function PhoneNumberSearch(text, options, metadata) {
							 | 
						||
| 
								 | 
							
								    _classCallCheck(this, PhoneNumberSearch);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.text = text; // If assigning the `{}` default value is moved to the arguments above,
							 | 
						||
| 
								 | 
							
								    // code coverage would decrease for some weird reason.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.options = options || {};
							 | 
						||
| 
								 | 
							
								    this.metadata = metadata; // Iteration tristate.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.state = 'NOT_READY';
							 | 
						||
| 
								 | 
							
								    this.regexp = new RegExp(_isViablePhoneNumber.VALID_PHONE_NUMBER_WITH_EXTENSION, 'ig');
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  _createClass(PhoneNumberSearch, [{
							 | 
						||
| 
								 | 
							
								    key: "find",
							 | 
						||
| 
								 | 
							
								    value: function find() {
							 | 
						||
| 
								 | 
							
								      var matches = this.regexp.exec(this.text);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!matches) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var number = matches[0];
							 | 
						||
| 
								 | 
							
								      var startsAt = matches.index;
							 | 
						||
| 
								 | 
							
								      number = number.replace(WHITESPACE_IN_THE_BEGINNING_PATTERN, '');
							 | 
						||
| 
								 | 
							
								      startsAt += matches[0].length - number.length; // Fixes not parsing numbers with whitespace in the end.
							 | 
						||
| 
								 | 
							
								      // Also fixes not parsing numbers with opening parentheses in the end.
							 | 
						||
| 
								 | 
							
								      // https://github.com/catamphetamine/libphonenumber-js/issues/252
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      number = number.replace(PUNCTUATION_IN_THE_END_PATTERN, '');
							 | 
						||
| 
								 | 
							
								      number = (0, _parsePreCandidate["default"])(number);
							 | 
						||
| 
								 | 
							
								      var result = this.parseCandidate(number, startsAt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (result) {
							 | 
						||
| 
								 | 
							
								        return result;
							 | 
						||
| 
								 | 
							
								      } // Tail recursion.
							 | 
						||
| 
								 | 
							
								      // Try the next one if this one is not a valid phone number.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return this.find();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, {
							 | 
						||
| 
								 | 
							
								    key: "parseCandidate",
							 | 
						||
| 
								 | 
							
								    value: function parseCandidate(number, startsAt) {
							 | 
						||
| 
								 | 
							
								      if (!(0, _isValidPreCandidate["default"])(number, startsAt, this.text)) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      } // Don't parse phone numbers which are non-phone numbers
							 | 
						||
| 
								 | 
							
								      // due to being part of something else (e.g. a UUID).
							 | 
						||
| 
								 | 
							
								      // https://github.com/catamphetamine/libphonenumber-js/issues/213
							 | 
						||
| 
								 | 
							
								      // Copy-pasted from Google's `PhoneNumberMatcher.js` (`.parseAndValidate()`).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!(0, _isValidCandidate["default"])(number, startsAt, this.text, this.options.extended ? 'POSSIBLE' : 'VALID')) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      } // // Prepend any opening brackets left behind by the
							 | 
						||
| 
								 | 
							
								      // // `PHONE_NUMBER_START_PATTERN` regexp.
							 | 
						||
| 
								 | 
							
								      // const text_before_number = text.slice(this.searching_from, startsAt)
							 | 
						||
| 
								 | 
							
								      // const full_number_starts_at = text_before_number.search(BEFORE_NUMBER_DIGITS_PUNCTUATION)
							 | 
						||
| 
								 | 
							
								      // if (full_number_starts_at >= 0)
							 | 
						||
| 
								 | 
							
								      // {
							 | 
						||
| 
								 | 
							
								      // 	number   = text_before_number.slice(full_number_starts_at) + number
							 | 
						||
| 
								 | 
							
								      // 	startsAt = full_number_starts_at
							 | 
						||
| 
								 | 
							
								      // }
							 | 
						||
| 
								 | 
							
								      //
							 | 
						||
| 
								 | 
							
								      // this.searching_from = matches.lastIndex
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var result = (0, _parse_["default"])(number, this.options, this.metadata);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!result.phone) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      result.startsAt = startsAt;
							 | 
						||
| 
								 | 
							
								      result.endsAt = startsAt + number.length;
							 | 
						||
| 
								 | 
							
								      return result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, {
							 | 
						||
| 
								 | 
							
								    key: "hasNext",
							 | 
						||
| 
								 | 
							
								    value: function hasNext() {
							 | 
						||
| 
								 | 
							
								      if (this.state === 'NOT_READY') {
							 | 
						||
| 
								 | 
							
								        this.last_match = this.find();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (this.last_match) {
							 | 
						||
| 
								 | 
							
								          this.state = 'READY';
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          this.state = 'DONE';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return this.state === 'READY';
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, {
							 | 
						||
| 
								 | 
							
								    key: "next",
							 | 
						||
| 
								 | 
							
								    value: function next() {
							 | 
						||
| 
								 | 
							
								      // Check the state and find the next match as a side-effect if necessary.
							 | 
						||
| 
								 | 
							
								      if (!this.hasNext()) {
							 | 
						||
| 
								 | 
							
								        throw new Error('No next element');
							 | 
						||
| 
								 | 
							
								      } // Don't retain that memory any longer than necessary.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var result = this.last_match;
							 | 
						||
| 
								 | 
							
								      this.last_match = null;
							 | 
						||
| 
								 | 
							
								      this.state = 'NOT_READY';
							 | 
						||
| 
								 | 
							
								      return result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return PhoneNumberSearch;
							 | 
						||
| 
								 | 
							
								}();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.PhoneNumberSearch = PhoneNumberSearch;
							 | 
						||
| 
								 | 
							
								//# sourceMappingURL=findPhoneNumbers_.js.map
							 |