🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

21
backend/node_modules/libphonenumber-js/.babelrc generated vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"presets": [
"@babel/env"
],
"plugins": [
["@babel/transform-for-of", { "loose": true }],
["@babel/plugin-syntax-import-assertions"]
],
"env": {
"es6": {
"presets": [
["@babel/env", { "modules": false }]
]
},
"nyc": {
"plugins": [
"babel-plugin-istanbul"
]
}
}
}

16
backend/node_modules/libphonenumber-js/.gitlab-ci.yml generated vendored Normal file
View File

@@ -0,0 +1,16 @@
image: node:16
pages:
script:
- npm install
- npm run metadata:generate
- npm run build
- mv ./bundle ./public
- cp --recursive ./website/* ./public/
artifacts:
paths:
- public
only:
- master

27
backend/node_modules/libphonenumber-js/.nycrc generated vendored Normal file
View File

@@ -0,0 +1,27 @@
{
"require": [
"@babel/register"
],
"reporter": [
"lcov",
"text-summary"
],
"include": [
"source/**/*.js"
],
"exclude": [
"source/findNumbers/Leniency.js",
"source/findNumbers/RegExpCache.js",
"source/findNumbers/LRUCache.js",
"source/PhoneNumberMatcher.js",
"source/formatNumberForMobileDialing.js",
"source/tools/*.js",
"**/*.test.js"
],
"check-coverage": true,
"lines": "100",
"sourceMap": false,
"instrument": false,
"cache": true,
"all": true
}

5
backend/node_modules/libphonenumber-js/AUTHORS generated vendored Normal file
View File

@@ -0,0 +1,5 @@
Google Inc.
Vonage Holdings Corp.
Ian Galpin
Ben Gertzfield
https://gitlab.com/catamphetamine

629
backend/node_modules/libphonenumber-js/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,629 @@
<!-- (breaking change) `parsePhoneNumberFromString()`: `extract: false` is now the default mode: non-phone-number characters aren't now trimmed on the left and on the right sides of a phone number. For example, `(213) 373-4253` is parsed as a valid phone number, but `Call: (213) 373-4253` is not, because `Call: ` doesn't automatically get trimmed now. For the old behavior, pass `extract: true` option. -->
<!-- Maybe rename `metadata.full.json` -> `metadata.max.json`. -->
<!-- (breaking change) Moved `findPhoneNumbersInText()` to its own subpackage: `libphonenumber-js/find`. The default export is `searchPhoneNumbersInText()` that returns an ES6 "iterator". -->
<!-- Renamed source files: `parsePhoneNumber.js` -> `parsePhoneNumberWithError.js`, etc. -->
<!-- (breaking change) Metadata is often updated, so it has been extracted into its own package: `libphonenumber-metadata`. -->
<!-- `metadata.json` is now included in the package. -->
<!-- (breaking change) `parseNumber()` is now `extended: true` by default (and the `extended` flag is no longer supported) meaning that by default it will parse all even remotely hypothetical phone numbers (this was decided to be the primary use case for this function, and it's how Google's libphonenumber does it). Pass `strict: true` flag for the old "only parse valid numbers" behaviour. -->
<!-- (breaking change) `formatNumber()` no longer supports `formatNumber(numberString, countryString, format)` notation, use `formatNumber({ phone, country }, format)` notation instead. -->
<!-- `type` parameter has been added to `isValidNumber()` for validating phone numbers of a particual type (fixed line, mobile, etc). -->
<!-- (breaking change) Replaced `phone: ...` with `number: ...` in returned objects and arguments in all functions: `formatNumber()`, `parseNumber()`, `isValidNumber()`, `getNumberType()`, `findPhoneNumbers()`. -->
<!-- (breaking change) Removed deprecated `findPhoneNumbers()`, `searchPhoneNumbers()` and `PhoneNumberSearch` functions. Use `findNumbers()`, `searchNumbers()` and `PhoneNumberMatcher` instead. -->
<!-- (breaking change) Better API.
https://github.com/catamphetamine/libphonenumber-js/issues/259
Maybe something like:
const number = parseNumber(value)
const {
number,
country,
nationalNumber,
carrierCode,
countryCallingCode,
valid,
possible
} = parseNumber(value, { extended: true })
// Maybe rename "extended" to something else.
-->
<!-- (breaking change)
`phone` property of phone number object renamed to `nationalNumber`
-->
<!-- (breaking change) `examples.mobile.json` now provides phone numbers in E.164 format (e.g. `+78005553535`). Previously those numbers were in "national (significant) number" form (e.g. `8005553535`).
-->
<!-- (breaking change) AsYouType -> AsYouTypeFormatter (maybe, or maybe not). -->
<!-- (breaking change) parse.js -> parseNumber.js, format.js -> formatNumber.js, validate.js -> isValidNumber.js. -->
<!-- (breaking change) `findNumbers()` now returns an array of `PhoneNumber` objects instead of objects having shape `{ country, phone }`. -->
<!-- (breaking change) Maybe change metadata from `.json` to `.js` to save size on `,0,` -> `,,`. -->
<!-- (breaking change) Prepend `+` in AsYouType if no `defaultCountry` has been set.
And edit the README:
* `getNumber()` — Returns the [`PhoneNumber`](#phonenumber). Will return `undefined` if no [national (significant) number](#national-significant-number) has been entered so far, or if no `defaultCountry` has been set and the user enters a phone number not in international format.
-->
<!-- (breaking change) Changed `countries` and `country_calling_codes` properties in metadata: now they're not properties but rather elements of an array (`countries` is an array now rather than an object; `countries` is `metadata[0]` and `country_calling_codes` is `metadata[1]`). If you were using a custom-generated metadata then it has to be re-generated for the new version. -->
This changelog [only](https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/16#note_594165443) mentions the changes in the code. See [Google's changelog](https://github.com/google/libphonenumber/blob/master/release_notes.txt) for metadata changes.
1.12.0 / 24.02.2025
===================
* Added an export of `PhoneNumber` class, as suggested by [Jan Vincent Liwanag](https://gitlab.com/jvliwanag) in his [pull request](https://gitlab.com/catamphetamine/libphonenumber-js/-/merge_requests/26).
1.11.0 / 06.05.2024
====================
* (TypeScript) Fixed Tagged type to be more strict, as suggested in an [issue](https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/144) by Islam Sharabash.
1.10.17 / 08.01.2023
==================
* [Added](https://github.com/catamphetamine/libphonenumber-js/issues/420) `PhoneNumber.getPossibleCountries()` function. It returns a list of countries this phone number could possibly belong to. Can be used when parsing complete international phone numbers containing a "calling code" that is shared between several countries. If parsing such a phone number returns `country: undefined` then `getPossibleCountries()` function could be used to somehow speculate about what country could this phone number possibly belong to.
1.10.0 / 18.05.2022
==================
* Migrated the library to use ["ES Modules" export](https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/42). This shouldn't break anyone's code and it makes it more modern since people asked about this feature.
1.9.48 / 06.02.2022
==================
* Merged a [pull request](https://gitlab.com/catamphetamine/libphonenumber-js/-/merge_requests/8) that [changed the declaration](https://github.com/catamphetamine/libphonenumber-js/issues/170#issuecomment-1030821520) of basic "string" types like `E164Number`, `NationalNumber`, `Extension`, etc.
1.9.45 / xx.01.2022
==================
* Added `AsYouType.getNumberValue()` function. The function will be [used](https://gitlab.com/catamphetamine/react-phone-number-input/-/issues/113) in `react-phone-number-input` component. Returns the phone number in [`E.164`](https://en.wikipedia.org/wiki/E.164) format. For example, for country `"US"` and input `"(222) 333-4444"` it will return `"+12223334444"`. Will return `undefined` if no digits have been input, or when inputting a phone number in national format and no default country or default "country calling code" have been set.
1.9.42 / 05.11.2021
==================
* Added a better called alias for `metadata.full.json``metadata.max.json`.
1.9.40 / 02.11.2021
==================
* Improved [format selection](https://gitlab.com/catamphetamine/react-phone-number-input/-/issues/93) in `AsYouType` formatter: previously it chose the first one before there were at least 3 national (significant) number digits, now it starts filtering out formats right from the start of the national (significant) number.
1.9.36 / 05.10.2021
==================
* Added a [`setExt(ext: string)`](https://gitlab.com/catamphetamine/libphonenumber-js/#setextext-string) function of a `PhoneNumber` class instance. It could be useful when formatting phone numbers stored as two separate fields: the phone number itself and the extension part.
1.9.27 / 09.09.2021
==================
* [Added](https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/45) TypeScript "typings" on the exported `Metadata` class. Also rewrote `Metadata` class API [docs](https://gitlab.com/catamphetamine/libphonenumber-js#metadata) and the description of [`leading_digits`](https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/METADATA.md#leading_digits) metadata property.
* TypeScript `Metadata` exported type was renamed to `MetadataJson` so that the `Metadata` class type could be exported as `Metadata`.
1.9.26 / 05.09.2021
==================
* [Added](https://github.com/catamphetamine/libphonenumber-js/issues/406) `validatePhoneNumberLength()` function: same as `isPossiblePhoneNumber()` but tells the actual reason why a phone number is not possible: `TOO_SHORT`, `TOO_LONG`, `INVALID_LENGTH`, etc.
```js
validatePhoneNumberLength('abcde') === 'NOT_A_NUMBER'
validatePhoneNumberLength('444 1 44') === 'INVALID_COUNTRY'
validatePhoneNumberLength('444 1 44', 'TR') === 'TOO_SHORT'
validatePhoneNumberLength('444 1 444', 'TR') === undefined
validatePhoneNumberLength('444 1 4444', 'TR') === 'INVALID_LENGTH'
validatePhoneNumberLength('444 1 44444', 'TR') === 'INVALID_LENGTH'
validatePhoneNumberLength('444 1 444444', 'TR') === undefined
validatePhoneNumberLength('444 1 4444444444', 'TR') === 'TOO_LONG'
```
1.9.20 / 07.06.2021
==================
* [Changed](https://github.com/google/libphonenumber/commit/c6277266fba8223cfc610cfb1e999deb9f876d65) formatting numbers in `IDD` format to always use the preferred IDD prefix (if defined), not just in cases when a country has multiple IDD prefixes. This means that it will output `8~10` as the prefix instead of `810` for some regions (like Uzbekistan) that have this tilde in their IDD prefix (the tilde designates that the user should wait before continuing to dial).
1.9.11 / 10.02.2021
==================
* [Added](https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/29) `extract: false` option on `parsePhoneNumberFromString()`: it enables a bit "stricter" parsing in a way that it attempts to parse the entire text as a phone number rather than extracting a phone number from text. For example, with `extract: false` option, `"(213) 373-4253"` is parsed as a valid phone number, but `"Call: (213) 373-4253"` is not, because the `"Call: "` part doesn't automatically get trimmed in this case. If there's version `2.x`, I guess `extract: false` will be the default behavior because it looks more appropriate than the default "extract" behavior of Google's `libphonenumber`.
* Added `isPossiblePhoneNumber()` and `isValidPhoneNumber()` functions, which are basically shortucts to `parsePhoneNumberFromString(text, { extract: false })` and then `.isValid()`/`.isPossible()`.
1.9.5 / 01.12.2020
==================
* Fixed the [issue](https://gitlab.com/catamphetamine/libphonenumber-js/-/merge_requests/4) with `findPhoneNumbersInText()` returning incorrect `startAt` and `endsAt` positions in some cases.
1.9.4 / 13.11.2020
==================
* Refactored the main ES6 export in order to support "tree shaking".
1.9.3 / 11.11.2020
==================
* Added `AsYouType.getChars()` method.
* Added formatting of international phone numbers that have been input without a leading `+`.
1.9.2 / 08.11.2020
==================
* Metadata `version` is now an integer instead of a semver version. Semver versions of previously generated metadata are automatically converted into an integer version.
1.9.1 / 08.11.2020
==================
* Merged the latest Google's [patch](https://github.com/google/libphonenumber/commit/55b2646ec9393f4d3d6661b9c82ef9e258e8b829) on parsing phone number extensions.
1.9.0 / 08.11.2020
==================
* Refactored `AsYouType` formatter.
* (could be a breaking change for some) Some people might have used some of the _undocumented_ `AsYouType` instance properties like `.countryCallingCode`, `.nationalNumber`, etc: those have been moved to a new `.state` object. The `.state` object is also not part of the public API, so developers shouldn't use it: use the documented getter methods instead. The `.country` property of `AsYouType` instance still stays: not because it hasn't been moved (it has been and is emulated), but because it has been part of an official (now legacy) API of `AsYouType` formatter.
* (misc) Renamed `asYouType` instance method `getCountryCallingCode()` to `getCountryCode()`. The older name still works.
* (could be a _build-time_ breaking change for custom metadata) For those who were generating custom metadata, the `libphonenumber-generate-metadata` console command has been moved to a separate package called `libphonenumber-metadata-generator`. The applications that're using it should do `npm install libphonenumber-metadata-generator --save-dev` and then use the new `libphonenumber-metadata-generator` command instead of the old one (only the name changed). [See instructions](https://gitlab.com/catamphetamine/libphonenumber-metadata-generator).
1.8.6 / 05.11.2020
==================
* Refactored `AsYouType` formatter.
* [Fixed](https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/23) `AsYouType` formatter not formatting numbers in some cases like, for example, certain types of Argentinian mobile numbers.
<!-- * Found out that all previous `metadata` was missing `domestic_carrier_code_formatting_rule` that is used in a few countries (like Argentina) when formatting phone numbers containing "carrier codes". It has been added now. -->
* `humanReadable` option of `"IDD"` formatting has been removed: now it's always `true`. The rationale is that Google's `formatOutOfCountryCallingNumber()` original function always formats in "human readable" format.
1.8.3 / 03.10.2020
==================
* (advanced) Fixed `metadata.mobile.json` and generating "custom" metadata: now it won't include non-relevant phone number types. Previously, `metadata.mobile.json` (and any other "custom"-generated metadata) included all phone number types for cases when there're several countries corresponding to the same country calling code (for example, `US` and `CA`). So, in case of `metadata.mobile.json`, for `DE` it only contained mobile phone number type, but for `US` and `CA` it contained all phone number types (this has been unnoticed until this release). Now it only contains mobile phone number types for any country, as it's supposed to be. This change didn't result in any significant "mobile" metadata size reduction: just `105 KB` -> `95 KB`.
1.8.1 / 23.09.2020
==================
* Renamed `parsePhoneNumber()` named export to `parsePhoneNumberWithError()`. The older name still works.
1.8.0 / 22.09.2020
==================
* Promoted `parsePhoneNumberFromString()` named export to a default export due to the name being too verbose.
1.7.50 / 05.04.2020
===================
* [Added](https://github.com/catamphetamine/libphonenumber-js/issues/388#issuecomment-609036293) some utility functions to `AsYouType`:
```js
/**
* Returns `true` if the phone number is being input in international format.
* In other words, returns `true` if and only if the parsed phone number starts with a `"+"`.
* @return {boolean}
*/
isInternational()
/**
* Returns the "country calling code" part of the phone number.
* Returns `undefined` if the number is not being input in international format.
* Returns "country calling code" for "non-geographic" phone numbering plans too.
* @return {string} [countryCallingCode]
*/
getCountryCallingCode()
/**
* Returns a two-letter country code of the phone number.
* Returns `undefined` for "non-geographic" phone numbering plans.
* Returns `undefined` if no phone number has been input yet.
* @return {string} [country]
*/
getCountry()
/**
* Returns `true` if the phone number is "possible".
* Is just a shortcut for `PhoneNumber.isPossible()`.
* @return {boolean}
*/
isPossible()
/**
* Returns `true` if the phone number is "valid".
* Is just a shortcut for `PhoneNumber.isValid()`.
* @return {boolean}
*/
isValid()
```
1.7.38 / 04.02.2020
===================
* Removed the `"001"` country code ("Non-Geographic Entity"): now in case of "non-geographic" phone numbers their `country` is just `undefined`. Instead, `PhoneNumber` class has an `.isNonGeographic()` method.
* Fixed "non-geographic" numbers `.isPossible() === false` bug.
1.7.35 / 03.02.2020
===================
* Fixed "Non-Geographic Entities" (`001` country code).
1.7.32 / 03.02.2020
===================
* Refactored the code. Mostly `AsYouType` formatter. `AsYouType.input()` no longer accepts "falsy" values like `null`: instead, it only accepts strings.
* Fixed `AsYouType` formatter bugs ([#318](https://github.com/catamphetamine/libphonenumber-js/issues/318)).
* Added `nationalPrefix: boolean` option to `PhoneNumber.format()` — Some phone numbers can be formatted both with national prefix and without it. In such cases the library defaults to "with national prefix" (for legacy reasons). Pass `nationalPrefix: false` option to force formatting without national prefix in such cases.
* Renamed `findNumbers(text, { v2: true })` to `findPhoneNumbersInText(text)`, and `searchNumbers(text, { v2: true })` to `searchPhoneNumbersInText(text)`.
1.7.27 / 18.11.2019
===================
* Added `getCountries()` function that returns a list of all available two-letter country codes. This is to prevent some users from having to deal with `Unknown country` error.
1.7.6 / 11.01.2019
==================
* `findNumbers()`, `searchNumbers()`, `PhoneNumberMatcher` don't throw "Unknown country" error anymore: a non-existent country is simply ignored instead. Same goes for `getExampleNumber()` and `getExtPrefix()`.
* `parsePhoneNumberFromString()` doesn't return `undefined` if a non-existent default country is passed: it simply ignores such country instead and still parses international numbers.
* Added `isSupportedCountry(country)` function.
* Added CDN bundles for `min`/`max`/`mobile` sub-packages.
* Moved demo to `max` metadata (was `min` previously).
* Added TypeScript definitions for `min`/`max`/`mobile`/`core` sub-packages.
1.7.1 / 01.12.2018
==================
* Added `/min`, `/max`, `/mobile` and `/custom` subpackages pre-wired with different flavors of metadata. See the relevant readme section for more info.
* Added `parsePhoneNumberFromString()` function (which doesn't throw but instead returns `undefined`).
1.7.0 / 31.12.2018
==================
* Refactored the code to remove cyclic dependencies which caused warnings on React Native. It's not a breaking change but it's still a big code diff overall so incremented the "minor" version number.
1.6.2 / 18.10.2018
==================
* Support Russian extension character "доб" as a valid one while parsing the numbers.
1.6.1 / 18.10.2018
==================
* Added `.getNumber()` method to `AsYouType` formatter instance. Returns a `PhoneNumber`.
1.6.0 / 17.10.2018
==================
* Added `parsePhoneNumber()` function and `PhoneNumber` class.
* Added `v2: true` option to `findNumbers()` function.
* Added `getExampleNumber()` function.
* Added `isPossibleNumber()` function.
* In `formatNumber()` renamed `National` to `NATIONAL` and `International` to `INTERNATIONAL`. The older variants still work but are considered deprecated.
* (metadata file internal format breaking change) (doesn't affect users of this library) If anyone was using metadata files from this library bypassing the library functions (i.e. those who parsed `metadata.min.json` file manually) then there's a new internal optimization introduced in this version: previously `formats` were copy-pasted for each country of the same region (e.g. `NANPA`) while now the `formats` are only defined on the "main" country for region and other countries simply read the `formats` from it at runtime. This reduced the default metadata file size by 5 kilobytes.
1.5.0 / 26.09.2018
==================
* Deprecated `findPhoneNumbers()`, `searchPhoneNumbers()` and `PhoneNumberSearch`. Use `findNumbers()`, `searchNumbers()` and `PhoneNumberMatcher` instead. The now-deprecated functions were a half-self-made implementation of Google's Java `findNumbers()` until the Java code was ported into javascript and passed tests. The port of Google's Java implementation is supposed to find numbers more correctly. It hasn't been tested by users in production yet, but the same tests as for the previous implementation of `findPhoneNumbers()` pass, so seems that it can be used in production.
1.4.6 / 12.09.2018
==================
* Fixed `formatNumber('NATIONAL')` not formatting national phone numbers with a national prefix when it's marked as optional (e.g. Russia). Before it didn't add national prefix when formatting national numbers if national prefix was marked as optional. Now it always adds national prefix when formatting national numbers even when national prefix is marked as optional.
1.4.5 / 07.09.2018
==================
* A bug in `matches_entirely` was found by a user which resulted in incorrect regexp matching in some cases, e.g. when there was a `|` in a regexp. This could cause incorrect `parseNumber()` results, or any other weird behaviour.
1.4.0 / 03.08.2018
==================
* Changed the output of `AsYouType` formatter. E.g. before for `US` and input `21` it was outputting `(21 )` which is not good for phone number input (not intuitive and is confusing). Now it will not add closing braces which haven't been reached yet by the input cursor and it will also strip the corresponding opening braces, so for `US` and input `21` it now is just `21`, and for `213` it is `(213)`.
* (could be a breaking change for those who somehow used `.template` property of an `AsYouType` instance) Due to the change in `AsYouType` formatting the `.template` property no longer strictly corresponds to the output, e.g. for `US` and input `21` the output is now `21` but the `.template` is still `(xxx) xxx-xxxx` like it used to be in the older versions when the output was `(21 )`. Therefore, a new function has been added to `AsYouType` instance called `.getTemplate()` which will return the _partial_ template for the currently input value, so for input `21` the output will be `21` and `.getTemplate()` will return `xx`, and for input `213` the output will be `(213)` and `.getTemplate()` will return `(xxx)`. So there is this difference between the new `.getTemplate()` function and the old `.template` property: the old `.template` property always returns the template for a fully entered phone number and the new `.getTemplate()` function always returns the template for the _partially_ entered phone number, i.e. for the partially entered number `(213) 45` it will return template `(xxx) xx` so it's a one-to-one correspondence now.
1.3.0 / 25.07.2018
==================
* Fixed `parseNumber()`, `isValidNumber()` and `getNumberType()` in some rare cases (made them a bit less strict where it fits): previously they were treating `defaultCountry` argument as "the country" in case of local numbers, e.g. `isValidNumber('07624 369230', 'GB')` would be `false` because `07624 369230` number belongs to `IM` (the Isle of Man). While `IM` is not `GB` it should still be `true` because `GB` is the _default_ country, without it necessarily being _the_ country.
* Added a new function `isValidNumberForRegion(number, country)` which mimics [Google's `libphonenumber`'s one](https://github.com/googlei18n/libphonenumber/blob/master/FAQ.md#when-should-i-use-isvalidnumberforregion).
1.2.13 / 30.05.2018
===================
* Fixed a previously unnoticed [bug](https://github.com/catamphetamine/libphonenumber-js/issues/217) regarding parsing RFC3966 phone URIs: previously `:` was mistakenly being considered a key-value separator instead of `=`. E.g. it was parsing RFC3966 phone numbers as `tel:+78005553535;ext:123` instead of `tel:+78005553535;ext=123`. The bug was found and reported by @cdunn.
1.2.6 / 12.05.2018
===================
* Removed `parseNumber()`'s `fromCountry` parameter used for parsing IDD prefixes: now it uses `defaultCountry` instead. `formatNumber()`'s `fromCountry` parameter stays and is not removed.
1.2.5 / 11.05.2018
===================
* Optimized metadata a bit: using `0` instead of `null`/`false` and `1` instead of `true`.
1.2.0 / 08.05.2018
===================
* Added support for [IDD prefixes](https://en.wikipedia.org/wiki/International_direct_dialing) — `parse()` now parses IDD-prefixed phones if `fromCountry` option is passed, `format()` now has an `IDD` format.
1.1.7 / 01.04.2018
===================
* Added `parseNumber()` and `formatNumber()` aliases for `parse()` and `format()`. Now these are the default ones, and `parse()` and `format()` names are considered deprecated. The rationale is that `parse()` and `format()` function names are too unspecific and can clash with other functions declared in a javascript file. And also searching in a project for `parseNumber` and `formatNumber` is easier than searching in a project for `parse` and `format`.
* Fixed `parseRFC3966()` and `formatRFC3966()` non-custom exports.
1.1.4 / 15.03.2018
===================
* `parse()` is now more forgiving when parsing invalid international numbers. E.g. `parse('+49(0)15123020522', 'DE')` doesn't return `{}` and instead removes the invalid `(0)` national prefix from the number.
1.1.1 / 10.03.2018
===================
* Added `PhoneNumberSearch` class for asynchronous phone number search.
1.1.0 / 09.03.2018
===================
* Added `findPhoneNumbers` function.
1.0.22 / 13.02.2018
===================
* Added `parseRFC3966` and `formatRFC3966` functions which are exported.
1.0.18 / 12.02.2018
===================
* Fixed custom metadata backwards compatibility [bug](https://github.com/catamphetamine/libphonenumber-js/issues/180) introduced in `1.0.16`. All people who previously installed `1.0.16` or `1.0.17` should update.
* Refactored metadata module which now supports versioning by adding the `version` property to metadata JSON.
1.0.17 / 07.02.2018
===================
* Fixed `RFC3966` format not prepending `tel:` to the output.
* Renamed `{ possible: true }` option to `{ extended: true }` and the result is now more verbose (see the README).
* Added `possible_lengths` property in metadata: metadata generated using previous versions of the library should be re-generated with then new version.
1.0.16 / 07.02.2018
===================
* (experimental) Added `{ possible: true }` option for `parse()` for parsing "possible numbers" which are not considered valid (like Google's demo does). E.g. `parse('+71111111111', { possible: true }) === { countryCallingCode: '7', phone: '1111111111', possible: true }` and `format({ countryCallingCode: '7', phone: '1111111111' }, 'E.164') === '+71111111111'`.
* `getPhoneCode` name is deprecated, use `getCountryCallingCode` instead.
* `getPhoneCodeCustom` name is deprecated, use `getCountryCallingCodeCustom` instead.
* `AsYouType.country_phone_code` renamed to `AsYouType.countryCallingCode` (but no one should have used that property).
1.0.0 / 21.01.2018
==================
* If `country: string` argument is passed to `parse()` now it becomes "the default country" rather than "restrict to country" ("restrict to country" option is gone).
* `parse()` `options` argument changed: it's now an undocumented feature and can have only a single option inside — `defaultCountry: string` — which should be passed as a string argument instead.
* Removed all previously deprecated stuff: all underscored exports (`is_valid_number`, `get_number_type` and `as_you_type`), lowercase exports for `asYouType` and `asYouTypeCustom` (use `AsYouType` and `AsYouTypeCustom` instead), `"International_plaintext"` format (use `"E.164"` instead).
* Integer phone numbers no longer [get automatically converted to strings](https://github.com/googlei18n/libphonenumber/blob/master/FALSEHOODS.md).
* `parse()`, `isValidNumber()`, `getNumberType()` and `format()` no longer accept `undefined` phone number argument: it must be either a string or a parsed number object having a string `phone` property.
0.4.52 / 21.01.2018
===================
* Added `formatExtension(number, extension)` option to `format()`
0.4.50 / 20.01.2018
===================
* Added support for phone number extensions.
* `asYouType` name is deprecated, use `AsYouType` instead (same goes for `asYouTypeCustom`).
* `is_valid_number`, `get_number_type` and `as_you_type` names are deprecated, use camelCased names instead.
* `International_plaintext` format is deprecated, use `E.164` instead.
* Added `RFC3966` format for phone number URIs (`tel:+1213334455;ext=123`).
0.4.2 / 30.03.2017
===================
* Added missing `getNumberTypeCustom` es6 export
0.4.0 / 29.03.2017
===================
* Removed `.valid` from "as you type" formatter because it wasn't reliable (gave false negatives). Use `isValidNumber(value)` for phone number validation instead.
0.3.11 / 07.03.2017
===================
* Fixed a bug when "as you type" formatter incorrectly formatted the input using non-matching phone number formats
0.3.8 / 25.02.2017
===================
* Loosened national prefix requirement when parsing (fixed certain Brazilian phone numbers parsing)
0.3.6 / 16.02.2017
===================
* Added more strict validation to `isValidNumber`
* Fixed CommonJS export for `getNumberType`
0.3.5 / 15.02.2017
===================
* Now exporting `getNumberType` function
0.3.0 / 29.01.2017
===================
* Removed `libphonenumber-js/custom.es6` exported file: now everything should be imported from the root package in ES6-capable bundlers (because tree-shaking actually works that way)
* Now custom functions like `parse`, `format` and `isValidNumber` are not bound to custom metadata: it's passed as the last argument instead. And custom `asYouType` is now not a function — instead, `asYouType` constructor takes an additional `metadata` argument
0.2.29 / 12.01.2017
===================
* Fixed `update-metadata` utility
0.2.26 / 02.01.2017
===================
* Added national prefix check for `parse` and `isPhoneValid`
0.2.25 / 30.12.2016
===================
* A bit more precise `valid` flag for "as you type" formatter
0.2.22 / 28.12.2016
===================
* Added metadata update `bin` command for end users (see README)
* Added the ability to include extra regular expressions for finer-grained phone number validation
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
===================
* Small fix for "as you type" to not prepend national prefix to the number being typed
0.2.13 / 23.12.2016
===================
* Reset `default_country` for "as you type" if the input is an international phone number
0.2.12 / 23.12.2016
===================
* (misc) Small fix for `format()` when the national number is `undefined`
0.2.10 / 23.12.2016
===================
* Better "as you type" matching: when the national prefix is optional it now tries both variants — with the national prefix extracted and without
0.2.9 / 22.12.2016
===================
* Exporting `metadata` and `getPhoneCode()`
0.2.6 / 22.12.2016
===================
* Fixed a minor bug in "as you type" when a local phone number without national prefix got formatted with the national prefix
0.2.2 / 14.12.2016
===================
* Fixed a bug when country couldn't be parsed from a phone number in most cases
0.2.1 / 10.12.2016
===================
* Added `.country_phone_code` readable property to "as you type" formatter
0.2.0 / 02.12.2016
===================
* "As you type" formatter's `country_code` argument is now `default_country_code`, and it doesn't restrict to the specified country anymore.
0.1.17 / 01.12.2016
===================
* "As you type" formatter `template` fix for national prefixes (which weren't replaced with `x`-es)
0.1.16 / 01.12.2016
===================
* "As you type" formatter now formats the whole input passed to the `.input()` function one at a time without splitting it into individual characters (which yields better performance)
0.1.14 / 01.12.2016
===================
* Added `valid`, `country` and `template` fields to "as you type" instance
0.1.12 / 30.11.2016
===================
* Managed to reduce metadata size by another 5 KiloBytes removing redundant (duplicate) phone number type regular expressions (because there's no "get phone type" API in this library).
0.1.11 / 30.11.2016
===================
* Managed to reduce metadata size by 10 KiloBytes removing phone number type regular expressions when `leading_digits` are present.
0.1.10 / 30.11.2016
===================
* Turned out those numerous bulky regular expressions (`<fixedLine/>`, `<mobile/>`, etc) are actually required to reliably infer country from country calling code and national phone number in cases where there are multiple countries assigned to the same country phone code (e.g. NANPA), so I've included those big regular expressions for those ambiguous cases which increased metadata size by 20 KiloBytes resulting in a total of 90 KiloBytes for the metadata.
0.1.9 / 30.11.2016
===================
* Small fix for "as you type" formatter: replacing digit placeholders (punctuation spaces) with regular spaces in the output
0.1.8 / 29.11.2016
===================
* Fixed a bug when national prefix `1` was present in "as you type" formatter for NANPA countries (while it shouldn't have been present)
0.1.7 / 29.11.2016
===================
* (may be a breaking change) renamed `.clear()` to `.reset()` for "as you type" formatter
0.1.5 / 29.11.2016
===================
* Better `asYouType` (better than Google's original "as you type" formatter)
0.1.0 / 28.11.2016
===================
* Added `asYouType` and `isValidNumber`.
0.0.3 / 24.11.2016
===================
* Added `format` function.
0.0.1 / 24.11.2016
===================
* Initial release. `parse` function is working.

View File

@@ -0,0 +1,78 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and free environment, we as
contributors and maintainers pledge to making participation in our project and
our community a censorship-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating an open and free environment
include:
* Not constraining the language to be "welcoming" or "inclusive"
* Not demanding show of empathy towards other community members
* Not dictating anyone to be respectful of differing viewpoints and experiences
* Not forcing anyone to change their views or opinions regardless of those
* Not intimidating other people into accepting your own views or opinions
* Not blackmailing other people to disclose their personal views or opinions
* Not constraining other people from publishing their personal views or opinions in an unintrusive way
* Focusing on what is best for the ecosystem
Examples of acceptable behavior by participants include:
* The use of sexualized language
* Occasional trolling or insulting comments that are not completely off-topic
Examples of unacceptable behavior by participants include:
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Unwelcome sexual attention or advances
* Public harassment or personal attacks when carried out in an bold or intrusive way
* Private harassment
* Any actions that are in violation of the local laws or otherwise considered illegal
* Other conduct which could reasonably be considered inappropriate in an open and free setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are free to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and authority to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of unacceptable behavior may be reported by contacting the project team.
The complaints will likely be reviewed and investigated and may result in a response that
is deemed necessary and appropriate to the circumstances. The project team should maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org

22
backend/node_modules/libphonenumber-js/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2016 @catamphetamine <purecatamphetamine@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

176
backend/node_modules/libphonenumber-js/LICENSE.Apache generated vendored Normal file
View File

@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

153
backend/node_modules/libphonenumber-js/METADATA.md generated vendored Normal file
View File

@@ -0,0 +1,153 @@
# Metadata
This document describes `metadata.json` that's generated from `PhoneNumberMetadata.xml` by running `npm run metadata:generate` command. It serves as an intermediary step for generating all other metadata (such as `metadata.min.json`), and is therefore not included in the final distribution. See [`PhoneNumberMetadata.xml`](https://github.com/google/libphonenumber/blob/master/resources/PhoneNumberMetadata.xml) in Google's repo. They also have some [docs](https://github.com/google/libphonenumber/blob/master/resources/phonemetadata.proto) on metadata fields too.
## Country calling codes
`country_calling_codes` — A list of countries by country calling code: some country calling codes are shared between several countries (for example, United States and Canada).
## Countries
`countries` — Contains metadata for each country.
### `phone_code`
Country calling code, duplicated here for easy lookup of country calling code by country. Could be considered "reverse lookup" compared to `country_calling_codes`.
### `idd_prefix`
[International Direct Dialing prefix](https://wikitravel.org/en/International_dialling_prefix) when calling out of this country. "IDD prefixes" are defined for every country and are used to call from one country to another. "IDD prefixes" originated when telephony was still analogue and analogue phones didn't have a `+` input. Nowadays, mobile phone users dial international numbers using a `+` rather than an "IDD prefix", but the mobile phone operating system replaces the `+` with an "IDD prefix" under the hood. For example, to call a Russian number `+7 800 555 35 35` from US the dialled digits would be `01178005553535` where `011` is an "IDD prefix".
### `default_idd_prefix`
When a country supports different "IDD prefixes", the `idd_prefix` is a regular expression and `default_idd_prefix` is the default "IDD prefix".
### `ext`
Localized `" ext. "` prefix for this country. For example, in Russia it's `" доб. "`. Is only used for formatting phone numbers having "extensions" (usually these're organizational phone numbers: businesses, governmental institutions, educational institutions, etc).
### `leading_digits`
National (significant) number "leading digits" pattern. It's only defined for about 20% of the countries, and in most cases it's for resolving ambiguity in cases when there're groups of countries sharing the same "country calling code". Although, if there's a group of countries sharing the same "country calling code", it doesn't necessarily mean that those countries have a `leading_digits` pattern defined.
For example, USA and Canada share the same `1` country calling code, but neither of them have a `leading_digits` pattern defined. On the other hand, Antigua and Barbuda also shares the same `1` country calling code, and its `leading_digits` pattern is `"268"`, so if an international phone number starts with `+1268` then it's certain that it belongs to Antigua and Barbuda, so "leading digits" are, in some cases, a quick way of determining which one of the countries sharing the same country calling code does a phone number belong to.
While in most cases a `leading_digits` pattern is a sequence of digits like `"268"` for Antigua and Barbuda, in other cases it's a pattern like `"8001|8[024]9"` for Dominican Republic.
Overall, `leading_digits` patterns are only used as a performance speed-up trick when determining which country a phone number belongs to: the check is still simpler than looking for a match against all of the precise phone number digit patterns of every country sharing a given country calling code.
For that reason, matching a `leading_digits` pattern is a sufficient but not a necessary condition for a phone number to belong to a country: if a `leading_digits` pattern exists and a phone number matches it that it's certain that the phone number belongs to the country, and no other country. But, if there's no `leading_digits` pattern, or if the phone number doesn't match the `leading_digits` pattern, then it doesn't mean that the phone number doesn't belong to the country.
For example, "toll free" numbers starting with `800` are valid for all countries having `1` country calling code, so it doesn't make sense to include `800` in their `leading_digits` patterns. But one could say that those "toll free" numbers could be thought of as an unrelated edge case that can be ignored if the application only deals with human phone numbers.
Another example of phone number that're not included in `leading_digits` patters are ["personal"](https://en.wikipedia.org/wiki/Personal_Communications_Service) (satellite) numbers that start with [`5xx`](https://en.wikipedia.org/wiki/Personal_communications_service_(NANP)) for `+1` calling code.
<!-- https://www.nationalnanpa.com/number_resource_info/5XX_codes.html -->
The last example are mobile phone numbers which sometimes have identical patterns across the countries sharing the same "country calling code". An example are Finland (`FI`) and Åland Islands (`AX`) which share the same `+358` calling code and the same pattern for mobile phone numbers. And while [`+358 457 XXX XXXX`](https://en.wikipedia.org/wiki/Telephone_numbers_in_Åland) mobile numbers could belong both to Finland or Åland Islands, Åland Islands' `leading_digits` pattern is just `18` which doesn't include any mobile numbers at all.
So `leading_digits` patterns could only be used for a quick "positive" check and they can't be used for ruling out any countries.
### `national_number_pattern`
A regular expression covering all possible phone numbers for the country.
### `national_prefix`
"National prefix", also known as "National Direct Dialing prefix". In the early days of analogue telephony, countries were divided into "areas" (for example, cities), and calling within an area (for example, a city) would only involve dialing a phone number without "area code" digits, but calling from one "area" (city) to another (city) would require dialing a "national prefix" first, so that the analogue telephone station would switch the user into "nation-wide" calling mode first.
For example, in New Zealand, the number that would be locally dialled as `09 345 3456` would be dialled from overseas as `+64 9 345 3456`. In this case, `0` is the national prefix.
Other national prefix examples: `1` in US, `0` in France and UK, `8` in Russia.
### `national_prefix_for_parsing` / `national_prefix_transform_rule`
`national_prefix_for_parsing` is used to parse a [national (significant) number](https://gitlab.com/catamphetamine/libphonenumber-js#national-significant-number) from a phone number. Contrary to its name, `national_prefix_for_parsing` is used not just for parsing a "national prefix" out of a phone number (just `national_prefix` property would be sufficient for that), but also for parsing any other possible phone number prefixes out of a phone number, if there're any, and for any other cases like fixing a missing area code. So it's actually not a "national prefix for parsing", but rather a "national (significant) number extraction mechanism".
`national_prefix_for_parsing` is a regular expression that could (or could not) have some ["capturing groups"](https://www.regular-expressions.info/refcapture.html). If there're any "capturing groups", then `national_prefix_for_parsing` is accompanied by `national_prefix_transform_rule`: yet another incorrect name by Google, because `national_prefix_transform_rule` is not a "rule for transforming a national prefix", but rather a "template to transform the captured groups into a national (significant) number".
There're different types of possible "prefixes" a phone number could have. One example are ["carrier codes"](https://www.bandwidth.com/glossary/carrier-identification-code-cic/). If a `national_prefix_transform_rule` is defined and the `national_prefix_for_parsing` has more than one "capturing group", then the second "capturing group" is a "carrier code". If a `national_prefix_transform_rule` is not defined and the `national_prefix_for_parsing` has at least one "capturing group", then the first "capturing group" is a "carrier code".
For example, countries like Argentina and Brazil do use ["carrier codes"](https://www.bandwidth.com/glossary/carrier-identification-code-cic/), and their `national_prefix_for_parsing` regular expressions include both national prefix and all possible "carrier codes". So, for example, to dial the number `2222-2222` in Fortaleza, Brazil (national prefix `0`, area code `85`) using the long distance carrier Oi (selection code `31`), one would dial `0 31 85 2222 2222`, and, for parsing such numbers, Brazil's `national_prefix_for_parsing` is `0(?:(1[245]|2[1-35]|31|4[13]|[56]5|99)(\d{10,11}))?`, which matches the whole `0318522222222` number with captured group #1 being `31` ("carrier code") and captured group #2 being `8522222222` (which is also the actual national (significant) number, because `national_prefix_transform_rule` is `$2`).
Another example of a "prefix": some countries support "utility" prefixes, like Australia (national prefix `0`) that supports `1831` prefix to [hide your phone number](https://exchange.telstra.com.au/how-to-block-your-number-when-calling-someone/) when calling somebody (and `1832` to un-hide it when in "permanent" hiding mode), and so Australia's `national_prefix_for_parsing` is `0|(183[12])`, which matches the `1831` prefix as group #1.
Another example of using a `national_prefix_for_parsing` / `national_prefix_transform_rule` pair, in this case for reasons completely unrelated to any "prefixes", are U.S. Virgin Islands (national prefix `1`) whose phone numbers always start with a `340` area code because there's no other area code in this tiny (`346.36` square kilometers) island country. So it's common for its citizens to call `693-4800` instead of `(340) 693-4800`, and Google's `libphonenumber` handles this case by `national_prefix_for_parsing` being `1|([2-9]\d{6})$`, which matches `6934800` number as group #1, which is later used in `national_prefix_transform_rule`, which is `340$1`, meaning that it prepends `340` to the group #1 being the `6934800` number, resulting in `3406934800` national (significant) number.
If `national_prefix_for_parsing` matches any "capturing groups", then it doesn't provide the actual national prefix being extracted, or even guarantee the fact that there is a national prefix: in those cases, it just converts a national number to a national (significant) number by applying a `national_prefix_for_parsing`/`national_prefix_transform_rule` transform to it.
For example, in `AG` country, phone numbers are same as in the `US`, with the only difference that they start with `268`. The `national_prefix_for_parsing` is `1|([457]\\d{6})$`. If a number is entered with a leading `1` (`"1 268 464 1234"`), then there're no "capturing groups" in that regular expression, so the national prefix is the entire substring matched by the regular expression: `"1"`. If a number is entered without a leading `1` (`"268 464 1234"`), then the regular expression doesn't match, and the number doesn't have a national prefix (which is true). If a number is entered without the "area code" `268` (just `"464 1234"`), then `national_prefix_for_parsing` regular expression matches with the "capturing group" being `"4641234"`, and then `national_prefix_transform_rule` `268$1` transforms that "capturing group" into a `2684641234` national (significant) number; and even though `national_prefix_for_parsing` did match, the phone number didn't have any national prefix.
Another example is Mexico (`MX`) that has no `national_prefix_transform_rule` and has `national_prefix_for_parsing` `0(?:[12]|4[45])|1`: the `?:` defines a "non-capturing group", so `national_prefix_for_parsing` has no "capturing groups", and, therefore, matches the actual national prefix of a phone number; that national prefix isn't used anywhere though: it's simply discarded, because all `format`s of Mexico have `national_prefix_is_optional_when_formatting: true`, meaning that a national prefix isn't used when formatting a phone number using any of those `format`s.
If no `national_prefix_for_parsing` has been defined, but `national_prefix` has been defined, then `national_prefix_for_parsing` is equal to `national_prefix`.
Whatever national prefix has been extracted, it's not used anywhere: instead, `national_prefix_formatting_rule` of a `format` already has a national prefix "hardcoded". For example, in Russia, `national_prefix` is `8`, and `national_prefix_formatting_rule` of all `format`s is `8 ($1)`. So the code doesn't store the extracted national prefix anywhere: only the fact that the national prefix has been extracted is used to decide whether to apply `national_prefix_formatting_rule` when formatting the parsed number.
### `types`
Regular expressions for all possible phone number [types](https://gitlab.com/catamphetamine/libphonenumber-js#gettype-string) for this country: `fixed_line`, `mobile`, `toll_free`, `premium_rate`, etc.
#### `type` `pattern`
A regular expression for a national (significant) number matching the type.
#### `type` `possible_lengths`
Possible lengths of a national (significant) number matching the type. Is always present.
### `examples`
Phone number examples for each of the phone number `types`.
### `possible_lengths`
Possible lengths of a national (significant) number for this numbering plan. This property is a combination of `possible_lengths` of all `types`. Is always present.
### `formats`
Describes all possible phone number formats for this country. May be missing if phone numbers aren't formatted for this country (there're many such countries, usually small islands).
#### `format` `pattern`
A regular expression for a phone number supported by this format.
For example, in `US` there's only one possible phone number format, and it's `pattern` is `(\d{3})(\d{3})(\d{4})`, meaning that the national (significant) number must be `3 + 3 + 4 = 10` digits long (for example, `2133734253`), and is divided into three groups of digits for formatting (in this case, `213`, `373` and `4253`).
#### `format` `format`
Defines how the aforementioned groups of digits are combined when formatting a phone number.
For example, in `US` there's only one possible phone number format, and it's `format` is `($1) $2-$3`, so `2133734253` national (significant) number is formatted as `(213) 373-4253`.
#### `format` `international_format`
Parentheses arond "area code" only make sense when formatting a national phone number, so international phone numbers don't use them, hence the explicit `international_format` in addition to the national `format`.
For example, in `US` there's only one possible phone number format, and it's `format` is `($1) $2-$3`, while its `international_format` is `$1-$2-$3`, meaning that `2133734253` national (significant) number is formatted as `+1 213 373-4253` when formatted for international dialing.
#### `format` `national_prefix_formatting_rule`
`national_prefix_formatting_rule` is sometimes used to define how national prefix changes how a phone number should be formatted. For example, in Russia (national prefix `8`), all `format`s have `national_prefix_formatting_rule` `8 ($1)`, meaning that a `88005553535` phone number is first stripped of `8` national prefix into a `8005553535` national (significant) number, then the national (significant) number is first parsed using `format.pattern` `(\d{3})(\d{3})(\d{2})(\d{2})` and then formatted using `format.format` `$1 $2-$3-$4` while also replacing `$1` in that `format.format` with `format.national_prefix_formatting_rule` which is `8 ($1)`, so the resulting `format.format` becomes `8 ($1) $2-$3-$4`, and so the formatted number is `8 (800) 555-35-35`. Have the phone number been input without the `8` national prefix, the `national_prefix_formatting_rule` wouldn't be applied, and `format.format` would stay `$1 $2-$3-$4`, and the formatted phone number would be `800 555-35-35`.
In some cases (for example, in Argentina), `format.format` may exclude `$1`, so in those cases `national_prefix_formatting_rule` being `0$1` would actually mean `0$2`, because there's no `$1` "capturing group" in `format.format`, but there is `$2` "capturing group" there.
#### `format` `national_prefix_is_optional_when_formatting`
This field specifies whether the national prefix can be omitted when formatting a number in national format. For example, a UK (`GB`) number would be formatted by `libphonenumber` as `020 XXXX XXXX`. Have they seen this number commonly being written without the leading `0` (like `(20) XXXX XXXX`), they would have updated the metadata with `national_prefix_is_optional_when_formatting` being `true` for that `format`, so that such number, when formatted, wouldn't have `national_prefix_formatting_rule` applied to it. Otherwise, if `national_prefix_is_optional_when_formatting` is not set to `true`, `national_prefix_formatting_rule` is always applied (when present).
#### `format` `domestic_carrier_code_formatting_rule`
Specifies how a carrier code (`$CC`) together with the first group (`$FG`) in a national significant number should be formatted, if carrier codes are used when formatting the number for dialing. For example, if a `format`'s `format` is `$1 $2-$3` and `domestic_carrier_code_formatting_rule` is `$NP $CC ($FG)`, then a national number, when having a carrier code, is formatted as `national-prefix carrier-code ($1) $2-$3`.
For example, Google's `libphonenumber` has `formatNumberForMobileDialing()` function that returns a number formatted in such a way that it can be dialed from a mobile phone within a specific country, and it adds ["carrier codes"](https://www.bandwidth.com/glossary/carrier-identification-code-cic/) when dialing within certain countries (Brazil — when dialing from a mobile phone to any number, Colombia — when dialing from a mobile phone to a fixed line number). Since `libphonenumber-js` is not a dialing library, it doesn't provide such a function and doesn't use "carrier codes" when formatting phone numbers, so this property is ignored in this library.
#### `format` `leading_digits_patterns`
"Leading digits" patterns are used in `AsYouType` formatter to choose a format suitable for the phone number being input: if a phone number's "leading digits" match those of a format, then that format is used to format the phone number being input. Each subsequent leading digits pattern in `leading_digits_patterns` array requires one more leading digit.
## Non-geographic
There're [calling codes](https://gitlab.com/catamphetamine/libphonenumber-js#non-geographic) that don't correspond to any country. For example, "Global Mobile Satellite System" (`+881`). Such phone numbering systems are called "non-geographic entities" in Google's code. These "non-geographic entitites" reside in their own `nonGeographic` property, analogous to the `countries` property. `nonGeographic` is an object with keys being calling codes of the corresponding "non-geographic entities", and values being same as the values of the `countries` property.
"Non-geographic" numbering plans don't have [`possible_lengths`](#possible-lengths).

1908
backend/node_modules/libphonenumber-js/README.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
:: Set the current folder to the script's folder.
pushd %~dp0
:: Update metadata and release the new version.
npm run metadata:update:job
:: Restore the previous current folder.
popd

16
backend/node_modules/libphonenumber-js/autoupdate.sh generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
export PATH=/usr/local/bin:$PATH
# Enter this script's folder
cd "${0%/*}"
now=$(date +'%d.%m.%Y')
echo "================================================" | tee /dev/stderr
echo "= Starting metadata update at $now" | tee /dev/stderr
echo "================================================" | tee /dev/stderr
npm run metadata:update:job
# Older way through submitting a pull request to github
# npm run metadata:update:pull-request

View File

@@ -0,0 +1,568 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _metadata = _interopRequireDefault(require("./metadata.js"));
var _PhoneNumber = _interopRequireDefault(require("./PhoneNumber.js"));
var _AsYouTypeState = _interopRequireDefault(require("./AsYouTypeState.js"));
var _AsYouTypeFormatter = _interopRequireWildcard(require("./AsYouTypeFormatter.js"));
var _AsYouTypeParser = _interopRequireWildcard(require("./AsYouTypeParser.js"));
var _getCountryByCallingCode = _interopRequireDefault(require("./helpers/getCountryByCallingCode.js"));
var _getCountryByNationalNumber = _interopRequireDefault(require("./helpers/getCountryByNationalNumber.js"));
var _isObject = _interopRequireDefault(require("./helpers/isObject.js"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
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; }
var USE_NON_GEOGRAPHIC_COUNTRY_CODE = false;
var AsYouType = /*#__PURE__*/function () {
/**
* @param {(string|object)?} [optionsOrDefaultCountry] - The default country used for parsing non-international phone numbers. Can also be an `options` object.
* @param {Object} metadata
*/
function AsYouType(optionsOrDefaultCountry, metadata) {
_classCallCheck(this, AsYouType);
this.metadata = new _metadata["default"](metadata);
var _this$getCountryAndCa = this.getCountryAndCallingCode(optionsOrDefaultCountry),
_this$getCountryAndCa2 = _slicedToArray(_this$getCountryAndCa, 2),
defaultCountry = _this$getCountryAndCa2[0],
defaultCallingCode = _this$getCountryAndCa2[1]; // `this.defaultCountry` and `this.defaultCallingCode` aren't required to be in sync.
// For example, `this.defaultCountry` could be `"AR"` and `this.defaultCallingCode` could be `undefined`.
// So `this.defaultCountry` and `this.defaultCallingCode` are totally independent.
this.defaultCountry = defaultCountry;
this.defaultCallingCode = defaultCallingCode;
this.reset();
}
_createClass(AsYouType, [{
key: "getCountryAndCallingCode",
value: function getCountryAndCallingCode(optionsOrDefaultCountry) {
// Set `defaultCountry` and `defaultCallingCode` options.
var defaultCountry;
var defaultCallingCode; // Turns out `null` also has type "object". Weird.
if (optionsOrDefaultCountry) {
if ((0, _isObject["default"])(optionsOrDefaultCountry)) {
defaultCountry = optionsOrDefaultCountry.defaultCountry;
defaultCallingCode = optionsOrDefaultCountry.defaultCallingCode;
} else {
defaultCountry = optionsOrDefaultCountry;
}
}
if (defaultCountry && !this.metadata.hasCountry(defaultCountry)) {
defaultCountry = undefined;
}
if (defaultCallingCode) {
/* istanbul ignore if */
if (USE_NON_GEOGRAPHIC_COUNTRY_CODE) {
if (this.metadata.isNonGeographicCallingCode(defaultCallingCode)) {
defaultCountry = '001';
}
}
}
return [defaultCountry, defaultCallingCode];
}
/**
* Inputs "next" phone number characters.
* @param {string} text
* @return {string} Formatted phone number characters that have been input so far.
*/
}, {
key: "input",
value: function input(text) {
var _this$parser$input = this.parser.input(text, this.state),
digits = _this$parser$input.digits,
justLeadingPlus = _this$parser$input.justLeadingPlus;
if (justLeadingPlus) {
this.formattedOutput = '+';
} else if (digits) {
this.determineTheCountryIfNeeded(); // Match the available formats by the currently available leading digits.
if (this.state.nationalSignificantNumber) {
this.formatter.narrowDownMatchingFormats(this.state);
}
var formattedNationalNumber;
if (this.metadata.hasSelectedNumberingPlan()) {
formattedNationalNumber = this.formatter.format(digits, this.state);
}
if (formattedNationalNumber === undefined) {
// See if another national (significant) number could be re-extracted.
if (this.parser.reExtractNationalSignificantNumber(this.state)) {
this.determineTheCountryIfNeeded(); // If it could, then re-try formatting the new national (significant) number.
var nationalDigits = this.state.getNationalDigits();
if (nationalDigits) {
formattedNationalNumber = this.formatter.format(nationalDigits, this.state);
}
}
}
this.formattedOutput = formattedNationalNumber ? this.getFullNumber(formattedNationalNumber) : this.getNonFormattedNumber();
}
return this.formattedOutput;
}
}, {
key: "reset",
value: function reset() {
var _this = this;
this.state = new _AsYouTypeState["default"]({
onCountryChange: function onCountryChange(country) {
// Before version `1.6.0`, the official `AsYouType` formatter API
// included the `.country` property of an `AsYouType` instance.
// Since that property (along with the others) have been moved to
// `this.state`, `this.country` property is emulated for compatibility
// with the old versions.
_this.country = country;
},
onCallingCodeChange: function onCallingCodeChange(callingCode, country) {
_this.metadata.selectNumberingPlan(country, callingCode);
_this.formatter.reset(_this.metadata.numberingPlan, _this.state);
_this.parser.reset(_this.metadata.numberingPlan);
}
});
this.formatter = new _AsYouTypeFormatter["default"]({
state: this.state,
metadata: this.metadata
});
this.parser = new _AsYouTypeParser["default"]({
defaultCountry: this.defaultCountry,
defaultCallingCode: this.defaultCallingCode,
metadata: this.metadata,
state: this.state,
onNationalSignificantNumberChange: function onNationalSignificantNumberChange() {
_this.determineTheCountryIfNeeded();
_this.formatter.reset(_this.metadata.numberingPlan, _this.state);
}
});
this.state.reset({
country: this.defaultCountry,
callingCode: this.defaultCallingCode
});
this.formattedOutput = '';
return this;
}
/**
* Returns `true` if the phone number is being input in international format.
* In other words, returns `true` if and only if the parsed phone number starts with a `"+"`.
* @return {boolean}
*/
}, {
key: "isInternational",
value: function isInternational() {
return this.state.international;
}
/**
* Returns the "calling code" part of the phone number when it's being input
* in an international format.
* If no valid calling code has been entered so far, returns `undefined`.
* @return {string} [callingCode]
*/
}, {
key: "getCallingCode",
value: function getCallingCode() {
// If the number is being input in national format and some "default calling code"
// has been passed to `AsYouType` constructor, then `this.state.callingCode`
// is equal to that "default calling code".
//
// If the number is being input in national format and no "default calling code"
// has been passed to `AsYouType` constructor, then returns `undefined`,
// even if a "default country" has been passed to `AsYouType` constructor.
//
if (this.isInternational()) {
return this.state.callingCode;
}
} // A legacy alias.
}, {
key: "getCountryCallingCode",
value: function getCountryCallingCode() {
return this.getCallingCode();
}
/**
* Returns a two-letter country code of the phone number.
* Returns `undefined` for "non-geographic" phone numbering plans.
* Returns `undefined` if no phone number has been input yet.
* @return {string} [country]
*/
}, {
key: "getCountry",
value: function getCountry() {
var digits = this.state.digits; // Return `undefined` if no digits have been input yet.
if (digits) {
return this._getCountry();
}
}
/**
* Returns a two-letter country code of the phone number.
* Returns `undefined` for "non-geographic" phone numbering plans.
* @return {string} [country]
*/
}, {
key: "_getCountry",
value: function _getCountry() {
var country = this.state.country;
/* istanbul ignore if */
if (USE_NON_GEOGRAPHIC_COUNTRY_CODE) {
// `AsYouType.getCountry()` returns `undefined`
// for "non-geographic" phone numbering plans.
if (country === '001') {
return;
}
}
return country;
}
}, {
key: "determineTheCountryIfNeeded",
value: function determineTheCountryIfNeeded() {
// Suppose a user enters a phone number in international format,
// and there're several countries corresponding to that country calling code,
// and a country has been derived from the number, and then
// a user enters one more digit and the number is no longer
// valid for the derived country, so the country should be re-derived
// on every new digit in those cases.
//
// If the phone number is being input in national format,
// then it could be a case when `defaultCountry` wasn't specified
// when creating `AsYouType` instance, and just `defaultCallingCode` was specified,
// and that "calling code" could correspond to a "non-geographic entity",
// or there could be several countries corresponding to that country calling code.
// In those cases, `this.country` is `undefined` and should be derived
// from the number. Again, if country calling code is ambiguous, then
// `this.country` should be re-derived with each new digit.
//
if (!this.state.country || this.isCountryCallingCodeAmbiguous()) {
this.determineTheCountry();
}
} // Prepends `+CountryCode ` in case of an international phone number
}, {
key: "getFullNumber",
value: function getFullNumber(formattedNationalNumber) {
var _this2 = this;
if (this.isInternational()) {
var prefix = function prefix(text) {
return _this2.formatter.getInternationalPrefixBeforeCountryCallingCode(_this2.state, {
spacing: text ? true : false
}) + text;
};
var callingCode = this.state.callingCode;
if (!callingCode) {
return prefix("".concat(this.state.getDigitsWithoutInternationalPrefix()));
}
if (!formattedNationalNumber) {
return prefix(callingCode);
}
return prefix("".concat(callingCode, " ").concat(formattedNationalNumber));
}
return formattedNationalNumber;
}
}, {
key: "getNonFormattedNationalNumberWithPrefix",
value: function getNonFormattedNationalNumberWithPrefix() {
var _this$state = this.state,
nationalSignificantNumber = _this$state.nationalSignificantNumber,
complexPrefixBeforeNationalSignificantNumber = _this$state.complexPrefixBeforeNationalSignificantNumber,
nationalPrefix = _this$state.nationalPrefix;
var number = nationalSignificantNumber;
var prefix = complexPrefixBeforeNationalSignificantNumber || nationalPrefix;
if (prefix) {
number = prefix + number;
}
return number;
}
}, {
key: "getNonFormattedNumber",
value: function getNonFormattedNumber() {
var nationalSignificantNumberMatchesInput = this.state.nationalSignificantNumberMatchesInput;
return this.getFullNumber(nationalSignificantNumberMatchesInput ? this.getNonFormattedNationalNumberWithPrefix() : this.state.getNationalDigits());
}
}, {
key: "getNonFormattedTemplate",
value: function getNonFormattedTemplate() {
var number = this.getNonFormattedNumber();
if (number) {
return number.replace(/[\+\d]/g, _AsYouTypeFormatter.DIGIT_PLACEHOLDER);
}
}
}, {
key: "isCountryCallingCodeAmbiguous",
value: function isCountryCallingCodeAmbiguous() {
var callingCode = this.state.callingCode;
var countryCodes = this.metadata.getCountryCodesForCallingCode(callingCode);
return countryCodes && countryCodes.length > 1;
} // Determines the country of the phone number
// entered so far based on the country phone code
// and the national phone number.
}, {
key: "determineTheCountry",
value: function determineTheCountry() {
this.state.setCountry((0, _getCountryByCallingCode["default"])(this.isInternational() ? this.state.callingCode : this.defaultCallingCode, {
nationalNumber: this.state.nationalSignificantNumber,
defaultCountry: this.defaultCountry,
metadata: this.metadata
}));
}
/**
* Returns a E.164 phone number value for the user's input.
*
* For example, for country `"US"` and input `"(222) 333-4444"`
* it will return `"+12223334444"`.
*
* For international phone number input, it will also auto-correct
* some minor errors such as using a national prefix when writing
* an international phone number. For example, if the user inputs
* `"+44 0 7400 000000"` then it will return an auto-corrected
* `"+447400000000"` phone number value.
*
* Will return `undefined` if no digits have been input,
* or when inputting a phone number in national format and no
* default country or default "country calling code" have been set.
*
* @return {string} [value]
*/
}, {
key: "getNumberValue",
value: function getNumberValue() {
var _this$state2 = this.state,
digits = _this$state2.digits,
callingCode = _this$state2.callingCode,
country = _this$state2.country,
nationalSignificantNumber = _this$state2.nationalSignificantNumber; // Will return `undefined` if no digits have been input.
if (!digits) {
return;
}
if (this.isInternational()) {
if (callingCode) {
return '+' + callingCode + nationalSignificantNumber;
} else {
return '+' + digits;
}
} else {
if (country || callingCode) {
var callingCode_ = country ? this.metadata.countryCallingCode() : callingCode;
return '+' + callingCode_ + nationalSignificantNumber;
}
}
}
/**
* Returns an instance of `PhoneNumber` class.
* Will return `undefined` if no national (significant) number
* digits have been entered so far, or if no `defaultCountry` has been
* set and the user enters a phone number not in international format.
*/
}, {
key: "getNumber",
value: function getNumber() {
var _this$state3 = this.state,
nationalSignificantNumber = _this$state3.nationalSignificantNumber,
carrierCode = _this$state3.carrierCode,
callingCode = _this$state3.callingCode; // `this._getCountry()` is basically same as `this.state.country`
// with the only change that it return `undefined` in case of a
// "non-geographic" numbering plan instead of `"001"` "internal use" value.
var country = this._getCountry();
if (!nationalSignificantNumber) {
return;
} // `state.country` and `state.callingCode` aren't required to be in sync.
// For example, `country` could be `"AR"` and `callingCode` could be `undefined`.
// So `country` and `callingCode` are totally independent.
if (!country && !callingCode) {
return;
} // By default, if `defaultCountry` parameter was passed when
// creating `AsYouType` instance, `state.country` is gonna be
// that `defaultCountry`, which doesn't entirely conform with
// `parsePhoneNumber()`'s behavior where it attempts to determine
// the country more precisely in cases when multiple countries
// could correspond to the same `countryCallingCode`.
// https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/103#note_1417192969
//
// Because `AsYouType.getNumber()` method is supposed to be a 1:1
// equivalent for `parsePhoneNumber(AsYouType.getNumberValue())`,
// then it should also behave accordingly in cases of `country` ambiguity.
// That's how users of this library would expect it to behave anyway.
//
if (country) {
if (country === this.defaultCountry) {
// `state.country` and `state.callingCode` aren't required to be in sync.
// For example, `state.country` could be `"AR"` and `state.callingCode` could be `undefined`.
// So `state.country` and `state.callingCode` are totally independent.
var metadata = new _metadata["default"](this.metadata.metadata);
metadata.selectNumberingPlan(country);
var _callingCode = metadata.numberingPlan.callingCode();
var ambiguousCountries = this.metadata.getCountryCodesForCallingCode(_callingCode);
if (ambiguousCountries.length > 1) {
var exactCountry = (0, _getCountryByNationalNumber["default"])(nationalSignificantNumber, {
countries: ambiguousCountries,
defaultCountry: this.defaultCountry,
metadata: this.metadata.metadata
});
if (exactCountry) {
country = exactCountry;
}
}
}
}
var phoneNumber = new _PhoneNumber["default"](country || callingCode, nationalSignificantNumber, this.metadata.metadata);
if (carrierCode) {
phoneNumber.carrierCode = carrierCode;
} // Phone number extensions are not supported by "As You Type" formatter.
return phoneNumber;
}
/**
* Returns `true` if the phone number is "possible".
* Is just a shortcut for `PhoneNumber.isPossible()`.
* @return {boolean}
*/
}, {
key: "isPossible",
value: function isPossible() {
var phoneNumber = this.getNumber();
if (!phoneNumber) {
return false;
}
return phoneNumber.isPossible();
}
/**
* Returns `true` if the phone number is "valid".
* Is just a shortcut for `PhoneNumber.isValid()`.
* @return {boolean}
*/
}, {
key: "isValid",
value: function isValid() {
var phoneNumber = this.getNumber();
if (!phoneNumber) {
return false;
}
return phoneNumber.isValid();
}
/**
* @deprecated
* This method is used in `react-phone-number-input/source/input-control.js`
* in versions before `3.0.16`.
*/
}, {
key: "getNationalNumber",
value: function getNationalNumber() {
return this.state.nationalSignificantNumber;
}
/**
* Returns the phone number characters entered by the user.
* @return {string}
*/
}, {
key: "getChars",
value: function getChars() {
return (this.state.international ? '+' : '') + this.state.digits;
}
/**
* Returns the template for the formatted phone number.
* @return {string}
*/
}, {
key: "getTemplate",
value: function getTemplate() {
return this.formatter.getTemplate(this.state) || this.getNonFormattedTemplate() || '';
}
}]);
return AsYouType;
}();
exports["default"] = AsYouType;
//# sourceMappingURL=AsYouType.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,264 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _AsYouTypeFormatterPatternParser = _interopRequireDefault(require("./AsYouTypeFormatter.PatternParser.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
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; }
var PatternMatcher = /*#__PURE__*/function () {
function PatternMatcher(pattern) {
_classCallCheck(this, PatternMatcher);
this.matchTree = new _AsYouTypeFormatterPatternParser["default"]().parse(pattern);
}
_createClass(PatternMatcher, [{
key: "match",
value: function match(string) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
allowOverflow = _ref.allowOverflow;
if (!string) {
throw new Error('String is required');
}
var result = _match(string.split(''), this.matchTree, true);
if (result && result.match) {
delete result.matchedChars;
}
if (result && result.overflow) {
if (!allowOverflow) {
return;
}
}
return result;
}
}]);
return PatternMatcher;
}();
/**
* Matches `characters` against a pattern compiled into a `tree`.
* @param {string[]} characters
* @param {Tree} tree — A pattern compiled into a `tree`. See the `*.d.ts` file for the description of the `tree` structure.
* @param {boolean} last — Whether it's the last (rightmost) subtree on its level of the match tree.
* @return {object} See the `*.d.ts` file for the description of the result object.
*/
exports["default"] = PatternMatcher;
function _match(characters, tree, last) {
// If `tree` is a string, then `tree` is a single character.
// That's because when a pattern is parsed, multi-character-string parts
// of a pattern are compiled into arrays of single characters.
// I still wrote this piece of code for a "general" hypothetical case
// when `tree` could be a string of several characters, even though
// such case is not possible with the current implementation.
if (typeof tree === 'string') {
var characterString = characters.join('');
if (tree.indexOf(characterString) === 0) {
// `tree` is always a single character.
// If `tree.indexOf(characterString) === 0`
// then `characters.length === tree.length`.
/* istanbul ignore else */
if (characters.length === tree.length) {
return {
match: true,
matchedChars: characters
};
} // `tree` is always a single character.
// If `tree.indexOf(characterString) === 0`
// then `characters.length === tree.length`.
/* istanbul ignore next */
return {
partialMatch: true // matchedChars: characters
};
}
if (characterString.indexOf(tree) === 0) {
if (last) {
// The `else` path is not possible because `tree` is always a single character.
// The `else` case for `characters.length > tree.length` would be
// `characters.length <= tree.length` which means `characters.length <= 1`.
// `characters` array can't be empty, so that means `characters === [tree]`,
// which would also mean `tree.indexOf(characterString) === 0` and that'd mean
// that the `if (tree.indexOf(characterString) === 0)` condition before this
// `if` condition would be entered, and returned from there, not reaching this code.
/* istanbul ignore else */
if (characters.length > tree.length) {
return {
overflow: true
};
}
}
return {
match: true,
matchedChars: characters.slice(0, tree.length)
};
}
return;
}
if (Array.isArray(tree)) {
var restCharacters = characters.slice();
var i = 0;
while (i < tree.length) {
var subtree = tree[i];
var result = _match(restCharacters, subtree, last && i === tree.length - 1);
if (!result) {
return;
} else if (result.overflow) {
return result;
} else if (result.match) {
// Continue with the next subtree with the rest of the characters.
restCharacters = restCharacters.slice(result.matchedChars.length);
if (restCharacters.length === 0) {
if (i === tree.length - 1) {
return {
match: true,
matchedChars: characters
};
} else {
return {
partialMatch: true // matchedChars: characters
};
}
}
} else {
/* istanbul ignore else */
if (result.partialMatch) {
return {
partialMatch: true // matchedChars: characters
};
} else {
throw new Error("Unsupported match result:\n".concat(JSON.stringify(result, null, 2)));
}
}
i++;
} // If `last` then overflow has already been checked
// by the last element of the `tree` array.
/* istanbul ignore if */
if (last) {
return {
overflow: true
};
}
return {
match: true,
matchedChars: characters.slice(0, characters.length - restCharacters.length)
};
}
switch (tree.op) {
case '|':
var partialMatch;
for (var _iterator = _createForOfIteratorHelperLoose(tree.args), _step; !(_step = _iterator()).done;) {
var branch = _step.value;
var _result = _match(characters, branch, last);
if (_result) {
if (_result.overflow) {
return _result;
} else if (_result.match) {
return {
match: true,
matchedChars: _result.matchedChars
};
} else {
/* istanbul ignore else */
if (_result.partialMatch) {
partialMatch = true;
} else {
throw new Error("Unsupported match result:\n".concat(JSON.stringify(_result, null, 2)));
}
}
}
}
if (partialMatch) {
return {
partialMatch: true // matchedChars: ...
};
} // Not even a partial match.
return;
case '[]':
for (var _iterator2 = _createForOfIteratorHelperLoose(tree.args), _step2; !(_step2 = _iterator2()).done;) {
var _char = _step2.value;
if (characters[0] === _char) {
if (characters.length === 1) {
return {
match: true,
matchedChars: characters
};
}
if (last) {
return {
overflow: true
};
}
return {
match: true,
matchedChars: [_char]
};
}
} // No character matches.
return;
/* istanbul ignore next */
default:
throw new Error("Unsupported instruction tree: ".concat(tree));
}
}
//# sourceMappingURL=AsYouTypeFormatter.PatternMatcher.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,502 @@
"use strict";
var _AsYouTypeFormatterPatternMatcher = _interopRequireDefault(require("./AsYouTypeFormatter.PatternMatcher.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('AsYouTypeFormatter.PatternMatcher', function () {
it('should throw when no pattern is passed', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]();
}).to["throw"]('Pattern is required');
});
it('should throw when no string is passed', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('1');
expect(function () {
return matcher.match();
}).to["throw"]('String is required');
});
it('should throw on illegal characters', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('4(5|6)7');
}).to["throw"]('Illegal characters');
});
it('should throw on an illegal ] operator', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('4]7');
}).to["throw"]('"]" operator must be preceded by "[" operator');
});
it('should throw on an illegal - operator in a one-of set', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('[-5]');
}).to["throw"]('Couldn\'t parse a one-of set pattern: -5');
});
it('should throw on a non-finalized context', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('4(?:5|7');
}).to["throw"]('Non-finalized contexts left when pattern parse ended');
});
it('should throw on an illegal (|) operator', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('4(?:5|)7');
}).to["throw"]('No instructions found after "|" operator in an "or" group');
});
it('should throw on an illegal ) operator', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('4[56)]7');
}).to["throw"]('")" operator must be preceded by "(?:" operator');
});
it('should throw on an illegal | operator', function () {
expect(function () {
return new _AsYouTypeFormatterPatternMatcher["default"]('4[5|6]7');
}).to["throw"]('operator can only be used inside "or" groups');
});
it('should match a one-digit pattern', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('4');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('44')).to.be.undefined;
matcher.match('44', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a two-digit pattern', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('44');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
partialMatch: true
});
matcher.match('44').should.deep.equal({
match: true
});
expect(matcher.match('444')).to.be.undefined;
matcher.match('444', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
expect(matcher.match('55')).to.be.undefined;
});
it('should match a one-digit one-of set (single digit)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[4]');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('44')).to.be.undefined;
matcher.match('44', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a one-digit one-of set (multiple digits)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[479]');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('44')).to.be.undefined;
matcher.match('44', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a one-digit one-of set using a dash notation (not inclusive)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[2-5]');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('44')).to.be.undefined;
matcher.match('44', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a one-digit one-of set using a dash notation (inclusive)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[3-4]');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('44')).to.be.undefined;
matcher.match('44', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a one-digit one-of set including a dash notation', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[124-68]');
expect(matcher.match('0')).to.be.undefined;
matcher.match('1').should.deep.equal({
match: true
});
matcher.match('2').should.deep.equal({
match: true
});
expect(matcher.match('3')).to.be.undefined;
matcher.match('4').should.deep.equal({
match: true
});
matcher.match('5').should.deep.equal({
match: true
});
matcher.match('6').should.deep.equal({
match: true
});
expect(matcher.match('7')).to.be.undefined;
matcher.match('8').should.deep.equal({
match: true
});
expect(matcher.match('9')).to.be.undefined;
expect(matcher.match('88')).to.be.undefined;
matcher.match('88', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a two-digit one-of set', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[479][45]');
expect(matcher.match('1')).to.be.undefined;
matcher.match('4').should.deep.equal({
partialMatch: true
});
expect(matcher.match('5')).to.be.undefined;
expect(matcher.match('55')).to.be.undefined;
matcher.match('44').should.deep.equal({
match: true
});
expect(matcher.match('444')).to.be.undefined;
matcher.match('444', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match a two-digit one-of set (regular digit and a one-of set)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('1[45]');
expect(matcher.match('0')).to.be.undefined;
matcher.match('1').should.deep.equal({
partialMatch: true
});
matcher.match('15').should.deep.equal({
match: true
});
expect(matcher.match('16')).to.be.undefined;
});
it('should match a pattern with an or group', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('7(?:1[0-68]|2[1-9])');
expect(matcher.match('1')).to.be.undefined;
matcher.match('7').should.deep.equal({
partialMatch: true
});
matcher.match('71').should.deep.equal({
partialMatch: true
});
expect(matcher.match('73')).to.be.undefined;
matcher.match('711').should.deep.equal({
match: true
});
expect(matcher.match('717')).to.be.undefined;
expect(matcher.match('720')).to.be.undefined;
matcher.match('722').should.deep.equal({
match: true
});
expect(matcher.match('7222')).to.be.undefined;
matcher.match('7222', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match an or pattern containing or groups', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('2(?:2[024-9]|3[0-59]|47|6[245]|9[02-8])|3(?:3[28]|4[03-9]|5[2-46-8]|7[1-578]|8[2-9])');
expect(matcher.match('1')).to.be.undefined;
matcher.match('2').should.deep.equal({
partialMatch: true
});
matcher.match('3').should.deep.equal({
partialMatch: true
});
expect(matcher.match('4')).to.be.undefined;
expect(matcher.match('21')).to.be.undefined;
matcher.match('22').should.deep.equal({
partialMatch: true
});
expect(matcher.match('221')).to.be.undefined;
matcher.match('222').should.deep.equal({
match: true
});
expect(matcher.match('2222')).to.be.undefined;
matcher.match('2222', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
matcher.match('3').should.deep.equal({
partialMatch: true
});
matcher.match('33').should.deep.equal({
partialMatch: true
});
matcher.match('332').should.deep.equal({
match: true
});
expect(matcher.match('333')).to.be.undefined;
});
it('should match an or pattern', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('6|8');
expect(matcher.match('5')).to.be.undefined;
matcher.match('6').should.deep.equal({
match: true
});
expect(matcher.match('7')).to.be.undefined;
matcher.match('8').should.deep.equal({
match: true
});
});
it('should match an or pattern (one-of sets)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[123]|[5-8]');
expect(matcher.match('0')).to.be.undefined;
matcher.match('1').should.deep.equal({
match: true
});
matcher.match('2').should.deep.equal({
match: true
});
matcher.match('3').should.deep.equal({
match: true
});
expect(matcher.match('4')).to.be.undefined;
matcher.match('5').should.deep.equal({
match: true
});
matcher.match('6').should.deep.equal({
match: true
});
matcher.match('7').should.deep.equal({
match: true
});
matcher.match('8').should.deep.equal({
match: true
});
expect(matcher.match('9')).to.be.undefined;
expect(matcher.match('18')).to.be.undefined;
matcher.match('18', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
});
it('should match an or pattern (different lengths)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('60|8');
expect(matcher.match('5')).to.be.undefined;
matcher.match('6').should.deep.equal({
partialMatch: true
});
matcher.match('60').should.deep.equal({
match: true
});
expect(matcher.match('61')).to.be.undefined;
expect(matcher.match('7')).to.be.undefined;
matcher.match('8').should.deep.equal({
match: true
});
expect(matcher.match('68')).to.be.undefined;
});
it('should match an or pattern (one-of sets) (different lengths)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[123]|[5-8][2-8]');
expect(matcher.match('0')).to.be.undefined;
});
it('should match an or pattern (one-of sets and regular digits) (different lengths)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[2358][2-5]|4');
expect(matcher.match('0')).to.be.undefined;
matcher.match('2').should.deep.equal({
partialMatch: true
});
expect(matcher.match('21')).to.be.undefined;
matcher.match('22').should.deep.equal({
match: true
});
matcher.match('25').should.deep.equal({
match: true
});
expect(matcher.match('26')).to.be.undefined;
expect(matcher.match('222')).to.be.undefined;
matcher.match('222', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
matcher.match('3').should.deep.equal({
partialMatch: true
});
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('6')).to.be.undefined;
});
it('should match an or pattern (one-of sets and regular digits mixed) (different lengths)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('[2358]2|4');
expect(matcher.match('0')).to.be.undefined;
matcher.match('2').should.deep.equal({
partialMatch: true
});
expect(matcher.match('21')).to.be.undefined;
matcher.match('22').should.deep.equal({
match: true
});
expect(matcher.match('222')).to.be.undefined;
matcher.match('222', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
matcher.match('3').should.deep.equal({
partialMatch: true
});
matcher.match('4').should.deep.equal({
match: true
});
expect(matcher.match('6')).to.be.undefined;
});
it('should match an or pattern (one-of sets groups and regular digits mixed) (different lengths)', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('1(?:11|[2-9])');
matcher.match('1').should.deep.equal({
partialMatch: true
});
expect(matcher.match('10')).to.be.undefined;
matcher.match('11').should.deep.equal({
partialMatch: true
});
matcher.match('111').should.deep.equal({
match: true
});
expect(matcher.match('1111')).to.be.undefined;
matcher.match('1111', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
matcher.match('12').should.deep.equal({
match: true
});
expect(matcher.match('122')).to.be.undefined;
matcher.match('19').should.deep.equal({
match: true
});
expect(matcher.match('5')).to.be.undefined;
});
it('should match nested or groups', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('1(?:2(?:3(?:4|5)|6)|7(?:8|9))0');
matcher.match('1').should.deep.equal({
partialMatch: true
});
expect(matcher.match('2')).to.be.undefined;
expect(matcher.match('11')).to.be.undefined;
matcher.match('12').should.deep.equal({
partialMatch: true
});
expect(matcher.match('121')).to.be.undefined;
matcher.match('123').should.deep.equal({
partialMatch: true
});
expect(matcher.match('1231')).to.be.undefined;
matcher.match('1234').should.deep.equal({
partialMatch: true
});
matcher.match('12340').should.deep.equal({
match: true
});
expect(matcher.match('123401')).to.be.undefined;
matcher.match('123401', {
allowOverflow: true
}).should.deep.equal({
overflow: true
});
matcher.match('12350').should.deep.equal({
match: true
});
expect(matcher.match('12360')).to.be.undefined;
matcher.match('1260').should.deep.equal({
match: true
});
expect(matcher.match('1270')).to.be.undefined;
expect(matcher.match('1770')).to.be.undefined;
matcher.match('1780').should.deep.equal({
match: true
});
matcher.match('1790').should.deep.equal({
match: true
});
expect(matcher.match('18')).to.be.undefined;
});
it('should match complex patterns', function () {
var matcher = new _AsYouTypeFormatterPatternMatcher["default"]('(?:31|4)6|51|6(?:5[0-3579]|[6-9])|7(?:20|32|8)|[89]');
expect(matcher.match('0')).to.be.undefined;
matcher.match('3').should.deep.equal({
partialMatch: true
});
matcher.match('31').should.deep.equal({
partialMatch: true
});
expect(matcher.match('32')).to.be.undefined;
matcher.match('316').should.deep.equal({
match: true
});
expect(matcher.match('315')).to.be.undefined;
matcher.match('4').should.deep.equal({
partialMatch: true
});
matcher.match('46').should.deep.equal({
match: true
});
expect(matcher.match('47')).to.be.undefined;
matcher.match('5').should.deep.equal({
partialMatch: true
});
expect(matcher.match('50')).to.be.undefined;
matcher.match('51').should.deep.equal({
match: true
});
matcher.match('6').should.deep.equal({
partialMatch: true
});
expect(matcher.match('64')).to.be.undefined;
matcher.match('65').should.deep.equal({
partialMatch: true
});
matcher.match('650').should.deep.equal({
match: true
});
expect(matcher.match('654')).to.be.undefined;
matcher.match('69').should.deep.equal({
match: true
});
matcher.match('8').should.deep.equal({
match: true
});
matcher.match('9').should.deep.equal({
match: true
});
});
it('shouldn\'t match things that shouldn\'t match', function () {
// There was a bug: "leading digits" `"2"` matched "leading digits pattern" `"90"`.
// The incorrect `.match()` function result was `{ oveflow: true }`
// while it should've been `undefined`.
// https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/66
expect(new _AsYouTypeFormatterPatternMatcher["default"]('2').match('90', {
allowOverflow: true
})).to.be.undefined;
});
});
//# sourceMappingURL=AsYouTypeFormatter.PatternMatcher.test.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,241 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
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; }
var PatternParser = /*#__PURE__*/function () {
function PatternParser() {
_classCallCheck(this, PatternParser);
}
_createClass(PatternParser, [{
key: "parse",
value: function parse(pattern) {
this.context = [{
or: true,
instructions: []
}];
this.parsePattern(pattern);
if (this.context.length !== 1) {
throw new Error('Non-finalized contexts left when pattern parse ended');
}
var _this$context$ = this.context[0],
branches = _this$context$.branches,
instructions = _this$context$.instructions;
if (branches) {
return {
op: '|',
args: branches.concat([expandSingleElementArray(instructions)])
};
}
/* istanbul ignore if */
if (instructions.length === 0) {
throw new Error('Pattern is required');
}
if (instructions.length === 1) {
return instructions[0];
}
return instructions;
}
}, {
key: "startContext",
value: function startContext(context) {
this.context.push(context);
}
}, {
key: "endContext",
value: function endContext() {
this.context.pop();
}
}, {
key: "getContext",
value: function getContext() {
return this.context[this.context.length - 1];
}
}, {
key: "parsePattern",
value: function parsePattern(pattern) {
if (!pattern) {
throw new Error('Pattern is required');
}
var match = pattern.match(OPERATOR);
if (!match) {
if (ILLEGAL_CHARACTER_REGEXP.test(pattern)) {
throw new Error("Illegal characters found in a pattern: ".concat(pattern));
}
this.getContext().instructions = this.getContext().instructions.concat(pattern.split(''));
return;
}
var operator = match[1];
var before = pattern.slice(0, match.index);
var rightPart = pattern.slice(match.index + operator.length);
switch (operator) {
case '(?:':
if (before) {
this.parsePattern(before);
}
this.startContext({
or: true,
instructions: [],
branches: []
});
break;
case ')':
if (!this.getContext().or) {
throw new Error('")" operator must be preceded by "(?:" operator');
}
if (before) {
this.parsePattern(before);
}
if (this.getContext().instructions.length === 0) {
throw new Error('No instructions found after "|" operator in an "or" group');
}
var _this$getContext = this.getContext(),
branches = _this$getContext.branches;
branches.push(expandSingleElementArray(this.getContext().instructions));
this.endContext();
this.getContext().instructions.push({
op: '|',
args: branches
});
break;
case '|':
if (!this.getContext().or) {
throw new Error('"|" operator can only be used inside "or" groups');
}
if (before) {
this.parsePattern(before);
} // The top-level is an implicit "or" group, if required.
if (!this.getContext().branches) {
// `branches` are not defined only for the root implicit "or" operator.
/* istanbul ignore else */
if (this.context.length === 1) {
this.getContext().branches = [];
} else {
throw new Error('"branches" not found in an "or" group context');
}
}
this.getContext().branches.push(expandSingleElementArray(this.getContext().instructions));
this.getContext().instructions = [];
break;
case '[':
if (before) {
this.parsePattern(before);
}
this.startContext({
oneOfSet: true
});
break;
case ']':
if (!this.getContext().oneOfSet) {
throw new Error('"]" operator must be preceded by "[" operator');
}
this.endContext();
this.getContext().instructions.push({
op: '[]',
args: parseOneOfSet(before)
});
break;
/* istanbul ignore next */
default:
throw new Error("Unknown operator: ".concat(operator));
}
if (rightPart) {
this.parsePattern(rightPart);
}
}
}]);
return PatternParser;
}();
exports["default"] = PatternParser;
function parseOneOfSet(pattern) {
var values = [];
var i = 0;
while (i < pattern.length) {
if (pattern[i] === '-') {
if (i === 0 || i === pattern.length - 1) {
throw new Error("Couldn't parse a one-of set pattern: ".concat(pattern));
}
var prevValue = pattern[i - 1].charCodeAt(0) + 1;
var nextValue = pattern[i + 1].charCodeAt(0) - 1;
var value = prevValue;
while (value <= nextValue) {
values.push(String.fromCharCode(value));
value++;
}
} else {
values.push(pattern[i]);
}
i++;
}
return values;
}
var ILLEGAL_CHARACTER_REGEXP = /[\(\)\[\]\?\:\|]/;
var OPERATOR = new RegExp( // any of:
'(' + // or operator
'\\|' + // or
'|' + // or group start
'\\(\\?\\:' + // or
'|' + // or group end
'\\)' + // or
'|' + // one-of set start
'\\[' + // or
'|' + // one-of set end
'\\]' + ')');
function expandSingleElementArray(array) {
if (array.length === 1) {
return array[0];
}
return array;
}
//# sourceMappingURL=AsYouTypeFormatter.PatternParser.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
"use strict";
var _AsYouTypeFormatterPatternParser = _interopRequireDefault(require("./AsYouTypeFormatter.PatternParser.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('PatternParser', function () {
it('should parse single-character patterns', function () {
new _AsYouTypeFormatterPatternParser["default"]().parse('2').should.deep.equal('2');
});
it('should parse string patterns', function () {
new _AsYouTypeFormatterPatternParser["default"]().parse('123').should.deep.equal(['1', '2', '3']);
});
it('should parse "one of" patterns', function () {
new _AsYouTypeFormatterPatternParser["default"]().parse('[5-9]').should.deep.equal({
op: '[]',
args: ['5', '6', '7', '8', '9']
});
});
it('should parse "or" patterns', function () {
new _AsYouTypeFormatterPatternParser["default"]().parse('123|[5-9]').should.deep.equal({
op: '|',
args: [['1', '2', '3'], {
op: '[]',
args: ['5', '6', '7', '8', '9']
}]
});
new _AsYouTypeFormatterPatternParser["default"]().parse('123|[5-9]0').should.deep.equal({
op: '|',
args: [['1', '2', '3'], [{
op: '[]',
args: ['5', '6', '7', '8', '9']
}, '0']]
});
});
it('should parse nested "or" patterns', function () {
new _AsYouTypeFormatterPatternParser["default"]().parse('123|(?:2|34)[5-9]').should.deep.equal({
op: '|',
args: [['1', '2', '3'], [{
op: '|',
args: ['2', ['3', '4']]
}, {
op: '[]',
args: ['5', '6', '7', '8', '9']
}]]
});
});
});
//# sourceMappingURL=AsYouTypeFormatter.PatternParser.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AsYouTypeFormatter.PatternParser.test.js","names":["describe","it","PatternParser","parse","should","deep","equal","op","args"],"sources":["../source/AsYouTypeFormatter.PatternParser.test.js"],"sourcesContent":["import PatternParser from './AsYouTypeFormatter.PatternParser.js'\r\n\r\ndescribe('PatternParser', function() {\r\n\tit('should parse single-character patterns', function() {\r\n\t\tnew PatternParser().parse('2').should.deep.equal('2')\r\n\t})\r\n\r\n\tit('should parse string patterns', function() {\r\n\t\tnew PatternParser().parse('123').should.deep.equal(['1', '2', '3'])\r\n\t})\r\n\r\n\tit('should parse \"one of\" patterns', function() {\r\n\t\tnew PatternParser().parse('[5-9]').should.deep.equal({\r\n\t\t\top: '[]',\r\n\t\t\targs: ['5', '6', '7', '8', '9']\r\n\t\t})\r\n\t})\r\n\r\n\tit('should parse \"or\" patterns', function() {\r\n\t\tnew PatternParser().parse('123|[5-9]').should.deep.equal({\r\n\t\t\top: '|',\r\n\t\t\targs: [\r\n\t\t\t\t['1', '2', '3'],\r\n\t\t\t\t{\r\n\t\t\t\t\top: '[]',\r\n\t\t\t\t\targs: ['5', '6', '7', '8', '9']\r\n\t\t\t\t}\r\n\t\t\t]\r\n\t\t})\r\n\r\n\t\tnew PatternParser().parse('123|[5-9]0').should.deep.equal({\r\n\t\t\top: '|',\r\n\t\t\targs: [\r\n\t\t\t\t['1', '2', '3'],\r\n\t\t\t\t[\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\top: '[]',\r\n\t\t\t\t\t\targs: ['5', '6', '7', '8', '9']\r\n\t\t\t\t\t},\r\n\t\t\t\t\t'0'\r\n\t\t\t\t]\r\n\t\t\t]\r\n\t\t})\r\n\t})\r\n\r\n\tit('should parse nested \"or\" patterns', function() {\r\n\t\tnew PatternParser().parse('123|(?:2|34)[5-9]').should.deep.equal({\r\n\t\t\top: '|',\r\n\t\t\targs: [\r\n\t\t\t\t['1', '2', '3'],\r\n\t\t\t\t[\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\top: '|',\r\n\t\t\t\t\t\targs: [\r\n\t\t\t\t\t\t\t'2',\r\n\t\t\t\t\t\t\t['3', '4']\r\n\t\t\t\t\t\t]\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\top: '[]',\r\n\t\t\t\t\t\targs: ['5', '6', '7', '8', '9']\r\n\t\t\t\t\t}\r\n\t\t\t\t]\r\n\t\t\t]\r\n\t\t})\r\n\t})\r\n})"],"mappings":";;AAAA;;;;AAEAA,QAAQ,CAAC,eAAD,EAAkB,YAAW;EACpCC,EAAE,CAAC,wCAAD,EAA2C,YAAW;IACvD,IAAIC,2CAAJ,GAAoBC,KAApB,CAA0B,GAA1B,EAA+BC,MAA/B,CAAsCC,IAAtC,CAA2CC,KAA3C,CAAiD,GAAjD;EACA,CAFC,CAAF;EAIAL,EAAE,CAAC,8BAAD,EAAiC,YAAW;IAC7C,IAAIC,2CAAJ,GAAoBC,KAApB,CAA0B,KAA1B,EAAiCC,MAAjC,CAAwCC,IAAxC,CAA6CC,KAA7C,CAAmD,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,CAAnD;EACA,CAFC,CAAF;EAIAL,EAAE,CAAC,gCAAD,EAAmC,YAAW;IAC/C,IAAIC,2CAAJ,GAAoBC,KAApB,CAA0B,OAA1B,EAAmCC,MAAnC,CAA0CC,IAA1C,CAA+CC,KAA/C,CAAqD;MACpDC,EAAE,EAAE,IADgD;MAEpDC,IAAI,EAAE,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,EAAgB,GAAhB,EAAqB,GAArB;IAF8C,CAArD;EAIA,CALC,CAAF;EAOAP,EAAE,CAAC,4BAAD,EAA+B,YAAW;IAC3C,IAAIC,2CAAJ,GAAoBC,KAApB,CAA0B,WAA1B,EAAuCC,MAAvC,CAA8CC,IAA9C,CAAmDC,KAAnD,CAAyD;MACxDC,EAAE,EAAE,GADoD;MAExDC,IAAI,EAAE,CACL,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,CADK,EAEL;QACCD,EAAE,EAAE,IADL;QAECC,IAAI,EAAE,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,EAAgB,GAAhB,EAAqB,GAArB;MAFP,CAFK;IAFkD,CAAzD;IAWA,IAAIN,2CAAJ,GAAoBC,KAApB,CAA0B,YAA1B,EAAwCC,MAAxC,CAA+CC,IAA/C,CAAoDC,KAApD,CAA0D;MACzDC,EAAE,EAAE,GADqD;MAEzDC,IAAI,EAAE,CACL,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,CADK,EAEL,CACC;QACCD,EAAE,EAAE,IADL;QAECC,IAAI,EAAE,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,EAAgB,GAAhB,EAAqB,GAArB;MAFP,CADD,EAKC,GALD,CAFK;IAFmD,CAA1D;EAaA,CAzBC,CAAF;EA2BAP,EAAE,CAAC,mCAAD,EAAsC,YAAW;IAClD,IAAIC,2CAAJ,GAAoBC,KAApB,CAA0B,mBAA1B,EAA+CC,MAA/C,CAAsDC,IAAtD,CAA2DC,KAA3D,CAAiE;MAChEC,EAAE,EAAE,GAD4D;MAEhEC,IAAI,EAAE,CACL,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,CADK,EAEL,CACC;QACCD,EAAE,EAAE,GADL;QAECC,IAAI,EAAE,CACL,GADK,EAEL,CAAC,GAAD,EAAM,GAAN,CAFK;MAFP,CADD,EAQC;QACCD,EAAE,EAAE,IADL;QAECC,IAAI,EAAE,CAAC,GAAD,EAAM,GAAN,EAAW,GAAX,EAAgB,GAAhB,EAAqB,GAArB;MAFP,CARD,CAFK;IAF0D,CAAjE;EAmBA,CApBC,CAAF;AAqBA,CAhEO,CAAR"}

View File

@@ -0,0 +1,133 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.canFormatCompleteNumber = canFormatCompleteNumber;
exports["default"] = formatCompleteNumber;
var _checkNumberLength = _interopRequireDefault(require("./helpers/checkNumberLength.js"));
var _parseDigits = _interopRequireDefault(require("./helpers/parseDigits.js"));
var _formatNationalNumberUsingFormat = _interopRequireDefault(require("./helpers/formatNationalNumberUsingFormat.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function formatCompleteNumber(state, format, _ref) {
var metadata = _ref.metadata,
shouldTryNationalPrefixFormattingRule = _ref.shouldTryNationalPrefixFormattingRule,
getSeparatorAfterNationalPrefix = _ref.getSeparatorAfterNationalPrefix;
var matcher = new RegExp("^(?:".concat(format.pattern(), ")$"));
if (matcher.test(state.nationalSignificantNumber)) {
return formatNationalNumberWithAndWithoutNationalPrefixFormattingRule(state, format, {
metadata: metadata,
shouldTryNationalPrefixFormattingRule: shouldTryNationalPrefixFormattingRule,
getSeparatorAfterNationalPrefix: getSeparatorAfterNationalPrefix
});
}
}
function canFormatCompleteNumber(nationalSignificantNumber, metadata) {
return (0, _checkNumberLength["default"])(nationalSignificantNumber, metadata) === 'IS_POSSIBLE';
}
function formatNationalNumberWithAndWithoutNationalPrefixFormattingRule(state, format, _ref2) {
var metadata = _ref2.metadata,
shouldTryNationalPrefixFormattingRule = _ref2.shouldTryNationalPrefixFormattingRule,
getSeparatorAfterNationalPrefix = _ref2.getSeparatorAfterNationalPrefix;
// `format` has already been checked for `nationalPrefix` requirement.
var nationalSignificantNumber = state.nationalSignificantNumber,
international = state.international,
nationalPrefix = state.nationalPrefix,
carrierCode = state.carrierCode; // Format the number with using `national_prefix_formatting_rule`.
// If the resulting formatted number is a valid formatted number, then return it.
//
// Google's AsYouType formatter is different in a way that it doesn't try
// to format using the "national prefix formatting rule", and instead it
// simply prepends a national prefix followed by a " " character.
// This code does that too, but as a fallback.
// The reason is that "national prefix formatting rule" may use parentheses,
// which wouldn't be included has it used the simpler Google's way.
//
if (shouldTryNationalPrefixFormattingRule(format)) {
var formattedNumber = formatNationalNumber(state, format, {
useNationalPrefixFormattingRule: true,
getSeparatorAfterNationalPrefix: getSeparatorAfterNationalPrefix,
metadata: metadata
});
if (formattedNumber) {
return formattedNumber;
}
} // Format the number without using `national_prefix_formatting_rule`.
return formatNationalNumber(state, format, {
useNationalPrefixFormattingRule: false,
getSeparatorAfterNationalPrefix: getSeparatorAfterNationalPrefix,
metadata: metadata
});
}
function formatNationalNumber(state, format, _ref3) {
var metadata = _ref3.metadata,
useNationalPrefixFormattingRule = _ref3.useNationalPrefixFormattingRule,
getSeparatorAfterNationalPrefix = _ref3.getSeparatorAfterNationalPrefix;
var formattedNationalNumber = (0, _formatNationalNumberUsingFormat["default"])(state.nationalSignificantNumber, format, {
carrierCode: state.carrierCode,
useInternationalFormat: state.international,
withNationalPrefix: useNationalPrefixFormattingRule,
metadata: metadata
});
if (!useNationalPrefixFormattingRule) {
if (state.nationalPrefix) {
// If a national prefix was extracted, then just prepend it,
// followed by a " " character.
formattedNationalNumber = state.nationalPrefix + getSeparatorAfterNationalPrefix(format) + formattedNationalNumber;
} else if (state.complexPrefixBeforeNationalSignificantNumber) {
formattedNationalNumber = state.complexPrefixBeforeNationalSignificantNumber + ' ' + formattedNationalNumber;
}
}
if (isValidFormattedNationalNumber(formattedNationalNumber, state)) {
return formattedNationalNumber;
}
} // Check that the formatted phone number contains exactly
// the same digits that have been input by the user.
// For example, when "0111523456789" is input for `AR` country,
// the extracted `this.nationalSignificantNumber` is "91123456789",
// which means that the national part of `this.digits` isn't simply equal to
// `this.nationalPrefix` + `this.nationalSignificantNumber`.
//
// Also, a `format` can add extra digits to the `this.nationalSignificantNumber`
// being formatted via `metadata[country].national_prefix_transform_rule`.
// For example, for `VI` country, it prepends `340` to the national number,
// and if this check hasn't been implemented, then there would be a bug
// when `340` "area coude" is "duplicated" during input for `VI` country:
// https://github.com/catamphetamine/libphonenumber-js/issues/318
//
// So, all these "gotchas" are filtered out.
//
// In the original Google's code, the comments say:
// "Check that we didn't remove nor add any extra digits when we matched
// this formatting pattern. This usually happens after we entered the last
// digit during AYTF. Eg: In case of MX, we swallow mobile token (1) when
// formatted but AYTF should retain all the number entered and not change
// in order to match a format (of same leading digits and length) display
// in that way."
// "If it's the same (i.e entered number and format is same), then it's
// safe to return this in formatted number as nothing is lost / added."
// Otherwise, don't use this format.
// https://github.com/google/libphonenumber/commit/3e7c1f04f5e7200f87fb131e6f85c6e99d60f510#diff-9149457fa9f5d608a11bb975c6ef4bc5
// https://github.com/google/libphonenumber/commit/3ac88c7106e7dcb553bcc794b15f19185928a1c6#diff-2dcb77e833422ee304da348b905cde0b
//
function isValidFormattedNationalNumber(formattedNationalNumber, state) {
return (0, _parseDigits["default"])(formattedNationalNumber) === state.getNationalDigits();
}
//# sourceMappingURL=AsYouTypeFormatter.complete.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,774 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "DIGIT_PLACEHOLDER", {
enumerable: true,
get: function get() {
return _AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER;
}
});
exports["default"] = void 0;
var _AsYouTypeFormatterUtil = require("./AsYouTypeFormatter.util.js");
var _AsYouTypeFormatterComplete = _interopRequireWildcard(require("./AsYouTypeFormatter.complete.js"));
var _AsYouTypeFormatterPatternMatcher = _interopRequireDefault(require("./AsYouTypeFormatter.PatternMatcher.js"));
var _parseDigits = _interopRequireDefault(require("./helpers/parseDigits.js"));
var _formatNationalNumberUsingFormat = require("./helpers/formatNationalNumberUsingFormat.js");
var _constants = require("./constants.js");
var _applyInternationalSeparatorStyle = _interopRequireDefault(require("./helpers/applyInternationalSeparatorStyle.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
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; }
// Used in phone number format template creation.
// Could be any digit, I guess.
var DUMMY_DIGIT = '9'; // 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 = (0, _AsYouTypeFormatterUtil.repeat)(DUMMY_DIGIT, LONGEST_NATIONAL_PHONE_NUMBER_LENGTH); // A set of characters that, if found in a national prefix formatting rules, are an indicator to
// us that we should separate the national prefix from the number when formatting.
var NATIONAL_PREFIX_SEPARATORS_PATTERN = /[- ]/; // Deprecated: Google has removed some formatting pattern related code from their repo.
// https://github.com/googlei18n/libphonenumber/commit/a395b4fef3caf57c4bc5f082e1152a4d2bd0ba4c
// "We no longer have numbers in formatting matching patterns, only \d."
// Because this library supports generating custom metadata
// some users may still be using old metadata so the relevant
// code seems to stay until some next major version update.
var SUPPORT_LEGACY_FORMATTING_PATTERNS = true; // A pattern that is used to match character classes in regular expressions.
// An example of a character class is "[1-4]".
var CREATE_CHARACTER_CLASS_PATTERN = SUPPORT_LEGACY_FORMATTING_PATTERNS && function () {
return /\[([^\[\]])*\]/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 CREATE_STANDALONE_DIGIT_PATTERN = SUPPORT_LEGACY_FORMATTING_PATTERNS && function () {
return /\d(?=[^,}][^,}])/g;
}; // A regular expression that is used to determine if a `format` is
// suitable to be used in the "as you type formatter".
// A `format` is suitable when the resulting formatted number has
// the same digits as the user has entered.
//
// In the simplest case, that would mean that the format
// doesn't add any additional digits when formatting a number.
// Google says that it also shouldn't add "star" (`*`) characters,
// like it does in some Israeli formats.
// Such basic format would only contain "valid punctuation"
// and "captured group" identifiers ($1, $2, etc).
//
// An example of a format that adds additional digits:
//
// Country: `AR` (Argentina).
// Format:
// {
// "pattern": "(\\d)(\\d{2})(\\d{4})(\\d{4})",
// "leading_digits_patterns": ["91"],
// "national_prefix_formatting_rule": "0$1",
// "format": "$2 15-$3-$4",
// "international_format": "$1 $2 $3-$4"
// }
//
// In the format above, the `format` adds `15` to the digits when formatting a number.
// A sidenote: this format actually is suitable because `national_prefix_for_parsing`
// has previously removed `15` from a national number, so re-adding `15` in `format`
// doesn't actually result in any extra digits added to user's input.
// But verifying that would be a complex procedure, so the code chooses a simpler path:
// it simply filters out all `format`s that contain anything but "captured group" ids.
//
// This regular expression is called `ELIGIBLE_FORMAT_PATTERN` in Google's
// `libphonenumber` code.
//
var NON_ALTERING_FORMAT_REG_EXP = new RegExp('[' + _constants.VALID_PUNCTUATION + ']*' + // Google developers say:
// "We require that the first matching group is present in the
// output pattern to ensure no data is lost while formatting."
'\\$1' + '[' + _constants.VALID_PUNCTUATION + ']*' + '(\\$\\d[' + _constants.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 AsYouTypeFormatter = /*#__PURE__*/function () {
function AsYouTypeFormatter(_ref) {
var state = _ref.state,
metadata = _ref.metadata;
_classCallCheck(this, AsYouTypeFormatter);
this.metadata = metadata;
this.resetFormat();
}
_createClass(AsYouTypeFormatter, [{
key: "resetFormat",
value: function resetFormat() {
this.chosenFormat = undefined;
this.template = undefined;
this.nationalNumberTemplate = undefined;
this.populatedNationalNumberTemplate = undefined;
this.populatedNationalNumberTemplatePosition = -1;
}
}, {
key: "reset",
value: function reset(numberingPlan, state) {
this.resetFormat();
if (numberingPlan) {
this.isNANP = numberingPlan.callingCode() === '1';
this.matchingFormats = numberingPlan.formats();
if (state.nationalSignificantNumber) {
this.narrowDownMatchingFormats(state);
}
} else {
this.isNANP = undefined;
this.matchingFormats = [];
}
}
/**
* Formats an updated phone number.
* @param {string} nextDigits — Additional phone number digits.
* @param {object} state — `AsYouType` state.
* @return {[string]} Returns undefined if the updated phone number can't be formatted using any of the available formats.
*/
}, {
key: "format",
value: function format(nextDigits, state) {
var _this = this;
// See if the phone number digits can be formatted as a complete phone number.
// If not, use the results from `formatNationalNumberWithNextDigits()`,
// which formats based on the chosen formatting pattern.
//
// Attempting to format complete phone number first is how it's done
// in Google's `libphonenumber`, so this library just follows it.
// Google's `libphonenumber` code doesn't explain in detail why does it
// attempt to format digits as a complete phone number
// instead of just going with a previoulsy (or newly) chosen `format`:
//
// "Checks 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."
//
if ((0, _AsYouTypeFormatterComplete.canFormatCompleteNumber)(state.nationalSignificantNumber, this.metadata)) {
for (var _iterator = _createForOfIteratorHelperLoose(this.matchingFormats), _step; !(_step = _iterator()).done;) {
var format = _step.value;
var formattedCompleteNumber = (0, _AsYouTypeFormatterComplete["default"])(state, format, {
metadata: this.metadata,
shouldTryNationalPrefixFormattingRule: function shouldTryNationalPrefixFormattingRule(format) {
return _this.shouldTryNationalPrefixFormattingRule(format, {
international: state.international,
nationalPrefix: state.nationalPrefix
});
},
getSeparatorAfterNationalPrefix: function getSeparatorAfterNationalPrefix(format) {
return _this.getSeparatorAfterNationalPrefix(format);
}
});
if (formattedCompleteNumber) {
this.resetFormat();
this.chosenFormat = format;
this.setNationalNumberTemplate(formattedCompleteNumber.replace(/\d/g, _AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER), state);
this.populatedNationalNumberTemplate = formattedCompleteNumber; // With a new formatting template, the matched position
// using the old template needs to be reset.
this.populatedNationalNumberTemplatePosition = this.template.lastIndexOf(_AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER);
return formattedCompleteNumber;
}
}
} // Format the digits as a partial (incomplete) phone number
// using the previously chosen formatting pattern (or a newly chosen one).
return this.formatNationalNumberWithNextDigits(nextDigits, state);
} // Formats the next phone number digits.
}, {
key: "formatNationalNumberWithNextDigits",
value: function formatNationalNumberWithNextDigits(nextDigits, state) {
var previouslyChosenFormat = this.chosenFormat; // Choose a format from the list of matching ones.
var newlyChosenFormat = this.chooseFormat(state);
if (newlyChosenFormat) {
if (newlyChosenFormat === previouslyChosenFormat) {
// If it can format the next (current) digits
// using the previously chosen phone number format
// then return the updated formatted number.
return this.formatNextNationalNumberDigits(nextDigits);
} else {
// If a more appropriate phone number format
// has been chosen for these "leading digits",
// then re-format the national phone number part
// using the newly selected format.
return this.formatNextNationalNumberDigits(state.getNationalDigits());
}
}
}
}, {
key: "narrowDownMatchingFormats",
value: function narrowDownMatchingFormats(_ref2) {
var _this2 = this;
var nationalSignificantNumber = _ref2.nationalSignificantNumber,
nationalPrefix = _ref2.nationalPrefix,
international = _ref2.international;
var leadingDigits = nationalSignificantNumber; // "leading digits" pattern list starts with a
// "leading digits" pattern fitting a maximum of 3 leading digits.
// So, after a user inputs 3 digits of a national (significant) phone number
// this national (significant) number can already be formatted.
// The next "leading digits" pattern is for 4 leading digits max,
// and the "leading digits" pattern after it is for 5 leading digits max, etc.
// This implementation is different from Google's
// in that it searches for a fitting format
// even if the user has entered less than
// `MIN_LEADING_DIGITS_LENGTH` digits of a national number.
// Because some leading digit patterns already match for a single first digit.
var leadingDigitsPatternIndex = leadingDigits.length - MIN_LEADING_DIGITS_LENGTH;
if (leadingDigitsPatternIndex < 0) {
leadingDigitsPatternIndex = 0;
}
this.matchingFormats = this.matchingFormats.filter(function (format) {
return _this2.formatSuits(format, international, nationalPrefix) && _this2.formatMatches(format, leadingDigits, leadingDigitsPatternIndex);
}); // If there was a phone number format chosen
// and it no longer holds given the new leading digits then reset it.
// The test for this `if` condition is marked as:
// "Reset a chosen format when it no longer holds given the new leading digits".
// To construct a valid test case for this one can find a country
// in `PhoneNumberMetadata.xml` yielding one format for 3 `<leadingDigits>`
// and yielding another format for 4 `<leadingDigits>` (Australia in this case).
if (this.chosenFormat && this.matchingFormats.indexOf(this.chosenFormat) === -1) {
this.resetFormat();
}
}
}, {
key: "formatSuits",
value: function formatSuits(format, international, nationalPrefix) {
// When a prefix before a national (significant) number is
// simply a national prefix, then it's parsed as `this.nationalPrefix`.
// In more complex cases, a prefix before national (significant) number
// could include a national prefix as well as some "capturing groups",
// and in that case there's no info whether a national prefix has been parsed.
// If national prefix is not used when formatting a phone number
// using this format, but a national prefix has been entered by the user,
// and was extracted, then discard such phone number format.
// In Google's "AsYouType" formatter code, the equivalent would be this part:
// https://github.com/google/libphonenumber/blob/0a45cfd96e71cad8edb0e162a70fcc8bd9728933/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java#L175-L184
if (nationalPrefix && !format.usesNationalPrefix() && // !format.domesticCarrierCodeFormattingRule() &&
!format.nationalPrefixIsOptionalWhenFormattingInNationalFormat()) {
return false;
} // If national prefix is mandatory for this phone number format
// and there're no guarantees that a national prefix is present in user input
// then discard this phone number format as not suitable.
// In Google's "AsYouType" formatter code, the equivalent would be this part:
// https://github.com/google/libphonenumber/blob/0a45cfd96e71cad8edb0e162a70fcc8bd9728933/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java#L185-L193
if (!international && !nationalPrefix && format.nationalPrefixIsMandatoryWhenFormattingInNationalFormat()) {
return false;
}
return true;
}
}, {
key: "formatMatches",
value: function formatMatches(format, leadingDigits, leadingDigitsPatternIndex) {
var leadingDigitsPatternsCount = format.leadingDigitsPatterns().length; // If this format is not restricted to a certain
// leading digits pattern then it fits.
// The test case could be found by searching for "leadingDigitsPatternsCount === 0".
if (leadingDigitsPatternsCount === 0) {
return true;
} // Start narrowing down the list of possible formats based on the leading digits.
// (only previously matched formats take part in the narrowing down process)
// `leading_digits_patterns` start with 3 digits min
// and then go up from there one digit at a time.
leadingDigitsPatternIndex = Math.min(leadingDigitsPatternIndex, leadingDigitsPatternsCount - 1);
var leadingDigitsPattern = format.leadingDigitsPatterns()[leadingDigitsPatternIndex]; // Google imposes a requirement on the leading digits
// to be minimum 3 digits long in order to be eligible
// for checking those with a leading digits pattern.
//
// Since `leading_digits_patterns` start with 3 digits min,
// Google's original `libphonenumber` library only starts
// excluding any non-matching formats only when the
// national number entered so far is at least 3 digits long,
// otherwise format matching would give false negatives.
//
// For example, when the digits entered so far are `2`
// and the leading digits pattern is `21`
// it's quite obvious in this case that the format could be the one
// but due to the absence of further digits it would give false negative.
//
// Also, `leading_digits_patterns` doesn't always correspond to a single
// digits count. For example, `60|8` pattern would already match `8`
// but the `60` part would require having at least two leading digits,
// so the whole pattern would require inputting two digits first in order to
// decide on whether it matches the input, even when the input is "80".
//
// This library — `libphonenumber-js` — allows filtering by `leading_digits_patterns`
// even when there's only 1 or 2 digits of the national (significant) number.
// To do that, it uses a non-strict pattern matcher written specifically for that.
//
if (leadingDigits.length < MIN_LEADING_DIGITS_LENGTH) {
// Before leading digits < 3 matching was implemented:
// return true
//
// After leading digits < 3 matching was implemented:
try {
return new _AsYouTypeFormatterPatternMatcher["default"](leadingDigitsPattern).match(leadingDigits, {
allowOverflow: true
}) !== undefined;
} catch (error)
/* istanbul ignore next */
{
// There's a slight possibility that there could be some undiscovered bug
// in the pattern matcher code. Since the "leading digits < 3 matching"
// feature is not "essential" for operation, it can fall back to the old way
// in case of any issues rather than halting the application's execution.
console.error(error);
return true;
}
} // If at least `MIN_LEADING_DIGITS_LENGTH` digits of a national number are
// available then use the usual regular expression matching.
//
// The whole pattern is wrapped in round brackets (`()`) because
// the pattern can use "or" operator (`|`) at the top level of the pattern.
//
return new RegExp("^(".concat(leadingDigitsPattern, ")")).test(leadingDigits);
}
}, {
key: "getFormatFormat",
value: function getFormatFormat(format, international) {
return international ? format.internationalFormat() : format.format();
}
}, {
key: "chooseFormat",
value: function chooseFormat(state) {
var _this3 = this;
var _loop = function _loop() {
var format = _step2.value;
// If this format is currently being used
// and is still suitable, then stick to it.
if (_this3.chosenFormat === format) {
return "break";
} // Sometimes, a formatting rule inserts additional digits in a phone number,
// and "as you type" formatter can't do that: it should only use the digits
// that the user has input.
//
// For example, in Argentina, there's a format for mobile phone numbers:
//
// {
// "pattern": "(\\d)(\\d{2})(\\d{4})(\\d{4})",
// "leading_digits_patterns": ["91"],
// "national_prefix_formatting_rule": "0$1",
// "format": "$2 15-$3-$4",
// "international_format": "$1 $2 $3-$4"
// }
//
// In that format, `international_format` is used instead of `format`
// because `format` inserts `15` in the formatted number,
// and `AsYouType` formatter should only use the digits
// the user has actually input, without adding any extra digits.
// In this case, it wouldn't make a difference, because the `15`
// is first stripped when applying `national_prefix_for_parsing`
// and then re-added when using `format`, so in reality it doesn't
// add any new digits to the number, but to detect that, the code
// would have to be more complex: it would have to try formatting
// the digits using the format and then see if any digits have
// actually been added or removed, and then, every time a new digit
// is input, it should re-check whether the chosen format doesn't
// alter the digits.
//
// Google's code doesn't go that far, and so does this library:
// it simply requires that a `format` doesn't add any additonal
// digits to user's input.
//
// Also, people in general should move from inputting phone numbers
// in national format (possibly with national prefixes)
// and use international phone number format instead:
// it's a logical thing in the modern age of mobile phones,
// globalization and the internet.
//
/* istanbul ignore if */
if (!NON_ALTERING_FORMAT_REG_EXP.test(_this3.getFormatFormat(format, state.international))) {
return "continue";
}
if (!_this3.createTemplateForFormat(format, state)) {
// Remove the format if it can't generate a template.
_this3.matchingFormats = _this3.matchingFormats.filter(function (_) {
return _ !== format;
});
return "continue";
}
_this3.chosenFormat = format;
return "break";
};
// When there are multiple available formats, the formatter uses the first
// format where a formatting template could be created.
//
// For some weird reason, `istanbul` says "else path not taken"
// for the `for of` line below. Supposedly that means that
// the loop doesn't ever go over the last element in the list.
// That's true because there always is `this.chosenFormat`
// when `this.matchingFormats` is non-empty.
// And, for some weird reason, it doesn't think that the case
// with empty `this.matchingFormats` qualifies for a valid "else" path.
// So simply muting this `istanbul` warning.
// It doesn't skip the contents of the `for of` loop,
// it just skips the `for of` line.
//
/* istanbul ignore next */
for (var _iterator2 = _createForOfIteratorHelperLoose(this.matchingFormats.slice()), _step2; !(_step2 = _iterator2()).done;) {
var _ret = _loop();
if (_ret === "break") break;
if (_ret === "continue") continue;
}
if (!this.chosenFormat) {
// No format matches the national (significant) phone number.
this.resetFormat();
}
return this.chosenFormat;
}
}, {
key: "createTemplateForFormat",
value: function createTemplateForFormat(format, state) {
// 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 (SUPPORT_LEGACY_FORMATTING_PATTERNS && format.pattern().indexOf('|') >= 0) {
return;
} // Get formatting template for this phone number format
var template = this.getTemplateForFormat(format, state); // If the national number entered is too long
// for any phone number format, then abort.
if (template) {
this.setNationalNumberTemplate(template, state);
return true;
}
}
}, {
key: "getSeparatorAfterNationalPrefix",
value: function getSeparatorAfterNationalPrefix(format) {
// `US` metadata doesn't have a `national_prefix_formatting_rule`,
// so the `if` condition below doesn't apply to `US`,
// but in reality there shoudl be a separator
// between a national prefix and a national (significant) number.
// So `US` national prefix separator is a "special" "hardcoded" case.
if (this.isNANP) {
return ' ';
} // If a `format` has a `national_prefix_formatting_rule`
// and that rule has a separator after a national prefix,
// then it means that there should be a separator
// between a national prefix and a national (significant) number.
if (format && format.nationalPrefixFormattingRule() && NATIONAL_PREFIX_SEPARATORS_PATTERN.test(format.nationalPrefixFormattingRule())) {
return ' ';
} // At this point, there seems to be no clear evidence that
// there should be a separator between a national prefix
// and a national (significant) number. So don't insert one.
return '';
}
}, {
key: "getInternationalPrefixBeforeCountryCallingCode",
value: function getInternationalPrefixBeforeCountryCallingCode(_ref3, options) {
var IDDPrefix = _ref3.IDDPrefix,
missingPlus = _ref3.missingPlus;
if (IDDPrefix) {
return options && options.spacing === false ? IDDPrefix : IDDPrefix + ' ';
}
if (missingPlus) {
return '';
}
return '+';
}
}, {
key: "getTemplate",
value: function getTemplate(state) {
if (!this.template) {
return;
} // `this.template` holds the template for a "complete" phone number.
// The currently entered phone number is most likely not "complete",
// so trim all non-populated digits.
var index = -1;
var i = 0;
var internationalPrefix = state.international ? this.getInternationalPrefixBeforeCountryCallingCode(state, {
spacing: false
}) : '';
while (i < internationalPrefix.length + state.getDigitsWithoutInternationalPrefix().length) {
index = this.template.indexOf(_AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER, index + 1);
i++;
}
return (0, _AsYouTypeFormatterUtil.cutAndStripNonPairedParens)(this.template, index + 1);
}
}, {
key: "setNationalNumberTemplate",
value: function setNationalNumberTemplate(template, state) {
this.nationalNumberTemplate = template;
this.populatedNationalNumberTemplate = template; // With a new formatting template, the matched position
// using the old template needs to be reset.
this.populatedNationalNumberTemplatePosition = -1; // For convenience, the public `.template` property
// contains the whole international number
// if the phone number being input is international:
// 'x' for the '+' sign, 'x'es for the country phone code,
// a spacebar and then the template for the formatted national number.
if (state.international) {
this.template = this.getInternationalPrefixBeforeCountryCallingCode(state).replace(/[\d\+]/g, _AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER) + (0, _AsYouTypeFormatterUtil.repeat)(_AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER, state.callingCode.length) + ' ' + template;
} else {
this.template = template;
}
}
/**
* Generates formatting template for a national phone number,
* optionally containing a national prefix, for a format.
* @param {Format} format
* @param {string} nationalPrefix
* @return {string}
*/
}, {
key: "getTemplateForFormat",
value: function getTemplateForFormat(format, _ref4) {
var nationalSignificantNumber = _ref4.nationalSignificantNumber,
international = _ref4.international,
nationalPrefix = _ref4.nationalPrefix,
complexPrefixBeforeNationalSignificantNumber = _ref4.complexPrefixBeforeNationalSignificantNumber;
var pattern = format.pattern();
/* istanbul ignore else */
if (SUPPORT_LEGACY_FORMATTING_PATTERNS) {
pattern = pattern // Replace anything in the form of [..] with \d
.replace(CREATE_CHARACTER_CLASS_PATTERN(), '\\d') // Replace any standalone digit (not the one in `{}`) with \d
.replace(CREATE_STANDALONE_DIGIT_PATTERN(), '\\d');
} // Generate a dummy national number (consisting of `9`s)
// that fits this format's `pattern`.
//
// This match will always succeed,
// because the "longest dummy phone number"
// has enough length to accomodate any possible
// national phone number format pattern.
//
var digits = LONGEST_DUMMY_PHONE_NUMBER.match(pattern)[0]; // If the national number entered is too long
// for any phone number format, then abort.
if (nationalSignificantNumber.length > digits.length) {
return;
} // Get a formatting template which can be used to efficiently format
// a partial number where digits are added one by one.
// Below `strictPattern` is used for the
// regular expression (with `^` and `$`).
// This wasn't originally in Google's `libphonenumber`
// and I guess they don't really need it
// because they're not using "templates" to format phone numbers
// but I added `strictPattern` after encountering
// South Korean phone number formatting bug.
//
// Non-strict regular expression bug demonstration:
//
// this.nationalSignificantNumber : `111111111` (9 digits)
//
// pattern : (\d{2})(\d{3,4})(\d{4})
// format : `$1 $2 $3`
// digits : `9999999999` (10 digits)
//
// '9999999999'.replace(new RegExp(/(\d{2})(\d{3,4})(\d{4})/g), '$1 $2 $3') = "99 9999 9999"
//
// template : xx xxxx xxxx
//
// But the correct template in this case is `xx xxx xxxx`.
// The template was generated incorrectly because of the
// `{3,4}` variability in the `pattern`.
//
// The fix is, if `this.nationalSignificantNumber` has already sufficient length
// to satisfy the `pattern` completely then `this.nationalSignificantNumber`
// is used instead of `digits`.
var strictPattern = new RegExp('^' + pattern + '$');
var nationalNumberDummyDigits = nationalSignificantNumber.replace(/\d/g, DUMMY_DIGIT); // If `this.nationalSignificantNumber` has already sufficient length
// to satisfy the `pattern` completely then use it
// instead of `digits`.
if (strictPattern.test(nationalNumberDummyDigits)) {
digits = nationalNumberDummyDigits;
}
var numberFormat = this.getFormatFormat(format, international);
var nationalPrefixIncludedInTemplate; // If a user did input a national prefix (and that's guaranteed),
// and if a `format` does have a national prefix formatting rule,
// then see if that national prefix formatting rule
// prepends exactly the same national prefix the user has input.
// If that's the case, then use the `format` with the national prefix formatting rule.
// Otherwise, use the `format` without the national prefix formatting rule,
// and prepend a national prefix manually to it.
if (this.shouldTryNationalPrefixFormattingRule(format, {
international: international,
nationalPrefix: nationalPrefix
})) {
var numberFormatWithNationalPrefix = numberFormat.replace(_formatNationalNumberUsingFormat.FIRST_GROUP_PATTERN, format.nationalPrefixFormattingRule()); // If `national_prefix_formatting_rule` of a `format` simply prepends
// national prefix at the start of a national (significant) number,
// then such formatting can be used with `AsYouType` formatter.
// There seems to be no `else` case: everywhere in metadata,
// national prefix formatting rule is national prefix + $1,
// or `($1)`, in which case such format isn't even considered
// when the user has input a national prefix.
/* istanbul ignore else */
if ((0, _parseDigits["default"])(format.nationalPrefixFormattingRule()) === (nationalPrefix || '') + (0, _parseDigits["default"])('$1')) {
numberFormat = numberFormatWithNationalPrefix;
nationalPrefixIncludedInTemplate = true; // Replace all digits of the national prefix in the formatting template
// with `DIGIT_PLACEHOLDER`s.
if (nationalPrefix) {
var i = nationalPrefix.length;
while (i > 0) {
numberFormat = numberFormat.replace(/\d/, _AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER);
i--;
}
}
}
} // Generate formatting template for this phone number format.
var template = digits // Format the dummy phone number according to the format.
.replace(new RegExp(pattern), numberFormat) // Replace each dummy digit with a DIGIT_PLACEHOLDER.
.replace(new RegExp(DUMMY_DIGIT, 'g'), _AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER); // If a prefix of a national (significant) number is not as simple
// as just a basic national prefix, then just prepend such prefix
// before the national (significant) number, optionally spacing
// the two with a whitespace.
if (!nationalPrefixIncludedInTemplate) {
if (complexPrefixBeforeNationalSignificantNumber) {
// Prepend the prefix to the template manually.
template = (0, _AsYouTypeFormatterUtil.repeat)(_AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER, complexPrefixBeforeNationalSignificantNumber.length) + ' ' + template;
} else if (nationalPrefix) {
// Prepend national prefix to the template manually.
template = (0, _AsYouTypeFormatterUtil.repeat)(_AsYouTypeFormatterUtil.DIGIT_PLACEHOLDER, nationalPrefix.length) + this.getSeparatorAfterNationalPrefix(format) + template;
}
}
if (international) {
template = (0, _applyInternationalSeparatorStyle["default"])(template);
}
return template;
}
}, {
key: "formatNextNationalNumberDigits",
value: function formatNextNationalNumberDigits(digits) {
var result = (0, _AsYouTypeFormatterUtil.populateTemplateWithDigits)(this.populatedNationalNumberTemplate, this.populatedNationalNumberTemplatePosition, digits);
if (!result) {
// Reset the format.
this.resetFormat();
return;
}
this.populatedNationalNumberTemplate = result[0];
this.populatedNationalNumberTemplatePosition = result[1]; // Return the formatted phone number so far.
return (0, _AsYouTypeFormatterUtil.cutAndStripNonPairedParens)(this.populatedNationalNumberTemplate, this.populatedNationalNumberTemplatePosition + 1); // The old way which was good for `input-format` but is not so good
// for `react-phone-number-input`'s default input (`InputBasic`).
// return closeNonPairedParens(this.populatedNationalNumberTemplate, this.populatedNationalNumberTemplatePosition + 1)
// .replace(new RegExp(DIGIT_PLACEHOLDER, 'g'), ' ')
}
}, {
key: "shouldTryNationalPrefixFormattingRule",
value: function shouldTryNationalPrefixFormattingRule(format, _ref5) {
var international = _ref5.international,
nationalPrefix = _ref5.nationalPrefix;
if (format.nationalPrefixFormattingRule()) {
// In some countries, `national_prefix_formatting_rule` is `($1)`,
// so it applies even if the user hasn't input a national prefix.
// `format.usesNationalPrefix()` detects such cases.
var usesNationalPrefix = format.usesNationalPrefix();
if (usesNationalPrefix && nationalPrefix || !usesNationalPrefix && !international) {
return true;
}
}
}
}]);
return AsYouTypeFormatter;
}();
exports["default"] = AsYouTypeFormatter;
//# sourceMappingURL=AsYouTypeFormatter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,141 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DIGIT_PLACEHOLDER = void 0;
exports.closeNonPairedParens = closeNonPairedParens;
exports.countOccurences = countOccurences;
exports.cutAndStripNonPairedParens = cutAndStripNonPairedParens;
exports.populateTemplateWithDigits = populateTemplateWithDigits;
exports.repeat = repeat;
exports.stripNonPairedParens = stripNonPairedParens;
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
// Should be the same as `DIGIT_PLACEHOLDER` in `libphonenumber-metadata-generator`.
var DIGIT_PLACEHOLDER = 'x'; // '\u2008' (punctuation space)
exports.DIGIT_PLACEHOLDER = DIGIT_PLACEHOLDER;
var DIGIT_PLACEHOLDER_MATCHER = new RegExp(DIGIT_PLACEHOLDER); // Counts all occurences of a symbol in a string.
// Unicode-unsafe (because using `.split()`).
function countOccurences(symbol, string) {
var count = 0; // Using `.split('')` to iterate through a string here
// to avoid requiring `Symbol.iterator` polyfill.
// `.split('')` is generally not safe for Unicode,
// but in this particular case for counting brackets it is safe.
// for (const character of string)
for (var _iterator = _createForOfIteratorHelperLoose(string.split('')), _step; !(_step = _iterator()).done;) {
var character = _step.value;
if (character === symbol) {
count++;
}
}
return count;
} // Repeats a string (or a symbol) N times.
// http://stackoverflow.com/questions/202605/repeat-string-javascript
function repeat(string, times) {
if (times < 1) {
return '';
}
var result = '';
while (times > 1) {
if (times & 1) {
result += string;
}
times >>= 1;
string += string;
}
return result + string;
}
function cutAndStripNonPairedParens(string, cutBeforeIndex) {
if (string[cutBeforeIndex] === ')') {
cutBeforeIndex++;
}
return stripNonPairedParens(string.slice(0, cutBeforeIndex));
}
function closeNonPairedParens(template, cut_before) {
var retained_template = template.slice(0, cut_before);
var opening_braces = countOccurences('(', retained_template);
var closing_braces = countOccurences(')', retained_template);
var dangling_braces = opening_braces - closing_braces;
while (dangling_braces > 0 && cut_before < template.length) {
if (template[cut_before] === ')') {
dangling_braces--;
}
cut_before++;
}
return template.slice(0, cut_before);
}
function stripNonPairedParens(string) {
var dangling_braces = [];
var i = 0;
while (i < string.length) {
if (string[i] === '(') {
dangling_braces.push(i);
} else if (string[i] === ')') {
dangling_braces.pop();
}
i++;
}
var start = 0;
var cleared_string = '';
dangling_braces.push(string.length);
for (var _i = 0, _dangling_braces = dangling_braces; _i < _dangling_braces.length; _i++) {
var index = _dangling_braces[_i];
cleared_string += string.slice(start, index);
start = index + 1;
}
return cleared_string;
}
function populateTemplateWithDigits(template, position, digits) {
// Using `.split('')` to iterate through a string here
// to avoid requiring `Symbol.iterator` polyfill.
// `.split('')` is generally not safe for Unicode,
// but in this particular case for `digits` it is safe.
// for (const digit of digits)
for (var _iterator2 = _createForOfIteratorHelperLoose(digits.split('')), _step2; !(_step2 = _iterator2()).done;) {
var digit = _step2.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 more digits are entered than the current format could handle.
if (template.slice(position + 1).search(DIGIT_PLACEHOLDER_MATCHER) < 0) {
return;
}
position = template.search(DIGIT_PLACEHOLDER_MATCHER);
template = template.replace(DIGIT_PLACEHOLDER_MATCHER, digit);
}
return [template, position];
}
//# sourceMappingURL=AsYouTypeFormatter.util.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
"use strict";
var _AsYouTypeFormatterUtil = require("./AsYouTypeFormatter.util.js");
describe('closeNonPairedParens', function () {
it('should close non-paired braces', function () {
(0, _AsYouTypeFormatterUtil.closeNonPairedParens)('(000) 123-45 (9 )', 15).should.equal('(000) 123-45 (9 )');
});
});
describe('stripNonPairedParens', function () {
it('should strip non-paired braces', function () {
(0, _AsYouTypeFormatterUtil.stripNonPairedParens)('(000) 123-45 (9').should.equal('(000) 123-45 9');
(0, _AsYouTypeFormatterUtil.stripNonPairedParens)('(000) 123-45 (9)').should.equal('(000) 123-45 (9)');
});
});
describe('repeat', function () {
it('should repeat string N times', function () {
(0, _AsYouTypeFormatterUtil.repeat)('a', 0).should.equal('');
(0, _AsYouTypeFormatterUtil.repeat)('a', 3).should.equal('aaa');
(0, _AsYouTypeFormatterUtil.repeat)('a', 4).should.equal('aaaa');
});
});
//# sourceMappingURL=AsYouTypeFormatter.util.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AsYouTypeFormatter.util.test.js","names":["describe","it","closeNonPairedParens","should","equal","stripNonPairedParens","repeat"],"sources":["../source/AsYouTypeFormatter.util.test.js"],"sourcesContent":["import { closeNonPairedParens, stripNonPairedParens, repeat } from './AsYouTypeFormatter.util.js'\r\n\r\ndescribe('closeNonPairedParens', () => {\r\n\tit('should close non-paired braces', () => {\r\n\t\tcloseNonPairedParens('(000) 123-45 (9 )', 15).should.equal('(000) 123-45 (9 )')\r\n\t})\r\n})\r\n\r\ndescribe('stripNonPairedParens', () => {\r\n\tit('should strip non-paired braces', () => {\r\n\t\tstripNonPairedParens('(000) 123-45 (9').should.equal('(000) 123-45 9')\r\n\t\tstripNonPairedParens('(000) 123-45 (9)').should.equal('(000) 123-45 (9)')\r\n\t})\r\n})\r\n\r\ndescribe('repeat', () => {\r\n\tit('should repeat string N times', () => {\r\n\t\trepeat('a', 0).should.equal('')\r\n\t\trepeat('a', 3).should.equal('aaa')\r\n\t\trepeat('a', 4).should.equal('aaaa')\r\n\t})\r\n})"],"mappings":";;AAAA;;AAEAA,QAAQ,CAAC,sBAAD,EAAyB,YAAM;EACtCC,EAAE,CAAC,gCAAD,EAAmC,YAAM;IAC1C,IAAAC,4CAAA,EAAqB,oBAArB,EAA2C,EAA3C,EAA+CC,MAA/C,CAAsDC,KAAtD,CAA4D,oBAA5D;EACA,CAFC,CAAF;AAGA,CAJO,CAAR;AAMAJ,QAAQ,CAAC,sBAAD,EAAyB,YAAM;EACtCC,EAAE,CAAC,gCAAD,EAAmC,YAAM;IAC1C,IAAAI,4CAAA,EAAqB,iBAArB,EAAwCF,MAAxC,CAA+CC,KAA/C,CAAqD,gBAArD;IACA,IAAAC,4CAAA,EAAqB,kBAArB,EAAyCF,MAAzC,CAAgDC,KAAhD,CAAsD,kBAAtD;EACA,CAHC,CAAF;AAIA,CALO,CAAR;AAOAJ,QAAQ,CAAC,QAAD,EAAW,YAAM;EACxBC,EAAE,CAAC,8BAAD,EAAiC,YAAM;IACxC,IAAAK,8BAAA,EAAO,GAAP,EAAY,CAAZ,EAAeH,MAAf,CAAsBC,KAAtB,CAA4B,EAA5B;IACA,IAAAE,8BAAA,EAAO,GAAP,EAAY,CAAZ,EAAeH,MAAf,CAAsBC,KAAtB,CAA4B,KAA5B;IACA,IAAAE,8BAAA,EAAO,GAAP,EAAY,CAAZ,EAAeH,MAAf,CAAsBC,KAAtB,CAA4B,MAA5B;EACA,CAJC,CAAF;AAKA,CANO,CAAR"}

View File

@@ -0,0 +1,524 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
exports.extractFormattedDigitsAndPlus = extractFormattedDigitsAndPlus;
var _extractCountryCallingCode2 = _interopRequireDefault(require("./helpers/extractCountryCallingCode.js"));
var _extractCountryCallingCodeFromInternationalNumberWithoutPlusSign = _interopRequireDefault(require("./helpers/extractCountryCallingCodeFromInternationalNumberWithoutPlusSign.js"));
var _extractNationalNumberFromPossiblyIncompleteNumber = _interopRequireDefault(require("./helpers/extractNationalNumberFromPossiblyIncompleteNumber.js"));
var _stripIddPrefix = _interopRequireDefault(require("./helpers/stripIddPrefix.js"));
var _parseDigits = _interopRequireDefault(require("./helpers/parseDigits.js"));
var _constants = require("./constants.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
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; }
var VALID_FORMATTED_PHONE_NUMBER_DIGITS_PART = '[' + _constants.VALID_PUNCTUATION + _constants.VALID_DIGITS + ']+';
var VALID_FORMATTED_PHONE_NUMBER_DIGITS_PART_PATTERN = new RegExp('^' + VALID_FORMATTED_PHONE_NUMBER_DIGITS_PART + '$', 'i');
var VALID_FORMATTED_PHONE_NUMBER_PART = '(?:' + '[' + _constants.PLUS_CHARS + ']' + '[' + _constants.VALID_PUNCTUATION + _constants.VALID_DIGITS + ']*' + '|' + '[' + _constants.VALID_PUNCTUATION + _constants.VALID_DIGITS + ']+' + ')';
var AFTER_PHONE_NUMBER_DIGITS_END_PATTERN = new RegExp('[^' + _constants.VALID_PUNCTUATION + _constants.VALID_DIGITS + ']+' + '.*' + '$'); // Tests whether `national_prefix_for_parsing` could match
// different national prefixes.
// Matches anything that's not a digit or a square bracket.
var COMPLEX_NATIONAL_PREFIX = /[^\d\[\]]/;
var AsYouTypeParser = /*#__PURE__*/function () {
function AsYouTypeParser(_ref) {
var defaultCountry = _ref.defaultCountry,
defaultCallingCode = _ref.defaultCallingCode,
metadata = _ref.metadata,
onNationalSignificantNumberChange = _ref.onNationalSignificantNumberChange;
_classCallCheck(this, AsYouTypeParser);
this.defaultCountry = defaultCountry;
this.defaultCallingCode = defaultCallingCode;
this.metadata = metadata;
this.onNationalSignificantNumberChange = onNationalSignificantNumberChange;
}
_createClass(AsYouTypeParser, [{
key: "input",
value: function input(text, state) {
var _extractFormattedDigi = extractFormattedDigitsAndPlus(text),
_extractFormattedDigi2 = _slicedToArray(_extractFormattedDigi, 2),
formattedDigits = _extractFormattedDigi2[0],
hasPlus = _extractFormattedDigi2[1];
var digits = (0, _parseDigits["default"])(formattedDigits); // Checks for a special case: just a leading `+` has been entered.
var justLeadingPlus;
if (hasPlus) {
if (!state.digits) {
state.startInternationalNumber();
if (!digits) {
justLeadingPlus = true;
}
}
}
if (digits) {
this.inputDigits(digits, state);
}
return {
digits: digits,
justLeadingPlus: justLeadingPlus
};
}
/**
* Inputs "next" phone number digits.
* @param {string} digits
* @return {string} [formattedNumber] Formatted national phone number (if it can be formatted at this stage). Returning `undefined` means "don't format the national phone number at this stage".
*/
}, {
key: "inputDigits",
value: function inputDigits(nextDigits, state) {
var digits = state.digits;
var hasReceivedThreeLeadingDigits = digits.length < 3 && digits.length + nextDigits.length >= 3; // Append phone number digits.
state.appendDigits(nextDigits); // Attempt to extract IDD prefix:
// Some users input their phone number in international format,
// but in an "out-of-country" dialing format instead of using the leading `+`.
// https://github.com/catamphetamine/libphonenumber-js/issues/185
// Detect such numbers as soon as there're at least 3 digits.
// Google's library attempts to extract IDD prefix at 3 digits,
// so this library just copies that behavior.
// I guess that's because the most commot IDD prefixes are
// `00` (Europe) and `011` (US).
// There exist really long IDD prefixes too:
// for example, in Australia the default IDD prefix is `0011`,
// and it could even be as long as `14880011`.
// An IDD prefix is extracted here, and then every time when
// there's a new digit and the number couldn't be formatted.
if (hasReceivedThreeLeadingDigits) {
this.extractIddPrefix(state);
}
if (this.isWaitingForCountryCallingCode(state)) {
if (!this.extractCountryCallingCode(state)) {
return;
}
} else {
state.appendNationalSignificantNumberDigits(nextDigits);
} // If a phone number is being input in international format,
// then it's not valid for it to have a national prefix.
// Still, some people incorrectly input such numbers with a national prefix.
// In such cases, only attempt to strip a national prefix if the number becomes too long.
// (but that is done later, not here)
if (!state.international) {
if (!this.hasExtractedNationalSignificantNumber) {
this.extractNationalSignificantNumber(state.getNationalDigits(), function (stateUpdate) {
return state.update(stateUpdate);
});
}
}
}
}, {
key: "isWaitingForCountryCallingCode",
value: function isWaitingForCountryCallingCode(_ref2) {
var international = _ref2.international,
callingCode = _ref2.callingCode;
return international && !callingCode;
} // Extracts a country calling code from a number
// being entered in internatonal format.
}, {
key: "extractCountryCallingCode",
value: function extractCountryCallingCode(state) {
var _extractCountryCallin = (0, _extractCountryCallingCode2["default"])('+' + state.getDigitsWithoutInternationalPrefix(), this.defaultCountry, this.defaultCallingCode, this.metadata.metadata),
countryCallingCode = _extractCountryCallin.countryCallingCode,
number = _extractCountryCallin.number;
if (countryCallingCode) {
state.setCallingCode(countryCallingCode);
state.update({
nationalSignificantNumber: number
});
return true;
}
}
}, {
key: "reset",
value: function reset(numberingPlan) {
if (numberingPlan) {
this.hasSelectedNumberingPlan = true;
var nationalPrefixForParsing = numberingPlan._nationalPrefixForParsing();
this.couldPossiblyExtractAnotherNationalSignificantNumber = nationalPrefixForParsing && COMPLEX_NATIONAL_PREFIX.test(nationalPrefixForParsing);
} else {
this.hasSelectedNumberingPlan = undefined;
this.couldPossiblyExtractAnotherNationalSignificantNumber = undefined;
}
}
/**
* Extracts a national (significant) number from user input.
* Google's library is different in that it only applies `national_prefix_for_parsing`
* and doesn't apply `national_prefix_transform_rule` after that.
* https://github.com/google/libphonenumber/blob/a3d70b0487875475e6ad659af404943211d26456/java/libphonenumber/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java#L539
* @return {boolean} [extracted]
*/
}, {
key: "extractNationalSignificantNumber",
value: function extractNationalSignificantNumber(nationalDigits, setState) {
if (!this.hasSelectedNumberingPlan) {
return;
}
var _extractNationalNumbe = (0, _extractNationalNumberFromPossiblyIncompleteNumber["default"])(nationalDigits, this.metadata),
nationalPrefix = _extractNationalNumbe.nationalPrefix,
nationalNumber = _extractNationalNumbe.nationalNumber,
carrierCode = _extractNationalNumbe.carrierCode;
if (nationalNumber === nationalDigits) {
return;
}
this.onExtractedNationalNumber(nationalPrefix, carrierCode, nationalNumber, nationalDigits, setState);
return true;
}
/**
* In Google's code this function is called "attempt to extract longer NDD".
* "Some national prefixes are a substring of others", they say.
* @return {boolean} [result] — Returns `true` if extracting a national prefix produced different results from what they were.
*/
}, {
key: "extractAnotherNationalSignificantNumber",
value: function extractAnotherNationalSignificantNumber(nationalDigits, prevNationalSignificantNumber, setState) {
if (!this.hasExtractedNationalSignificantNumber) {
return this.extractNationalSignificantNumber(nationalDigits, setState);
}
if (!this.couldPossiblyExtractAnotherNationalSignificantNumber) {
return;
}
var _extractNationalNumbe2 = (0, _extractNationalNumberFromPossiblyIncompleteNumber["default"])(nationalDigits, this.metadata),
nationalPrefix = _extractNationalNumbe2.nationalPrefix,
nationalNumber = _extractNationalNumbe2.nationalNumber,
carrierCode = _extractNationalNumbe2.carrierCode; // If a national prefix has been extracted previously,
// then it's always extracted as additional digits are added.
// That's assuming `extractNationalNumberFromPossiblyIncompleteNumber()`
// doesn't do anything different from what it currently does.
// So, just in case, here's this check, though it doesn't occur.
/* istanbul ignore if */
if (nationalNumber === prevNationalSignificantNumber) {
return;
}
this.onExtractedNationalNumber(nationalPrefix, carrierCode, nationalNumber, nationalDigits, setState);
return true;
}
}, {
key: "onExtractedNationalNumber",
value: function onExtractedNationalNumber(nationalPrefix, carrierCode, nationalSignificantNumber, nationalDigits, setState) {
var complexPrefixBeforeNationalSignificantNumber;
var nationalSignificantNumberMatchesInput; // This check also works with empty `this.nationalSignificantNumber`.
var nationalSignificantNumberIndex = nationalDigits.lastIndexOf(nationalSignificantNumber); // If the extracted national (significant) number is the
// last substring of the `digits`, then it means that it hasn't been altered:
// no digits have been removed from the national (significant) number
// while applying `national_prefix_transform_rule`.
// https://gitlab.com/catamphetamine/libphonenumber-js/-/blob/master/METADATA.md#national_prefix_for_parsing--national_prefix_transform_rule
if (nationalSignificantNumberIndex >= 0 && nationalSignificantNumberIndex === nationalDigits.length - nationalSignificantNumber.length) {
nationalSignificantNumberMatchesInput = true; // If a prefix of a national (significant) number is not as simple
// as just a basic national prefix, then such prefix is stored in
// `this.complexPrefixBeforeNationalSignificantNumber` property and will be
// prepended "as is" to the national (significant) number to produce
// a formatted result.
var prefixBeforeNationalNumber = nationalDigits.slice(0, nationalSignificantNumberIndex); // `prefixBeforeNationalNumber` is always non-empty,
// because `onExtractedNationalNumber()` isn't called
// when a national (significant) number hasn't been actually "extracted":
// when a national (significant) number is equal to the national part of `digits`,
// then `onExtractedNationalNumber()` doesn't get called.
if (prefixBeforeNationalNumber !== nationalPrefix) {
complexPrefixBeforeNationalSignificantNumber = prefixBeforeNationalNumber;
}
}
setState({
nationalPrefix: nationalPrefix,
carrierCode: carrierCode,
nationalSignificantNumber: nationalSignificantNumber,
nationalSignificantNumberMatchesInput: nationalSignificantNumberMatchesInput,
complexPrefixBeforeNationalSignificantNumber: complexPrefixBeforeNationalSignificantNumber
}); // `onExtractedNationalNumber()` is only called when
// the national (significant) number actually did change.
this.hasExtractedNationalSignificantNumber = true;
this.onNationalSignificantNumberChange();
}
}, {
key: "reExtractNationalSignificantNumber",
value: function reExtractNationalSignificantNumber(state) {
// Attempt to extract a national prefix.
//
// Some people incorrectly input national prefix
// in an international phone number.
// For example, some people write British phone numbers as `+44(0)...`.
//
// Also, in some rare cases, it is valid for a national prefix
// to be a part of an international phone number.
// For example, mobile phone numbers in Mexico are supposed to be
// dialled internationally using a `1` national prefix,
// so the national prefix will be part of an international number.
//
// Quote from:
// https://www.mexperience.com/dialing-cell-phones-in-mexico/
//
// "Dialing a Mexican cell phone from abroad
// When you are calling a cell phone number in Mexico from outside Mexico,
// its necessary to dial an additional “1” after Mexicos country code
// (which is “52”) and before the area code.
// You also ignore the 045, and simply dial the area code and the
// cell phones number.
//
// If you dont add the “1”, youll receive a recorded announcement
// asking you to redial using it.
//
// For example, if you are calling from the USA to a cell phone
// in Mexico City, you would dial +52 1 55 1234 5678.
// (Note that this is different to calling a land line in Mexico City
// from abroad, where the number dialed would be +52 55 1234 5678)".
//
// Google's demo output:
// https://libphonenumber.appspot.com/phonenumberparser?number=%2b5215512345678&country=MX
//
if (this.extractAnotherNationalSignificantNumber(state.getNationalDigits(), state.nationalSignificantNumber, function (stateUpdate) {
return state.update(stateUpdate);
})) {
return true;
} // If no format matches the phone number, then it could be
// "a really long IDD" (quote from a comment in Google's library).
// An IDD prefix is first extracted when the user has entered at least 3 digits,
// and then here — every time when there's a new digit and the number
// couldn't be formatted.
// For example, in Australia the default IDD prefix is `0011`,
// and it could even be as long as `14880011`.
//
// Could also check `!hasReceivedThreeLeadingDigits` here
// to filter out the case when this check duplicates the one
// already performed when there're 3 leading digits,
// but it's not a big deal, and in most cases there
// will be a suitable `format` when there're 3 leading digits.
//
if (this.extractIddPrefix(state)) {
this.extractCallingCodeAndNationalSignificantNumber(state);
return true;
} // Google's AsYouType formatter supports sort of an "autocorrection" feature
// when it "autocorrects" numbers that have been input for a country
// with that country's calling code.
// Such "autocorrection" feature looks weird, but different people have been requesting it:
// https://github.com/catamphetamine/libphonenumber-js/issues/376
// https://github.com/catamphetamine/libphonenumber-js/issues/375
// https://github.com/catamphetamine/libphonenumber-js/issues/316
if (this.fixMissingPlus(state)) {
this.extractCallingCodeAndNationalSignificantNumber(state);
return true;
}
}
}, {
key: "extractIddPrefix",
value: function extractIddPrefix(state) {
// An IDD prefix can't be present in a number written with a `+`.
// Also, don't re-extract an IDD prefix if has already been extracted.
var international = state.international,
IDDPrefix = state.IDDPrefix,
digits = state.digits,
nationalSignificantNumber = state.nationalSignificantNumber;
if (international || IDDPrefix) {
return;
} // Some users input their phone number in "out-of-country"
// dialing format instead of using the leading `+`.
// https://github.com/catamphetamine/libphonenumber-js/issues/185
// Detect such numbers.
var numberWithoutIDD = (0, _stripIddPrefix["default"])(digits, this.defaultCountry, this.defaultCallingCode, this.metadata.metadata);
if (numberWithoutIDD !== undefined && numberWithoutIDD !== digits) {
// If an IDD prefix was stripped then convert the IDD-prefixed number
// to international number for subsequent parsing.
state.update({
IDDPrefix: digits.slice(0, digits.length - numberWithoutIDD.length)
});
this.startInternationalNumber(state, {
country: undefined,
callingCode: undefined
});
return true;
}
}
}, {
key: "fixMissingPlus",
value: function fixMissingPlus(state) {
if (!state.international) {
var _extractCountryCallin2 = (0, _extractCountryCallingCodeFromInternationalNumberWithoutPlusSign["default"])(state.digits, this.defaultCountry, this.defaultCallingCode, this.metadata.metadata),
newCallingCode = _extractCountryCallin2.countryCallingCode,
number = _extractCountryCallin2.number;
if (newCallingCode) {
state.update({
missingPlus: true
});
this.startInternationalNumber(state, {
country: state.country,
callingCode: newCallingCode
});
return true;
}
}
}
}, {
key: "startInternationalNumber",
value: function startInternationalNumber(state, _ref3) {
var country = _ref3.country,
callingCode = _ref3.callingCode;
state.startInternationalNumber(country, callingCode); // If a national (significant) number has been extracted before, reset it.
if (state.nationalSignificantNumber) {
state.resetNationalSignificantNumber();
this.onNationalSignificantNumberChange();
this.hasExtractedNationalSignificantNumber = undefined;
}
}
}, {
key: "extractCallingCodeAndNationalSignificantNumber",
value: function extractCallingCodeAndNationalSignificantNumber(state) {
if (this.extractCountryCallingCode(state)) {
// `this.extractCallingCode()` is currently called when the number
// couldn't be formatted during the standard procedure.
// Normally, the national prefix would be re-extracted
// for an international number if such number couldn't be formatted,
// but since it's already not able to be formatted,
// there won't be yet another retry, so also extract national prefix here.
this.extractNationalSignificantNumber(state.getNationalDigits(), function (stateUpdate) {
return state.update(stateUpdate);
});
}
}
}]);
return AsYouTypeParser;
}();
/**
* Extracts formatted phone number from text (if there's any).
* @param {string} text
* @return {string} [formattedPhoneNumber]
*/
exports["default"] = AsYouTypeParser;
function extractFormattedPhoneNumber(text) {
// Attempt to extract a possible number from the string passed in.
var startsAt = text.search(VALID_FORMATTED_PHONE_NUMBER_PART);
if (startsAt < 0) {
return;
} // Trim everything to the left of the phone number.
text = text.slice(startsAt); // Trim the `+`.
var hasPlus;
if (text[0] === '+') {
hasPlus = true;
text = text.slice('+'.length);
} // Trim everything to the right of the phone number.
text = text.replace(AFTER_PHONE_NUMBER_DIGITS_END_PATTERN, ''); // Re-add the previously trimmed `+`.
if (hasPlus) {
text = '+' + text;
}
return text;
}
/**
* Extracts formatted phone number digits (and a `+`) from text (if there're any).
* @param {string} text
* @return {any[]}
*/
function _extractFormattedDigitsAndPlus(text) {
// Extract a formatted phone number part from text.
var extractedNumber = extractFormattedPhoneNumber(text) || ''; // Trim a `+`.
if (extractedNumber[0] === '+') {
return [extractedNumber.slice('+'.length), true];
}
return [extractedNumber];
}
/**
* Extracts formatted phone number digits (and a `+`) from text (if there're any).
* @param {string} text
* @return {any[]}
*/
function extractFormattedDigitsAndPlus(text) {
var _extractFormattedDigi3 = _extractFormattedDigitsAndPlus(text),
_extractFormattedDigi4 = _slicedToArray(_extractFormattedDigi3, 2),
formattedDigits = _extractFormattedDigi4[0],
hasPlus = _extractFormattedDigi4[1]; // If the extracted phone number part
// can possibly be a part of some valid phone number
// then parse phone number characters from a formatted phone number.
if (!VALID_FORMATTED_PHONE_NUMBER_DIGITS_PART_PATTERN.test(formattedDigits)) {
formattedDigits = '';
}
return [formattedDigits, hasPlus];
}
//# sourceMappingURL=AsYouTypeParser.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,145 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
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; }
// This "state" object simply holds the state of the "AsYouType" parser:
//
// * `country?: string`
// * `callingCode?: string`
// * `digits: string`
// * `international: boolean`
// * `missingPlus: boolean`
// * `IDDPrefix?: string`
// * `carrierCode?: string`
// * `nationalPrefix?: string`
// * `nationalSignificantNumber?: string`
// * `nationalSignificantNumberMatchesInput: boolean`
// * `complexPrefixBeforeNationalSignificantNumber?: string`
//
// `state.country` and `state.callingCode` aren't required to be in sync.
// For example, `state.country` could be `"AR"` and `state.callingCode` could be `undefined`.
// So `state.country` and `state.callingCode` are totally independent.
//
var AsYouTypeState = /*#__PURE__*/function () {
function AsYouTypeState(_ref) {
var onCountryChange = _ref.onCountryChange,
onCallingCodeChange = _ref.onCallingCodeChange;
_classCallCheck(this, AsYouTypeState);
this.onCountryChange = onCountryChange;
this.onCallingCodeChange = onCallingCodeChange;
}
_createClass(AsYouTypeState, [{
key: "reset",
value: function reset(_ref2) {
var country = _ref2.country,
callingCode = _ref2.callingCode;
this.international = false;
this.missingPlus = false;
this.IDDPrefix = undefined;
this.callingCode = undefined;
this.digits = '';
this.resetNationalSignificantNumber();
this.initCountryAndCallingCode(country, callingCode);
}
}, {
key: "resetNationalSignificantNumber",
value: function resetNationalSignificantNumber() {
this.nationalSignificantNumber = this.getNationalDigits();
this.nationalSignificantNumberMatchesInput = true;
this.nationalPrefix = undefined;
this.carrierCode = undefined;
this.complexPrefixBeforeNationalSignificantNumber = undefined;
}
}, {
key: "update",
value: function update(properties) {
for (var _i = 0, _Object$keys = Object.keys(properties); _i < _Object$keys.length; _i++) {
var key = _Object$keys[_i];
this[key] = properties[key];
}
}
}, {
key: "initCountryAndCallingCode",
value: function initCountryAndCallingCode(country, callingCode) {
this.setCountry(country);
this.setCallingCode(callingCode);
}
}, {
key: "setCountry",
value: function setCountry(country) {
this.country = country;
this.onCountryChange(country);
}
}, {
key: "setCallingCode",
value: function setCallingCode(callingCode) {
this.callingCode = callingCode;
this.onCallingCodeChange(callingCode, this.country);
}
}, {
key: "startInternationalNumber",
value: function startInternationalNumber(country, callingCode) {
// Prepend the `+` to parsed input.
this.international = true; // If a default country was set then reset it
// because an explicitly international phone
// number is being entered.
this.initCountryAndCallingCode(country, callingCode);
}
}, {
key: "appendDigits",
value: function appendDigits(nextDigits) {
this.digits += nextDigits;
}
}, {
key: "appendNationalSignificantNumberDigits",
value: function appendNationalSignificantNumberDigits(nextDigits) {
this.nationalSignificantNumber += nextDigits;
}
/**
* Returns the part of `this.digits` that corresponds to the national number.
* Basically, all digits that have been input by the user, except for the
* international prefix and the country calling code part
* (if the number is an international one).
* @return {string}
*/
}, {
key: "getNationalDigits",
value: function getNationalDigits() {
if (this.international) {
return this.digits.slice((this.IDDPrefix ? this.IDDPrefix.length : 0) + (this.callingCode ? this.callingCode.length : 0));
}
return this.digits;
}
}, {
key: "getDigitsWithoutInternationalPrefix",
value: function getDigitsWithoutInternationalPrefix() {
if (this.international) {
if (this.IDDPrefix) {
return this.digits.slice(this.IDDPrefix.length);
}
}
return this.digits;
}
}]);
return AsYouTypeState;
}();
exports["default"] = AsYouTypeState;
//# sourceMappingURL=AsYouTypeState.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,63 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
// https://stackoverflow.com/a/46971044/970769
// "Breaking changes in Typescript 2.1"
// "Extending built-ins like Error, Array, and Map may no longer work."
// "As a recommendation, you can manually adjust the prototype immediately after any super(...) calls."
// https://github.com/Microsoft/TypeScript-wiki/blob/main/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
var ParseError = /*#__PURE__*/function (_Error) {
_inherits(ParseError, _Error);
var _super = _createSuper(ParseError);
function ParseError(code) {
var _this;
_classCallCheck(this, ParseError);
_this = _super.call(this, code); // Set the prototype explicitly.
// Any subclass of FooError will have to manually set the prototype as well.
Object.setPrototypeOf(_assertThisInitialized(_this), ParseError.prototype);
_this.name = _this.constructor.name;
return _this;
}
return _createClass(ParseError);
}( /*#__PURE__*/_wrapNativeSuper(Error));
exports["default"] = ParseError;
//# sourceMappingURL=ParseError.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ParseError.js","names":["ParseError","code","Object","setPrototypeOf","prototype","name","constructor","Error"],"sources":["../source/ParseError.js"],"sourcesContent":["// https://stackoverflow.com/a/46971044/970769\r\n// \"Breaking changes in Typescript 2.1\"\r\n// \"Extending built-ins like Error, Array, and Map may no longer work.\"\r\n// \"As a recommendation, you can manually adjust the prototype immediately after any super(...) calls.\"\r\n// https://github.com/Microsoft/TypeScript-wiki/blob/main/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\r\nexport default class ParseError extends Error {\r\n constructor(code) {\r\n super(code)\r\n // Set the prototype explicitly.\r\n // Any subclass of FooError will have to manually set the prototype as well.\r\n Object.setPrototypeOf(this, ParseError.prototype)\r\n this.name = this.constructor.name\r\n }\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;IACqBA,U;;;;;EACnB,oBAAYC,IAAZ,EAAkB;IAAA;;IAAA;;IAChB,0BAAMA,IAAN,EADgB,CAEhB;IACA;;IACAC,MAAM,CAACC,cAAP,gCAA4BH,UAAU,CAACI,SAAvC;IACA,MAAKC,IAAL,GAAY,MAAKC,WAAL,CAAiBD,IAA7B;IALgB;EAMjB;;;iCAPqCE,K"}

View File

@@ -0,0 +1,244 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _metadata = _interopRequireWildcard(require("./metadata.js"));
var _isPossible = _interopRequireDefault(require("./isPossible.js"));
var _isValid = _interopRequireDefault(require("./isValid.js"));
var _getNumberType = _interopRequireDefault(require("./helpers/getNumberType.js"));
var _getPossibleCountriesForNumber = _interopRequireDefault(require("./helpers/getPossibleCountriesForNumber.js"));
var _extractCountryCallingCode = _interopRequireDefault(require("./helpers/extractCountryCallingCode.js"));
var _isObject = _interopRequireDefault(require("./helpers/isObject.js"));
var _format2 = _interopRequireDefault(require("./format.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
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; }
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; }
var USE_NON_GEOGRAPHIC_COUNTRY_CODE = false;
var PhoneNumber = /*#__PURE__*/function () {
/**
* @param {string} countryOrCountryCallingCode
* @param {string} nationalNumber
* @param {object} metadata — Metadata JSON
* @return {PhoneNumber}
*/
function PhoneNumber(countryOrCountryCallingCode, nationalNumber, metadata) {
_classCallCheck(this, PhoneNumber);
// Validate `countryOrCountryCallingCode` argument.
if (!countryOrCountryCallingCode) {
throw new TypeError('First argument is required');
}
if (typeof countryOrCountryCallingCode !== 'string') {
throw new TypeError('First argument must be a string');
} // In case of public API use: `constructor(number, metadata)`.
// Transform the arguments from `constructor(number, metadata)` to
// `constructor(countryOrCountryCallingCode, nationalNumber, metadata)`.
if (countryOrCountryCallingCode[0] === '+' && !nationalNumber) {
throw new TypeError('`metadata` argument not passed');
}
if ((0, _isObject["default"])(nationalNumber) && (0, _isObject["default"])(nationalNumber.countries)) {
metadata = nationalNumber;
var e164Number = countryOrCountryCallingCode;
if (!E164_NUMBER_REGEXP.test(e164Number)) {
throw new Error('Invalid `number` argument passed: must consist of a "+" followed by digits');
}
var _extractCountryCallin = (0, _extractCountryCallingCode["default"])(e164Number, undefined, undefined, metadata),
_countryCallingCode = _extractCountryCallin.countryCallingCode,
number = _extractCountryCallin.number;
nationalNumber = number;
countryOrCountryCallingCode = _countryCallingCode;
if (!nationalNumber) {
throw new Error('Invalid `number` argument passed: too short');
}
} // Validate `nationalNumber` argument.
if (!nationalNumber) {
throw new TypeError('`nationalNumber` argument is required');
}
if (typeof nationalNumber !== 'string') {
throw new TypeError('`nationalNumber` argument must be a string');
} // Validate `metadata` argument.
(0, _metadata.validateMetadata)(metadata); // Initialize properties.
var _getCountryAndCountry = getCountryAndCountryCallingCode(countryOrCountryCallingCode, metadata),
country = _getCountryAndCountry.country,
countryCallingCode = _getCountryAndCountry.countryCallingCode;
this.country = country;
this.countryCallingCode = countryCallingCode;
this.nationalNumber = nationalNumber;
this.number = '+' + this.countryCallingCode + this.nationalNumber; // Exclude `metadata` property output from `PhoneNumber.toString()`
// so that it doesn't clutter the console output of Node.js.
// Previously, when Node.js did `console.log(new PhoneNumber(...))`,
// it would output the whole internal structure of the `metadata` object.
this.getMetadata = function () {
return metadata;
};
}
_createClass(PhoneNumber, [{
key: "setExt",
value: function setExt(ext) {
this.ext = ext;
}
}, {
key: "getPossibleCountries",
value: function getPossibleCountries() {
if (this.country) {
return [this.country];
}
return (0, _getPossibleCountriesForNumber["default"])(this.countryCallingCode, this.nationalNumber, this.getMetadata());
}
}, {
key: "isPossible",
value: function isPossible() {
return (0, _isPossible["default"])(this, {
v2: true
}, this.getMetadata());
}
}, {
key: "isValid",
value: function isValid() {
return (0, _isValid["default"])(this, {
v2: true
}, this.getMetadata());
}
}, {
key: "isNonGeographic",
value: function isNonGeographic() {
var metadata = new _metadata["default"](this.getMetadata());
return metadata.isNonGeographicCallingCode(this.countryCallingCode);
}
}, {
key: "isEqual",
value: function isEqual(phoneNumber) {
return this.number === phoneNumber.number && this.ext === phoneNumber.ext;
} // This function was originally meant to be an equivalent for `validatePhoneNumberLength()`,
// but later it was found out that it doesn't include the possible `TOO_SHORT` result
// returned from `parsePhoneNumberWithError()` in the original `validatePhoneNumberLength()`,
// so eventually I simply commented out this method from the `PhoneNumber` class
// and just left the `validatePhoneNumberLength()` function, even though that one would require
// and additional step to also validate the actual country / calling code of the phone number.
// validateLength() {
// const metadata = new Metadata(this.getMetadata())
// metadata.selectNumberingPlan(this.countryCallingCode)
// const result = checkNumberLength(this.nationalNumber, metadata)
// if (result !== 'IS_POSSIBLE') {
// return result
// }
// }
}, {
key: "getType",
value: function getType() {
return (0, _getNumberType["default"])(this, {
v2: true
}, this.getMetadata());
}
}, {
key: "format",
value: function format(_format, options) {
return (0, _format2["default"])(this, _format, options ? _objectSpread(_objectSpread({}, options), {}, {
v2: true
}) : {
v2: true
}, this.getMetadata());
}
}, {
key: "formatNational",
value: function formatNational(options) {
return this.format('NATIONAL', options);
}
}, {
key: "formatInternational",
value: function formatInternational(options) {
return this.format('INTERNATIONAL', options);
}
}, {
key: "getURI",
value: function getURI(options) {
return this.format('RFC3966', options);
}
}]);
return PhoneNumber;
}();
exports["default"] = PhoneNumber;
var isCountryCode = function isCountryCode(value) {
return /^[A-Z]{2}$/.test(value);
};
function getCountryAndCountryCallingCode(countryOrCountryCallingCode, metadataJson) {
var country;
var countryCallingCode;
var metadata = new _metadata["default"](metadataJson); // If country code is passed then derive `countryCallingCode` from it.
// Also store the country code as `.country`.
if (isCountryCode(countryOrCountryCallingCode)) {
country = countryOrCountryCallingCode;
metadata.selectNumberingPlan(country);
countryCallingCode = metadata.countryCallingCode();
} else {
countryCallingCode = countryOrCountryCallingCode;
/* istanbul ignore if */
if (USE_NON_GEOGRAPHIC_COUNTRY_CODE) {
if (metadata.isNonGeographicCallingCode(countryCallingCode)) {
country = '001';
}
}
}
return {
country: country,
countryCallingCode: countryCallingCode
};
}
var E164_NUMBER_REGEXP = /^\+\d+$/;
//# sourceMappingURL=PhoneNumber.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,133 @@
"use strict";
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
var _PhoneNumber = _interopRequireDefault(require("./PhoneNumber.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('PhoneNumber', function () {
it('should create a phone number via a public constructor', function () {
var phoneNumber = new _PhoneNumber["default"]('+78005553535', _metadataMin["default"]);
phoneNumber.setExt('1234');
expect(phoneNumber.country).to.be.undefined;
phoneNumber.countryCallingCode.should.equal('7');
phoneNumber.nationalNumber.should.equal('8005553535');
phoneNumber.formatNational().should.equal('8 (800) 555-35-35 ext. 1234');
});
it('should validate constructor arguments (public constructor)', function () {
expect(function () {
return new _PhoneNumber["default"]();
}).to["throw"]('argument is required');
expect(function () {
return new _PhoneNumber["default"](undefined, _metadataMin["default"]);
}).to["throw"]('argument is required');
expect(function () {
return new _PhoneNumber["default"]('7', _metadataMin["default"]);
}).to["throw"]('must consist of a "+"');
expect(function () {
return new _PhoneNumber["default"]('+7', _metadataMin["default"]);
}).to["throw"]('too short');
expect(function () {
return new _PhoneNumber["default"]('+7800');
}).to["throw"]('`metadata` argument not passed');
expect(function () {
return new _PhoneNumber["default"](1234567890);
}).to["throw"]('must be a string');
expect(function () {
return new _PhoneNumber["default"]('+1', 1234567890);
}).to["throw"]('must be a string');
});
it('should validate constructor arguments (private constructor)', function () {
expect(function () {
return new _PhoneNumber["default"](undefined, '800', _metadataMin["default"]);
}).to["throw"]('First argument is required');
expect(function () {
return new _PhoneNumber["default"]('7', undefined, _metadataMin["default"]);
}).to["throw"]('`nationalNumber` argument is required');
expect(function () {
return new _PhoneNumber["default"]('7', '8005553535');
}).to["throw"]('`metadata` argument not passed');
});
it('should accept country code argument', function () {
var phoneNumber = new _PhoneNumber["default"]('RU', '8005553535', _metadataMin["default"]);
phoneNumber.countryCallingCode.should.equal('7');
phoneNumber.country.should.equal('RU');
phoneNumber.number.should.equal('+78005553535');
});
it('should format number with options', function () {
var phoneNumber = new _PhoneNumber["default"]('7', '8005553535', _metadataMin["default"]);
phoneNumber.ext = '123';
phoneNumber.format('NATIONAL', {
formatExtension: function formatExtension(number, extension) {
return "".concat(number, " \u0434\u043E\u0431. ").concat(extension);
}
}).should.equal('8 (800) 555-35-35 доб. 123');
});
it('should compare phone numbers', function () {
new _PhoneNumber["default"]('RU', '8005553535', _metadataMin["default"]).isEqual(new _PhoneNumber["default"]('RU', '8005553535', _metadataMin["default"])).should.equal(true);
new _PhoneNumber["default"]('RU', '8005553535', _metadataMin["default"]).isEqual(new _PhoneNumber["default"]('7', '8005553535', _metadataMin["default"])).should.equal(true);
new _PhoneNumber["default"]('RU', '8005553535', _metadataMin["default"]).isEqual(new _PhoneNumber["default"]('RU', '8005553536', _metadataMin["default"])).should.equal(false);
});
it('should tell if a number is non-geographic', function () {
new _PhoneNumber["default"]('7', '8005553535', _metadataMin["default"]).isNonGeographic().should.equal(false);
new _PhoneNumber["default"]('870', '773111632', _metadataMin["default"]).isNonGeographic().should.equal(true);
});
it('should allow setting extension', function () {
var phoneNumber = new _PhoneNumber["default"]('1', '2133734253', _metadataMin["default"]);
phoneNumber.setExt('1234');
phoneNumber.ext.should.equal('1234');
phoneNumber.formatNational().should.equal('(213) 373-4253 ext. 1234');
});
it('should return possible countries', function () {
// "599": [
// "CW", // "possible_lengths": [7, 8]
// "BQ" // "possible_lengths": [7]
// ]
var phoneNumber = new _PhoneNumber["default"]('599', '123456', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().should.deep.equal([]);
phoneNumber = new _PhoneNumber["default"]('599', '1234567', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().should.deep.equal(['CW', 'BQ']);
phoneNumber = new _PhoneNumber["default"]('599', '12345678', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().should.deep.equal(['CW']);
phoneNumber = new _PhoneNumber["default"]('599', '123456789', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().should.deep.equal([]);
});
it('should return possible countries in case of ambiguity', function () {
var phoneNumber = new _PhoneNumber["default"]('1', '2223334444', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().indexOf('US').should.equal(0);
phoneNumber.getPossibleCountries().length.should.equal(25);
}); // it('should return empty possible countries when no national number has been input', () => {
// const phoneNumber = new PhoneNumber('1', '', metadata)
// expect(phoneNumber.country).to.be.undefined
// phoneNumber.getPossibleCountries().should.deep.equal([])
// })
it('should return empty possible countries when not enough national number digits have been input', function () {
var phoneNumber = new _PhoneNumber["default"]('1', '222', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().should.deep.equal([]);
});
it('should return possible countries in case of no ambiguity', function () {
var phoneNumber = new _PhoneNumber["default"]('US', '2133734253', _metadataMin["default"]);
phoneNumber.country.should.equal('US');
phoneNumber.getPossibleCountries().should.deep.equal(['US']);
});
it('should return empty possible countries in case of an unknown calling code', function () {
var phoneNumber = new _PhoneNumber["default"]('777', '123', _metadataMin["default"]);
expect(phoneNumber.country).to.be.undefined;
phoneNumber.getPossibleCountries().should.deep.equal([]);
}); // it('should validate phone number length', () => {
// const phoneNumber = new PhoneNumber('RU', '800', metadata)
// expect(phoneNumber.validateLength()).to.equal('TOO_SHORT')
//
// const phoneNumberValid = new PhoneNumber('RU', '8005553535', metadata)
// expect(phoneNumberValid.validateLength()).to.be.undefined
// })
});
//# sourceMappingURL=PhoneNumber.test.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,384 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _PhoneNumber = _interopRequireDefault(require("./PhoneNumber.js"));
var _constants = require("./constants.js");
var _createExtensionPattern = _interopRequireDefault(require("./helpers/extension/createExtensionPattern.js"));
var _RegExpCache = _interopRequireDefault(require("./findNumbers/RegExpCache.js"));
var _util = require("./findNumbers/util.js");
var _utf = require("./findNumbers/utf-8.js");
var _Leniency = _interopRequireDefault(require("./findNumbers/Leniency.js"));
var _parsePreCandidate = _interopRequireDefault(require("./findNumbers/parsePreCandidate.js"));
var _isValidPreCandidate = _interopRequireDefault(require("./findNumbers/isValidPreCandidate.js"));
var _isValidCandidate = _interopRequireWildcard(require("./findNumbers/isValidCandidate.js"));
var _metadata = require("./metadata.js");
var _parsePhoneNumber = _interopRequireDefault(require("./parsePhoneNumber.js"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
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; }
var USE_NON_GEOGRAPHIC_COUNTRY_CODE = false;
var EXTN_PATTERNS_FOR_MATCHING = (0, _createExtensionPattern["default"])('matching');
/**
* Patterns used to extract phone numbers from a larger phone-number-like pattern. These are
* ordered according to specificity. For example, white-space is last since that is frequently
* used in numbers, not just to separate two numbers. We have separate patterns since we don't
* want to break up the phone-number-like text on more than one different kind of symbol at one
* time, although symbols of the same type (e.g. space) can be safely grouped together.
*
* Note that if there is a match, we will always check any text found up to the first match as
* well.
*/
var INNER_MATCHES = [// Breaks on the slash - e.g. "651-234-2345/332-445-1234"
'\\/+(.*)/', // Note that the bracket here is inside the capturing group, since we consider it part of the
// phone number. Will match a pattern like "(650) 223 3345 (754) 223 3321".
'(\\([^(]*)', // Breaks on a hyphen - e.g. "12345 - 332-445-1234 is my number."
// We require a space on either side of the hyphen for it to be considered a separator.
"(?:".concat(_utf.pZ, "-|-").concat(_utf.pZ, ")").concat(_utf.pZ, "*(.+)"), // Various types of wide hyphens. Note we have decided not to enforce a space here, since it's
// possible that it's supposed to be used to break two numbers without spaces, and we haven't
// seen many instances of it used within a number.
"[\u2012-\u2015\uFF0D]".concat(_utf.pZ, "*(.+)"), // Breaks on a full stop - e.g. "12345. 332-445-1234 is my number."
"\\.+".concat(_utf.pZ, "*([^.]+)"), // Breaks on space - e.g. "3324451234 8002341234"
"".concat(_utf.pZ, "+(").concat(_utf.PZ, "+)")]; // Limit on the number of leading (plus) characters.
var leadLimit = (0, _util.limit)(0, 2); // Limit on the number of consecutive punctuation characters.
var punctuationLimit = (0, _util.limit)(0, 4);
/* The maximum number of digits allowed in a digit-separated block. As we allow all digits in a
* single block, set high enough to accommodate the entire national number and the international
* country code. */
var digitBlockLimit = _constants.MAX_LENGTH_FOR_NSN + _constants.MAX_LENGTH_COUNTRY_CODE; // Limit on the number of blocks separated by punctuation.
// Uses digitBlockLimit since some formats use spaces to separate each digit.
var blockLimit = (0, _util.limit)(0, digitBlockLimit);
/* A punctuation sequence allowing white space. */
var punctuation = "[".concat(_constants.VALID_PUNCTUATION, "]") + punctuationLimit; // A digits block without punctuation.
var digitSequence = _utf.pNd + (0, _util.limit)(1, digitBlockLimit);
/**
* Phone number pattern allowing optional punctuation.
* The phone number pattern used by `find()`, similar to
* VALID_PHONE_NUMBER, but with the following differences:
* <ul>
* <li>All captures are limited in order to place an upper bound to the text matched by the
* pattern.
* <ul>
* <li>Leading punctuation / plus signs are limited.
* <li>Consecutive occurrences of punctuation are limited.
* <li>Number of digits is limited.
* </ul>
* <li>No whitespace is allowed at the start or end.
* <li>No alpha digits (vanity numbers such as 1-800-SIX-FLAGS) are currently supported.
* </ul>
*/
var PATTERN = '(?:' + _isValidCandidate.LEAD_CLASS + punctuation + ')' + leadLimit + digitSequence + '(?:' + punctuation + digitSequence + ')' + blockLimit + '(?:' + EXTN_PATTERNS_FOR_MATCHING + ')?'; // Regular expression of trailing characters that we want to remove.
// We remove all characters that are not alpha or numerical characters.
// The hash character is retained here, as it may signify
// the previous block was an extension.
//
// // Don't know what does '&&' mean here.
// const UNWANTED_END_CHAR_PATTERN = new RegExp(`[[\\P{N}&&\\P{L}]&&[^#]]+$`)
//
var UNWANTED_END_CHAR_PATTERN = new RegExp("[^".concat(_utf._pN).concat(_utf._pL, "#]+$"));
var NON_DIGITS_PATTERN = /(\D+)/;
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1;
/**
* A stateful class that finds and extracts telephone numbers from {@linkplain CharSequence text}.
* Instances can be created using the {@linkplain PhoneNumberUtil#findNumbers factory methods} in
* {@link PhoneNumberUtil}.
*
* <p>Vanity numbers (phone numbers using alphabetic digits such as <tt>1-800-SIX-FLAGS</tt> are
* not found.
*
* <p>This class is not thread-safe.
*/
var PhoneNumberMatcher = /*#__PURE__*/function () {
/**
* @param {string} text — the character sequence that we will search, null for no text.
* @param {'POSSIBLE'|'VALID'|'STRICT_GROUPING'|'EXACT_GROUPING'} [options.leniency] — The leniency to use when evaluating candidate phone numbers. See `source/findNumbers/Leniency.js` for more details.
* @param {number} [options.maxTries] — The maximum number of invalid numbers to try before giving up on the text. This is to cover degenerate cases where the text has a lot of false positives in it. Must be >= 0.
*/
function PhoneNumberMatcher() {
var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var metadata = arguments.length > 2 ? arguments[2] : undefined;
_classCallCheck(this, PhoneNumberMatcher);
options = {
v2: options.v2,
defaultCallingCode: options.defaultCallingCode,
defaultCountry: options.defaultCountry && (0, _metadata.isSupportedCountry)(options.defaultCountry, metadata) ? options.defaultCountry : undefined,
leniency: options.leniency || (options.extended ? 'POSSIBLE' : 'VALID'),
maxTries: options.maxTries || MAX_SAFE_INTEGER
}; // Validate `leniency`.
if (!options.leniency) {
throw new TypeError('`leniency` is required');
}
if (options.leniency !== 'POSSIBLE' && options.leniency !== 'VALID') {
throw new TypeError("Invalid `leniency`: \"".concat(options.leniency, "\". Supported values: \"POSSIBLE\", \"VALID\"."));
} // Validate `maxTries`.
if (options.maxTries < 0) {
throw new TypeError('`maxTries` must be `>= 0`');
}
this.text = text;
this.options = options;
this.metadata = metadata; // The degree of phone number validation.
this.leniency = _Leniency["default"][options.leniency];
if (!this.leniency) {
throw new TypeError("Unknown leniency: \"".concat(options.leniency, "\""));
}
/** The maximum number of retries after matching an invalid number. */
this.maxTries = options.maxTries;
this.PATTERN = new RegExp(PATTERN, 'ig');
/** The iteration tristate. */
this.state = 'NOT_READY';
/** The next index to start searching at. Undefined in {@link State#DONE}. */
this.searchIndex = 0; // A cache for frequently used country-specific regular expressions. Set to 32 to cover ~2-3
// countries being used for the same doc with ~10 patterns for each country. Some pages will have
// a lot more countries in use, but typically fewer numbers for each so expanding the cache for
// that use-case won't have a lot of benefit.
this.regExpCache = new _RegExpCache["default"](32);
}
/**
* Attempts to find the next subsequence in the searched sequence on or after {@code searchIndex}
* that represents a phone number. Returns the next match, null if none was found.
*
* @param index the search index to start searching at
* @return the phone number match found, null if none can be found
*/
_createClass(PhoneNumberMatcher, [{
key: "find",
value: function find() {
// // Reset the regular expression.
// this.PATTERN.lastIndex = index
var matches;
while (this.maxTries > 0 && (matches = this.PATTERN.exec(this.text)) !== null) {
var candidate = matches[0];
var offset = matches.index;
candidate = (0, _parsePreCandidate["default"])(candidate);
if ((0, _isValidPreCandidate["default"])(candidate, offset, this.text)) {
var match = // Try to come up with a valid match given the entire candidate.
this.parseAndVerify(candidate, offset, this.text) // If that failed, try to find an "inner match" -
// there might be a phone number within this candidate.
|| this.extractInnerMatch(candidate, offset, this.text);
if (match) {
if (this.options.v2) {
return {
startsAt: match.startsAt,
endsAt: match.endsAt,
number: match.phoneNumber
};
} else {
var phoneNumber = match.phoneNumber;
var result = {
startsAt: match.startsAt,
endsAt: match.endsAt,
phone: phoneNumber.nationalNumber
};
if (phoneNumber.country) {
/* istanbul ignore if */
if (USE_NON_GEOGRAPHIC_COUNTRY_CODE && country === '001') {
result.countryCallingCode = phoneNumber.countryCallingCode;
} else {
result.country = phoneNumber.country;
}
} else {
result.countryCallingCode = phoneNumber.countryCallingCode;
}
if (phoneNumber.ext) {
result.ext = phoneNumber.ext;
}
return result;
}
}
}
this.maxTries--;
}
}
/**
* Attempts to extract a match from `substring`
* if the substring itself does not qualify as a match.
*/
}, {
key: "extractInnerMatch",
value: function extractInnerMatch(substring, offset, text) {
for (var _iterator = _createForOfIteratorHelperLoose(INNER_MATCHES), _step; !(_step = _iterator()).done;) {
var innerMatchPattern = _step.value;
var isFirstMatch = true;
var candidateMatch = void 0;
var innerMatchRegExp = new RegExp(innerMatchPattern, 'g');
while (this.maxTries > 0 && (candidateMatch = innerMatchRegExp.exec(substring)) !== null) {
if (isFirstMatch) {
// We should handle any group before this one too.
var _candidate = (0, _util.trimAfterFirstMatch)(UNWANTED_END_CHAR_PATTERN, substring.slice(0, candidateMatch.index));
var _match = this.parseAndVerify(_candidate, offset, text);
if (_match) {
return _match;
}
this.maxTries--;
isFirstMatch = false;
}
var candidate = (0, _util.trimAfterFirstMatch)(UNWANTED_END_CHAR_PATTERN, candidateMatch[1]); // Java code does `groupMatcher.start(1)` here,
// but there's no way in javascript to get a `candidate` start index,
// therefore resort to using this kind of an approximation.
// (`groupMatcher` is called `candidateInSubstringMatch` in this javascript port)
// https://stackoverflow.com/questions/15934353/get-index-of-each-capture-in-a-javascript-regex
var candidateIndexGuess = substring.indexOf(candidate, candidateMatch.index);
var match = this.parseAndVerify(candidate, offset + candidateIndexGuess, text);
if (match) {
return match;
}
this.maxTries--;
}
}
}
/**
* Parses a phone number from the `candidate` using `parse` and
* verifies it matches the requested `leniency`. If parsing and verification succeed,
* a corresponding `PhoneNumberMatch` is returned, otherwise this method returns `null`.
*
* @param candidate the candidate match
* @param offset the offset of {@code candidate} within {@link #text}
* @return the parsed and validated phone number match, or null
*/
}, {
key: "parseAndVerify",
value: function parseAndVerify(candidate, offset, text) {
if (!(0, _isValidCandidate["default"])(candidate, offset, text, this.options.leniency)) {
return;
}
var phoneNumber = (0, _parsePhoneNumber["default"])(candidate, {
extended: true,
defaultCountry: this.options.defaultCountry,
defaultCallingCode: this.options.defaultCallingCode
}, this.metadata);
if (!phoneNumber) {
return;
}
if (!phoneNumber.isPossible()) {
return;
}
if (this.leniency(phoneNumber, {
candidate: candidate,
defaultCountry: this.options.defaultCountry,
metadata: this.metadata,
regExpCache: this.regExpCache
})) {
return {
startsAt: offset,
endsAt: offset + candidate.length,
phoneNumber: phoneNumber
};
}
}
}, {
key: "hasNext",
value: function hasNext() {
if (this.state === 'NOT_READY') {
this.lastMatch = this.find(); // (this.searchIndex)
if (this.lastMatch) {
// this.searchIndex = this.lastMatch.endsAt
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.lastMatch;
this.lastMatch = null;
this.state = 'NOT_READY';
return result;
}
}]);
return PhoneNumberMatcher;
}();
exports["default"] = PhoneNumberMatcher;
//# sourceMappingURL=PhoneNumberMatcher.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,88 @@
"use strict";
var _PhoneNumberMatcher = _interopRequireDefault(require("./PhoneNumberMatcher.js"));
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function test(text, defaultCountry, expectedNumbers) {
if (typeof expectedNumbers === 'string') {
expectedNumbers = [{
nationalNumber: expectedNumbers
}];
}
var matcher = new _PhoneNumberMatcher["default"](text, {
defaultCountry: defaultCountry,
v2: true
}, _metadataMin["default"]);
while (matcher.hasNext()) {
var number = matcher.next();
var phoneNumber = expectedNumbers.shift();
if (phoneNumber.startsAt !== undefined) {
number.startsAt.should.equal(phoneNumber.startsAt);
}
if (phoneNumber.endsAt !== undefined) {
number.endsAt.should.equal(phoneNumber.endsAt);
}
number.number.country.should.equal(phoneNumber.country || defaultCountry);
number.number.nationalNumber.should.equal(phoneNumber.nationalNumber);
}
expectedNumbers.length.should.equal(0);
}
describe('PhoneNumberMatcher', function () {
it('should find phone numbers', function () {
test('The number is +7 (800) 555-35-35 and not (213) 373-4253 as written in the document.', 'US', [{
country: 'RU',
nationalNumber: '8005553535',
startsAt: 14,
endsAt: 32
}, {
country: 'US',
nationalNumber: '2133734253',
startsAt: 41,
endsAt: 55
}]);
});
it('should find phone numbers from Mexico', function () {
// Test parsing fixed-line numbers of Mexico.
test('+52 (449)978-0001', 'MX', '4499780001');
test('01 (449)978-0001', 'MX', '4499780001');
test('(449)978-0001', 'MX', '4499780001'); // "Dialling tokens 01, 02, 044, 045 and 1 are removed as they are
// no longer valid since August 2019."
// // Test parsing mobile numbers of Mexico.
// test('+52 1 33 1234-5678', 'MX', '3312345678')
// test('044 (33) 1234-5678', 'MX', '3312345678')
// test('045 33 1234-5678', 'MX', '3312345678')
});
it('should find phone numbers from Argentina', function () {
// Test parsing mobile numbers of Argentina.
test('+54 9 343 555 1212', 'AR', '93435551212');
test('0343 15-555-1212', 'AR', '93435551212');
test('+54 9 3715 65 4320', 'AR', '93715654320');
test('03715 15 65 4320', 'AR', '93715654320'); // Test parsing fixed-line numbers of Argentina.
test('+54 11 3797 0000', 'AR', '1137970000');
test('011 3797 0000', 'AR', '1137970000');
test('+54 3715 65 4321', 'AR', '3715654321');
test('03715 65 4321', 'AR', '3715654321');
test('+54 23 1234 0000', 'AR', '2312340000');
test('023 1234 0000', 'AR', '2312340000');
});
it('should only support the supported leniency values', function () {
expect(function () {
return new _PhoneNumberMatcher["default"]('+54 23 1234 0000', {
leniency: 'STRICT_GROUPING',
v2: true
}, _metadataMin["default"]);
}).to["throw"]('Supported values: "POSSIBLE", "VALID".');
});
});
//# sourceMappingURL=PhoneNumberMatcher.test.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.WHITESPACE = exports.VALID_PUNCTUATION = exports.VALID_DIGITS = exports.PLUS_CHARS = exports.MIN_LENGTH_FOR_NSN = exports.MAX_LENGTH_FOR_NSN = exports.MAX_LENGTH_COUNTRY_CODE = void 0;
// The minimum length of the national significant number.
var MIN_LENGTH_FOR_NSN = 2; // The ITU says the maximum length should be 15,
// but one can find longer numbers in Germany.
exports.MIN_LENGTH_FOR_NSN = MIN_LENGTH_FOR_NSN;
var MAX_LENGTH_FOR_NSN = 17; // The maximum length of the country calling code.
exports.MAX_LENGTH_FOR_NSN = MAX_LENGTH_FOR_NSN;
var MAX_LENGTH_COUNTRY_CODE = 3; // Digits accepted in phone numbers
// (ascii, fullwidth, arabic-indic, and eastern arabic digits).
exports.MAX_LENGTH_COUNTRY_CODE = MAX_LENGTH_COUNTRY_CODE;
var VALID_DIGITS = "0-9\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9"; // `DASHES` will be right after the opening square bracket of the "character class"
exports.VALID_DIGITS = VALID_DIGITS;
var DASHES = "-\u2010-\u2015\u2212\u30FC\uFF0D";
var SLASHES = "\uFF0F/";
var DOTS = "\uFF0E.";
var WHITESPACE = " \xA0\xAD\u200B\u2060\u3000";
exports.WHITESPACE = WHITESPACE;
var BRACKETS = "()\uFF08\uFF09\uFF3B\uFF3D\\[\\]"; // export const OPENING_BRACKETS = '(\uFF08\uFF3B\\\['
var TILDES = "~\u2053\u223C\uFF5E"; // Regular expression of acceptable punctuation found in phone numbers. This
// excludes punctuation found as a leading character only. This consists of dash
// characters, white space characters, full stops, slashes, square brackets,
// parentheses and tildes. Full-width variants are also present.
var VALID_PUNCTUATION = "".concat(DASHES).concat(SLASHES).concat(DOTS).concat(WHITESPACE).concat(BRACKETS).concat(TILDES);
exports.VALID_PUNCTUATION = VALID_PUNCTUATION;
var PLUS_CHARS = "+\uFF0B"; // const LEADING_PLUS_CHARS_PATTERN = new RegExp('^[' + PLUS_CHARS + ']+')
exports.PLUS_CHARS = PLUS_CHARS;
//# sourceMappingURL=constants.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constants.js","names":["MIN_LENGTH_FOR_NSN","MAX_LENGTH_FOR_NSN","MAX_LENGTH_COUNTRY_CODE","VALID_DIGITS","DASHES","SLASHES","DOTS","WHITESPACE","BRACKETS","TILDES","VALID_PUNCTUATION","PLUS_CHARS"],"sources":["../source/constants.js"],"sourcesContent":["// The minimum length of the national significant number.\r\nexport const MIN_LENGTH_FOR_NSN = 2\r\n\r\n// The ITU says the maximum length should be 15,\r\n// but one can find longer numbers in Germany.\r\nexport const MAX_LENGTH_FOR_NSN = 17\r\n\r\n// The maximum length of the country calling code.\r\nexport const MAX_LENGTH_COUNTRY_CODE = 3\r\n\r\n// Digits accepted in phone numbers\r\n// (ascii, fullwidth, arabic-indic, and eastern arabic digits).\r\nexport const VALID_DIGITS = '0-9\\uFF10-\\uFF19\\u0660-\\u0669\\u06F0-\\u06F9'\r\n\r\n// `DASHES` will be right after the opening square bracket of the \"character class\"\r\nconst DASHES = '-\\u2010-\\u2015\\u2212\\u30FC\\uFF0D'\r\nconst SLASHES = '\\uFF0F/'\r\nconst DOTS = '\\uFF0E.'\r\nexport const WHITESPACE = ' \\u00A0\\u00AD\\u200B\\u2060\\u3000'\r\nconst BRACKETS = '()\\uFF08\\uFF09\\uFF3B\\uFF3D\\\\[\\\\]'\r\n// export const OPENING_BRACKETS = '(\\uFF08\\uFF3B\\\\\\['\r\nconst TILDES = '~\\u2053\\u223C\\uFF5E'\r\n\r\n// Regular expression of acceptable punctuation found in phone numbers. This\r\n// excludes punctuation found as a leading character only. This consists of dash\r\n// characters, white space characters, full stops, slashes, square brackets,\r\n// parentheses and tildes. Full-width variants are also present.\r\nexport const VALID_PUNCTUATION = `${DASHES}${SLASHES}${DOTS}${WHITESPACE}${BRACKETS}${TILDES}`\r\n\r\nexport const PLUS_CHARS = '+\\uFF0B'\r\n// const LEADING_PLUS_CHARS_PATTERN = new RegExp('^[' + PLUS_CHARS + ']+')"],"mappings":";;;;;;AAAA;AACO,IAAMA,kBAAkB,GAAG,CAA3B,C,CAEP;AACA;;;AACO,IAAMC,kBAAkB,GAAG,EAA3B,C,CAEP;;;AACO,IAAMC,uBAAuB,GAAG,CAAhC,C,CAEP;AACA;;;AACO,IAAMC,YAAY,GAAG,4CAArB,C,CAEP;;;AACA,IAAMC,MAAM,GAAG,kCAAf;AACA,IAAMC,OAAO,GAAG,SAAhB;AACA,IAAMC,IAAI,GAAG,SAAb;AACO,IAAMC,UAAU,GAAG,6BAAnB;;AACP,IAAMC,QAAQ,GAAG,kCAAjB,C,CACA;;AACA,IAAMC,MAAM,GAAG,qBAAf,C,CAEA;AACA;AACA;AACA;;AACO,IAAMC,iBAAiB,aAAMN,MAAN,SAAeC,OAAf,SAAyBC,IAAzB,SAAgCC,UAAhC,SAA6CC,QAA7C,SAAwDC,MAAxD,CAAvB;;AAEA,IAAME,UAAU,GAAG,SAAnB,C,CACP"}

View File

@@ -0,0 +1,134 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// https://medium.com/dsinjs/implementing-lru-cache-in-javascript-94ba6755cda9
var Node = /*#__PURE__*/_createClass(function Node(key, value) {
var next = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var prev = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
_classCallCheck(this, Node);
this.key = key;
this.value = value;
this.next = next;
this.prev = prev;
});
var LRUCache = /*#__PURE__*/function () {
//set default limit of 10 if limit is not passed.
function LRUCache() {
var limit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
_classCallCheck(this, LRUCache);
this.size = 0;
this.limit = limit;
this.head = null;
this.tail = null;
this.cache = {};
} // Write Node to head of LinkedList
// update cache with Node key and Node reference
_createClass(LRUCache, [{
key: "put",
value: function put(key, value) {
this.ensureLimit();
if (!this.head) {
this.head = this.tail = new Node(key, value);
} else {
var node = new Node(key, value, this.head);
this.head.prev = node;
this.head = node;
} //Update the cache map
this.cache[key] = this.head;
this.size++;
} // Read from cache map and make that node as new Head of LinkedList
}, {
key: "get",
value: function get(key) {
if (this.cache[key]) {
var value = this.cache[key].value; // node removed from it's position and cache
this.remove(key); // write node again to the head of LinkedList to make it most recently used
this.put(key, value);
return value;
}
console.log("Item not available in cache for key ".concat(key));
}
}, {
key: "ensureLimit",
value: function ensureLimit() {
if (this.size === this.limit) {
this.remove(this.tail.key);
}
}
}, {
key: "remove",
value: function remove(key) {
var node = this.cache[key];
if (node.prev !== null) {
node.prev.next = node.next;
} else {
this.head = node.next;
}
if (node.next !== null) {
node.next.prev = node.prev;
} else {
this.tail = node.prev;
}
delete this.cache[key];
this.size--;
}
}, {
key: "clear",
value: function clear() {
this.head = null;
this.tail = null;
this.size = 0;
this.cache = {};
} // // Invokes the callback function with every node of the chain and the index of the node.
// forEach(fn) {
// let node = this.head;
// let counter = 0;
// while (node) {
// fn(node, counter);
// node = node.next;
// counter++;
// }
// }
// // To iterate over LRU with a 'for...of' loop
// *[Symbol.iterator]() {
// let node = this.head;
// while (node) {
// yield node;
// node = node.next;
// }
// }
}]);
return LRUCache;
}();
exports["default"] = LRUCache;
//# sourceMappingURL=LRUCache.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"LRUCache.js","names":["Node","key","value","next","prev","LRUCache","limit","size","head","tail","cache","ensureLimit","node","remove","put","console","log"],"sources":["../../source/findNumbers/LRUCache.js"],"sourcesContent":["// https://medium.com/dsinjs/implementing-lru-cache-in-javascript-94ba6755cda9\r\n\r\nclass Node {\r\n constructor(key, value, next = null, prev = null) {\r\n this.key = key;\r\n this.value = value;\r\n this.next = next;\r\n this.prev = prev;\r\n }\r\n}\r\n\r\nexport default class LRUCache {\r\n //set default limit of 10 if limit is not passed.\r\n constructor(limit = 10) {\r\n this.size = 0;\r\n this.limit = limit;\r\n this.head = null;\r\n this.tail = null;\r\n this.cache = {};\r\n }\r\n\r\n // Write Node to head of LinkedList\r\n // update cache with Node key and Node reference\r\n put(key, value){\r\n this.ensureLimit();\r\n\r\n if(!this.head){\r\n this.head = this.tail = new Node(key, value);\r\n }else{\r\n const node = new Node(key, value, this.head);\r\n this.head.prev = node;\r\n this.head = node;\r\n }\r\n\r\n //Update the cache map\r\n this.cache[key] = this.head;\r\n this.size++;\r\n }\r\n\r\n // Read from cache map and make that node as new Head of LinkedList\r\n get(key){\r\n if(this.cache[key]){\r\n const value = this.cache[key].value;\r\n\r\n // node removed from it's position and cache\r\n this.remove(key)\r\n // write node again to the head of LinkedList to make it most recently used\r\n this.put(key, value);\r\n\r\n return value;\r\n }\r\n\r\n console.log(`Item not available in cache for key ${key}`);\r\n }\r\n\r\n ensureLimit(){\r\n if(this.size === this.limit){\r\n this.remove(this.tail.key)\r\n }\r\n }\r\n\r\n remove(key){\r\n const node = this.cache[key];\r\n\r\n if(node.prev !== null){\r\n node.prev.next = node.next;\r\n }else{\r\n this.head = node.next;\r\n }\r\n\r\n if(node.next !== null){\r\n node.next.prev = node.prev;\r\n }else{\r\n this.tail = node.prev\r\n }\r\n\r\n delete this.cache[key];\r\n this.size--;\r\n }\r\n\r\n clear() {\r\n this.head = null;\r\n this.tail = null;\r\n this.size = 0;\r\n this.cache = {};\r\n }\r\n\r\n // // Invokes the callback function with every node of the chain and the index of the node.\r\n // forEach(fn) {\r\n // let node = this.head;\r\n // let counter = 0;\r\n // while (node) {\r\n // fn(node, counter);\r\n // node = node.next;\r\n // counter++;\r\n // }\r\n // }\r\n\r\n // // To iterate over LRU with a 'for...of' loop\r\n // *[Symbol.iterator]() {\r\n // let node = this.head;\r\n // while (node) {\r\n // yield node;\r\n // node = node.next;\r\n // }\r\n // }\r\n}"],"mappings":";;;;;;;;;;;;;AAAA;IAEMA,I,6BACJ,cAAYC,GAAZ,EAAiBC,KAAjB,EAAkD;EAAA,IAA1BC,IAA0B,uEAAnB,IAAmB;EAAA,IAAbC,IAAa,uEAAN,IAAM;;EAAA;;EAChD,KAAKH,GAAL,GAAWA,GAAX;EACA,KAAKC,KAAL,GAAaA,KAAb;EACA,KAAKC,IAAL,GAAYA,IAAZ;EACA,KAAKC,IAAL,GAAYA,IAAZ;AACD,C;;IAGkBC,Q;EACnB;EACA,oBAAwB;IAAA,IAAZC,KAAY,uEAAJ,EAAI;;IAAA;;IACtB,KAAKC,IAAL,GAAY,CAAZ;IACA,KAAKD,KAAL,GAAaA,KAAb;IACA,KAAKE,IAAL,GAAY,IAAZ;IACA,KAAKC,IAAL,GAAY,IAAZ;IACA,KAAKC,KAAL,GAAa,EAAb;EACD,C,CAED;EACA;;;;;WACA,aAAIT,GAAJ,EAASC,KAAT,EAAe;MACb,KAAKS,WAAL;;MAEA,IAAG,CAAC,KAAKH,IAAT,EAAc;QACZ,KAAKA,IAAL,GAAY,KAAKC,IAAL,GAAY,IAAIT,IAAJ,CAASC,GAAT,EAAcC,KAAd,CAAxB;MACD,CAFD,MAEK;QACH,IAAMU,IAAI,GAAG,IAAIZ,IAAJ,CAASC,GAAT,EAAcC,KAAd,EAAqB,KAAKM,IAA1B,CAAb;QACA,KAAKA,IAAL,CAAUJ,IAAV,GAAiBQ,IAAjB;QACA,KAAKJ,IAAL,GAAYI,IAAZ;MACD,CATY,CAWb;;;MACA,KAAKF,KAAL,CAAWT,GAAX,IAAkB,KAAKO,IAAvB;MACA,KAAKD,IAAL;IACD,C,CAED;;;;WACA,aAAIN,GAAJ,EAAQ;MACN,IAAG,KAAKS,KAAL,CAAWT,GAAX,CAAH,EAAmB;QACjB,IAAMC,KAAK,GAAG,KAAKQ,KAAL,CAAWT,GAAX,EAAgBC,KAA9B,CADiB,CAGjB;;QACA,KAAKW,MAAL,CAAYZ,GAAZ,EAJiB,CAKjB;;QACA,KAAKa,GAAL,CAASb,GAAT,EAAcC,KAAd;QAEA,OAAOA,KAAP;MACD;;MAEDa,OAAO,CAACC,GAAR,+CAAmDf,GAAnD;IACD;;;WAED,uBAAa;MACX,IAAG,KAAKM,IAAL,KAAc,KAAKD,KAAtB,EAA4B;QAC1B,KAAKO,MAAL,CAAY,KAAKJ,IAAL,CAAUR,GAAtB;MACD;IACF;;;WAED,gBAAOA,GAAP,EAAW;MACT,IAAMW,IAAI,GAAG,KAAKF,KAAL,CAAWT,GAAX,CAAb;;MAEA,IAAGW,IAAI,CAACR,IAAL,KAAc,IAAjB,EAAsB;QACpBQ,IAAI,CAACR,IAAL,CAAUD,IAAV,GAAiBS,IAAI,CAACT,IAAtB;MACD,CAFD,MAEK;QACH,KAAKK,IAAL,GAAYI,IAAI,CAACT,IAAjB;MACD;;MAED,IAAGS,IAAI,CAACT,IAAL,KAAc,IAAjB,EAAsB;QACpBS,IAAI,CAACT,IAAL,CAAUC,IAAV,GAAiBQ,IAAI,CAACR,IAAtB;MACD,CAFD,MAEK;QACH,KAAKK,IAAL,GAAYG,IAAI,CAACR,IAAjB;MACD;;MAED,OAAO,KAAKM,KAAL,CAAWT,GAAX,CAAP;MACA,KAAKM,IAAL;IACD;;;WAED,iBAAQ;MACN,KAAKC,IAAL,GAAY,IAAZ;MACA,KAAKC,IAAL,GAAY,IAAZ;MACA,KAAKF,IAAL,GAAY,CAAZ;MACA,KAAKG,KAAL,GAAa,EAAb;IACD,C,CAED;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA"}

View File

@@ -0,0 +1,374 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.containsMoreThanOneSlashInNationalNumber = containsMoreThanOneSlashInNationalNumber;
exports["default"] = void 0;
var _isValid = _interopRequireDefault(require("../isValid.js"));
var _parseDigits = _interopRequireDefault(require("../helpers/parseDigits.js"));
var _matchPhoneNumberStringAgainstPhoneNumber = _interopRequireDefault(require("./matchPhoneNumberStringAgainstPhoneNumber.js"));
var _metadata2 = _interopRequireDefault(require("../metadata.js"));
var _getCountryByCallingCode = _interopRequireDefault(require("../helpers/getCountryByCallingCode.js"));
var _format = require("../format.js");
var _util = require("./util.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Leniency when finding potential phone numbers in text segments
* The levels here are ordered in increasing strictness.
*/
var _default = {
/**
* Phone numbers accepted are "possible", but not necessarily "valid".
*/
POSSIBLE: function POSSIBLE(phoneNumber, _ref) {
var candidate = _ref.candidate,
metadata = _ref.metadata;
return true;
},
/**
* Phone numbers accepted are "possible" and "valid".
* Numbers written in national format must have their national-prefix
* present if it is usually written for a number of this type.
*/
VALID: function VALID(phoneNumber, _ref2) {
var candidate = _ref2.candidate,
defaultCountry = _ref2.defaultCountry,
metadata = _ref2.metadata;
if (!phoneNumber.isValid() || !containsOnlyValidXChars(phoneNumber, candidate, metadata)) {
return false;
} // Skipped for simplicity.
// return isNationalPrefixPresentIfRequired(phoneNumber, { defaultCountry, metadata })
return true;
},
/**
* Phone numbers accepted are "valid" and
* are grouped in a possible way for this locale. For example, a US number written as
* "65 02 53 00 00" and "650253 0000" are not accepted at this leniency level, whereas
* "650 253 0000", "650 2530000" or "6502530000" are.
* Numbers with more than one '/' symbol in the national significant number
* are also dropped at this level.
*
* Warning: This level might result in lower coverage especially for regions outside of
* country code "+1". If you are not sure about which level to use,
* email the discussion group libphonenumber-discuss@googlegroups.com.
*/
STRICT_GROUPING: function STRICT_GROUPING(phoneNumber, _ref3) {
var candidate = _ref3.candidate,
defaultCountry = _ref3.defaultCountry,
metadata = _ref3.metadata,
regExpCache = _ref3.regExpCache;
if (!phoneNumber.isValid() || !containsOnlyValidXChars(phoneNumber, candidate, metadata) || containsMoreThanOneSlashInNationalNumber(phoneNumber, candidate) || !isNationalPrefixPresentIfRequired(phoneNumber, {
defaultCountry: defaultCountry,
metadata: metadata
})) {
return false;
}
return checkNumberGroupingIsValid(phoneNumber, candidate, metadata, allNumberGroupsRemainGrouped, regExpCache);
},
/**
* Phone numbers accepted are "valid" and are grouped in the same way
* that we would have formatted it, or as a single block.
* For example, a US number written as "650 2530000" is not accepted
* at this leniency level, whereas "650 253 0000" or "6502530000" are.
* Numbers with more than one '/' symbol are also dropped at this level.
*
* Warning: This level might result in lower coverage especially for regions outside of
* country code "+1". If you are not sure about which level to use, email the discussion group
* libphonenumber-discuss@googlegroups.com.
*/
EXACT_GROUPING: function EXACT_GROUPING(phoneNumber, _ref4) {
var candidate = _ref4.candidate,
defaultCountry = _ref4.defaultCountry,
metadata = _ref4.metadata,
regExpCache = _ref4.regExpCache;
if (!phoneNumber.isValid() || !containsOnlyValidXChars(phoneNumber, candidate, metadata) || containsMoreThanOneSlashInNationalNumber(phoneNumber, candidate) || !isNationalPrefixPresentIfRequired(phoneNumber, {
defaultCountry: defaultCountry,
metadata: metadata
})) {
return false;
}
return checkNumberGroupingIsValid(phoneNumber, candidate, metadata, allNumberGroupsAreExactlyPresent, regExpCache);
}
};
exports["default"] = _default;
function containsOnlyValidXChars(phoneNumber, candidate, metadata) {
// The characters 'x' and 'X' can be (1) a carrier code, in which case they always precede the
// national significant number or (2) an extension sign, in which case they always precede the
// extension number. We assume a carrier code is more than 1 digit, so the first case has to
// have more than 1 consecutive 'x' or 'X', whereas the second case can only have exactly 1 'x'
// or 'X'. We ignore the character if it appears as the last character of the string.
for (var index = 0; index < candidate.length - 1; index++) {
var charAtIndex = candidate.charAt(index);
if (charAtIndex === 'x' || charAtIndex === 'X') {
var charAtNextIndex = candidate.charAt(index + 1);
if (charAtNextIndex === 'x' || charAtNextIndex === 'X') {
// This is the carrier code case, in which the 'X's always precede the national
// significant number.
index++;
if ((0, _matchPhoneNumberStringAgainstPhoneNumber["default"])(candidate.substring(index), phoneNumber, metadata) !== 'NSN_MATCH') {
return false;
} // This is the extension sign case, in which the 'x' or 'X' should always precede the
// extension number.
} else {
var ext = (0, _parseDigits["default"])(candidate.substring(index));
if (ext) {
if (phoneNumber.ext !== ext) {
return false;
}
} else {
if (phoneNumber.ext) {
return false;
}
}
}
}
}
return true;
}
function isNationalPrefixPresentIfRequired(phoneNumber, _ref5) {
var defaultCountry = _ref5.defaultCountry,
_metadata = _ref5.metadata;
// First, check how we deduced the country code. If it was written in international format, then
// the national prefix is not required.
if (phoneNumber.__countryCallingCodeSource !== 'FROM_DEFAULT_COUNTRY') {
return true;
}
var metadata = new _metadata2["default"](_metadata);
metadata.selectNumberingPlan(phoneNumber.countryCallingCode);
var phoneNumberRegion = phoneNumber.country || (0, _getCountryByCallingCode["default"])(phoneNumber.countryCallingCode, {
nationalNumber: phoneNumber.nationalNumber,
defaultCountry: defaultCountry,
metadata: metadata
}); // Check if a national prefix should be present when formatting this number.
var nationalNumber = phoneNumber.nationalNumber;
var format = (0, _format.chooseFormatForNumber)(metadata.numberingPlan.formats(), nationalNumber); // To do this, we check that a national prefix formatting rule was present
// and that it wasn't just the first-group symbol ($1) with punctuation.
if (format.nationalPrefixFormattingRule()) {
if (metadata.numberingPlan.nationalPrefixIsOptionalWhenFormattingInNationalFormat()) {
// The national-prefix is optional in these cases, so we don't need to check if it was present.
return true;
}
if (!format.usesNationalPrefix()) {
// National Prefix not needed for this number.
return true;
}
return Boolean(phoneNumber.nationalPrefix);
}
return true;
}
function containsMoreThanOneSlashInNationalNumber(phoneNumber, candidate) {
var firstSlashInBodyIndex = candidate.indexOf('/');
if (firstSlashInBodyIndex < 0) {
// No slashes, this is okay.
return false;
} // Now look for a second one.
var secondSlashInBodyIndex = candidate.indexOf('/', firstSlashInBodyIndex + 1);
if (secondSlashInBodyIndex < 0) {
// Only one slash, this is okay.
return false;
} // If the first slash is after the country calling code, this is permitted.
var candidateHasCountryCode = phoneNumber.__countryCallingCodeSource === 'FROM_NUMBER_WITH_PLUS_SIGN' || phoneNumber.__countryCallingCodeSource === 'FROM_NUMBER_WITHOUT_PLUS_SIGN';
if (candidateHasCountryCode && (0, _parseDigits["default"])(candidate.substring(0, firstSlashInBodyIndex)) === phoneNumber.countryCallingCode) {
// Any more slashes and this is illegal.
return candidate.slice(secondSlashInBodyIndex + 1).indexOf('/') >= 0;
}
return true;
}
function checkNumberGroupingIsValid(number, candidate, metadata, checkGroups, regExpCache) {
throw new Error('This part of code hasn\'t been ported');
var normalizedCandidate = normalizeDigits(candidate, true
/* keep non-digits */
);
var formattedNumberGroups = getNationalNumberGroups(metadata, number, null);
if (checkGroups(metadata, number, normalizedCandidate, formattedNumberGroups)) {
return true;
} // If this didn't pass, see if there are any alternate formats that match, and try them instead.
var alternateFormats = MetadataManager.getAlternateFormatsForCountry(number.getCountryCode());
var nationalSignificantNumber = util.getNationalSignificantNumber(number);
if (alternateFormats) {
for (var _iterator = _createForOfIteratorHelperLoose(alternateFormats.numberFormats()), _step; !(_step = _iterator()).done;) {
var alternateFormat = _step.value;
if (alternateFormat.leadingDigitsPatterns().length > 0) {
// There is only one leading digits pattern for alternate formats.
var leadingDigitsRegExp = regExpCache.getPatternForRegExp('^' + alternateFormat.leadingDigitsPatterns()[0]);
if (!leadingDigitsRegExp.test(nationalSignificantNumber)) {
// Leading digits don't match; try another one.
continue;
}
}
formattedNumberGroups = getNationalNumberGroups(metadata, number, alternateFormat);
if (checkGroups(metadata, number, normalizedCandidate, formattedNumberGroups)) {
return true;
}
}
}
return false;
}
/**
* Helper method to get the national-number part of a number, formatted without any national
* prefix, and return it as a set of digit blocks that would be formatted together following
* standard formatting rules.
*/
function getNationalNumberGroups(metadata, number, formattingPattern) {
throw new Error('This part of code hasn\'t been ported');
if (formattingPattern) {
// We format the NSN only, and split that according to the separator.
var nationalSignificantNumber = util.getNationalSignificantNumber(number);
return util.formatNsnUsingPattern(nationalSignificantNumber, formattingPattern, 'RFC3966', metadata).split('-');
} // This will be in the format +CC-DG1-DG2-DGX;ext=EXT where DG1..DGX represents groups of digits.
var rfc3966Format = formatNumber(number, 'RFC3966', metadata); // We remove the extension part from the formatted string before splitting it into different
// groups.
var endIndex = rfc3966Format.indexOf(';');
if (endIndex < 0) {
endIndex = rfc3966Format.length;
} // The country-code will have a '-' following it.
var startIndex = rfc3966Format.indexOf('-') + 1;
return rfc3966Format.slice(startIndex, endIndex).split('-');
}
function allNumberGroupsAreExactlyPresent(metadata, number, normalizedCandidate, formattedNumberGroups) {
throw new Error('This part of code hasn\'t been ported');
var candidateGroups = normalizedCandidate.split(NON_DIGITS_PATTERN); // Set this to the last group, skipping it if the number has an extension.
var candidateNumberGroupIndex = number.hasExtension() ? candidateGroups.length - 2 : candidateGroups.length - 1; // First we check if the national significant number is formatted as a block.
// We use contains and not equals, since the national significant number may be present with
// a prefix such as a national number prefix, or the country code itself.
if (candidateGroups.length == 1 || candidateGroups[candidateNumberGroupIndex].contains(util.getNationalSignificantNumber(number))) {
return true;
} // Starting from the end, go through in reverse, excluding the first group, and check the
// candidate and number groups are the same.
var formattedNumberGroupIndex = formattedNumberGroups.length - 1;
while (formattedNumberGroupIndex > 0 && candidateNumberGroupIndex >= 0) {
if (candidateGroups[candidateNumberGroupIndex] !== formattedNumberGroups[formattedNumberGroupIndex]) {
return false;
}
formattedNumberGroupIndex--;
candidateNumberGroupIndex--;
} // Now check the first group. There may be a national prefix at the start, so we only check
// that the candidate group ends with the formatted number group.
return candidateNumberGroupIndex >= 0 && (0, _util.endsWith)(candidateGroups[candidateNumberGroupIndex], formattedNumberGroups[0]);
}
function allNumberGroupsRemainGrouped(metadata, number, normalizedCandidate, formattedNumberGroups) {
throw new Error('This part of code hasn\'t been ported');
var fromIndex = 0;
if (number.getCountryCodeSource() !== CountryCodeSource.FROM_DEFAULT_COUNTRY) {
// First skip the country code if the normalized candidate contained it.
var countryCode = String(number.getCountryCode());
fromIndex = normalizedCandidate.indexOf(countryCode) + countryCode.length();
} // Check each group of consecutive digits are not broken into separate groupings in the
// {@code normalizedCandidate} string.
for (var i = 0; i < formattedNumberGroups.length; i++) {
// Fails if the substring of {@code normalizedCandidate} starting from {@code fromIndex}
// doesn't contain the consecutive digits in formattedNumberGroups[i].
fromIndex = normalizedCandidate.indexOf(formattedNumberGroups[i], fromIndex);
if (fromIndex < 0) {
return false;
} // Moves {@code fromIndex} forward.
fromIndex += formattedNumberGroups[i].length();
if (i == 0 && fromIndex < normalizedCandidate.length()) {
// We are at the position right after the NDC. We get the region used for formatting
// information based on the country code in the phone number, rather than the number itself,
// as we do not need to distinguish between different countries with the same country
// calling code and this is faster.
var region = util.getRegionCodeForCountryCode(number.getCountryCode());
if (util.getNddPrefixForRegion(region, true) != null && Character.isDigit(normalizedCandidate.charAt(fromIndex))) {
// This means there is no formatting symbol after the NDC. In this case, we only
// accept the number if there is no formatting symbol at all in the number, except
// for extensions. This is only important for countries with national prefixes.
var nationalSignificantNumber = util.getNationalSignificantNumber(number);
return (0, _util.startsWith)(normalizedCandidate.slice(fromIndex - formattedNumberGroups[i].length), nationalSignificantNumber);
}
}
} // The check here makes sure that we haven't mistakenly already used the extension to
// match the last group of the subscriber number. Note the extension cannot have
// formatting in-between digits.
return normalizedCandidate.slice(fromIndex).contains(number.getExtension());
}
//# sourceMappingURL=Leniency.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
/*
import { containsMoreThanOneSlashInNationalNumber } from './Leniency.js'
describe('Leniency', () => {
it('testContainsMoreThanOneSlashInNationalNumber', () => {
// A date should return true.
number.setCountryCode(1)
number.setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY)
containsMoreThanOneSlashInNationalNumber(number, '1/05/2013').should.equal(true)
// Here, the country code source thinks it started with a country calling code, but this is not
// the same as the part before the slash, so it's still true.
number.setCountryCode(274)
number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN)
containsMoreThanOneSlashInNationalNumber(number, '27/4/2013').should.equal(true)
// Now it should be false, because the first slash is after the country calling code.
number.setCountryCode(49)
number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)
containsMoreThanOneSlashInNationalNumber(number, '49/69/2013').should.equal(false)
number.setCountryCode(49)
number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN)
containsMoreThanOneSlashInNationalNumber(number, '+49/69/2013').should.equal(false)
containsMoreThanOneSlashInNationalNumber(number, '+ 49/69/2013').should.equal(false)
containsMoreThanOneSlashInNationalNumber(number, '+ 49/69/20/13').should.equal(true)
// Here, the first group is not assumed to be the country calling code, even though it is the
// same as it, so this should return true.
number.setCountryCode(49)
number.setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY)
containsMoreThanOneSlashInNationalNumber(number, '49/69/2013').should.equal(true)
})
})
*/
"use strict";
//# sourceMappingURL=Leniency.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Leniency.test.js","names":[],"sources":["../../source/findNumbers/Leniency.test.js"],"sourcesContent":["/*\r\nimport { containsMoreThanOneSlashInNationalNumber } from './Leniency.js'\r\n\r\ndescribe('Leniency', () => {\r\n\tit('testContainsMoreThanOneSlashInNationalNumber', () => {\r\n\t\t// A date should return true.\r\n\t\tnumber.setCountryCode(1)\r\n\t\tnumber.setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '1/05/2013').should.equal(true)\r\n\r\n\t\t// Here, the country code source thinks it started with a country calling code, but this is not\r\n\t\t// the same as the part before the slash, so it's still true.\r\n\t\tnumber.setCountryCode(274)\r\n\t\tnumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '27/4/2013').should.equal(true)\r\n\r\n\t\t// Now it should be false, because the first slash is after the country calling code.\r\n\t\tnumber.setCountryCode(49)\r\n\t\tnumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '49/69/2013').should.equal(false)\r\n\r\n\t\tnumber.setCountryCode(49)\r\n\t\tnumber.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '+49/69/2013').should.equal(false)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '+ 49/69/2013').should.equal(false)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '+ 49/69/20/13').should.equal(true)\r\n\r\n\t\t// Here, the first group is not assumed to be the country calling code, even though it is the\r\n\t\t// same as it, so this should return true.\r\n\t\tnumber.setCountryCode(49)\r\n\t\tnumber.setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY)\r\n\t\tcontainsMoreThanOneSlashInNationalNumber(number, '49/69/2013').should.equal(true)\r\n\t})\r\n})\r\n*/"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _LRUCache = _interopRequireDefault(require("./LRUCache.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; }
// A cache for frequently used country-specific regular expressions. Set to 32 to cover ~2-3
// countries being used for the same doc with ~10 patterns for each country. Some pages will have
// a lot more countries in use, but typically fewer numbers for each so expanding the cache for
// that use-case won't have a lot of benefit.
var RegExpCache = /*#__PURE__*/function () {
function RegExpCache(size) {
_classCallCheck(this, RegExpCache);
this.cache = new _LRUCache["default"](size);
}
_createClass(RegExpCache, [{
key: "getPatternForRegExp",
value: function getPatternForRegExp(pattern) {
var regExp = this.cache.get(pattern);
if (!regExp) {
regExp = new RegExp('^' + pattern);
this.cache.put(pattern, regExp);
}
return regExp;
}
}]);
return RegExpCache;
}();
exports["default"] = RegExpCache;
//# sourceMappingURL=RegExpCache.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RegExpCache.js","names":["RegExpCache","size","cache","LRUCache","pattern","regExp","get","RegExp","put"],"sources":["../../source/findNumbers/RegExpCache.js"],"sourcesContent":["import LRUCache from './LRUCache.js'\r\n\r\n// A cache for frequently used country-specific regular expressions. Set to 32 to cover ~2-3\r\n// countries being used for the same doc with ~10 patterns for each country. Some pages will have\r\n// a lot more countries in use, but typically fewer numbers for each so expanding the cache for\r\n// that use-case won't have a lot of benefit.\r\nexport default class RegExpCache {\r\n\tconstructor(size) {\r\n\t\tthis.cache = new LRUCache(size)\r\n\t}\r\n\r\n\tgetPatternForRegExp(pattern) {\r\n\t\tlet regExp = this.cache.get(pattern)\r\n\t\tif (!regExp) {\r\n\t\t\tregExp = new RegExp('^' + pattern)\r\n\t\t\tthis.cache.put(pattern, regExp)\r\n\t\t}\r\n\t\treturn regExp\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;;;;;;;;;AAEA;AACA;AACA;AACA;IACqBA,W;EACpB,qBAAYC,IAAZ,EAAkB;IAAA;;IACjB,KAAKC,KAAL,GAAa,IAAIC,oBAAJ,CAAaF,IAAb,CAAb;EACA;;;;WAED,6BAAoBG,OAApB,EAA6B;MAC5B,IAAIC,MAAM,GAAG,KAAKH,KAAL,CAAWI,GAAX,CAAeF,OAAf,CAAb;;MACA,IAAI,CAACC,MAAL,EAAa;QACZA,MAAM,GAAG,IAAIE,MAAJ,CAAW,MAAMH,OAAjB,CAAT;QACA,KAAKF,KAAL,CAAWM,GAAX,CAAeJ,OAAf,EAAwBC,MAAxB;MACA;;MACD,OAAOA,MAAP;IACA"}

View File

@@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.LEAD_CLASS = void 0;
exports["default"] = isValidCandidate;
var _constants = require("../constants.js");
var _util = require("./util.js");
var _utf = require("./utf-8.js");
// Copy-pasted from `PhoneNumberMatcher.js`.
var OPENING_PARENS = "(\\[\uFF08\uFF3B";
var CLOSING_PARENS = ")\\]\uFF09\uFF3D";
var NON_PARENS = "[^".concat(OPENING_PARENS).concat(CLOSING_PARENS, "]");
var LEAD_CLASS = "[".concat(OPENING_PARENS).concat(_constants.PLUS_CHARS, "]"); // Punctuation that may be at the start of a phone number - brackets and plus signs.
exports.LEAD_CLASS = LEAD_CLASS;
var LEAD_CLASS_LEADING = new RegExp('^' + LEAD_CLASS); // Limit on the number of pairs of brackets in a phone number.
var BRACKET_PAIR_LIMIT = (0, _util.limit)(0, 3);
/**
* Pattern to check that brackets match. Opening brackets should be closed within a phone number.
* This also checks that there is something inside the brackets. Having no brackets at all is also
* fine.
*
* An opening bracket at the beginning may not be closed, but subsequent ones should be. It's
* also possible that the leading bracket was dropped, so we shouldn't be surprised if we see a
* closing bracket first. We limit the sets of brackets in a phone number to four.
*/
var MATCHING_BRACKETS_ENTIRE = new RegExp('^' + "(?:[" + OPENING_PARENS + "])?" + "(?:" + NON_PARENS + "+" + "[" + CLOSING_PARENS + "])?" + NON_PARENS + "+" + "(?:[" + OPENING_PARENS + "]" + NON_PARENS + "+[" + CLOSING_PARENS + "])" + BRACKET_PAIR_LIMIT + NON_PARENS + "*" + '$');
/**
* Matches strings that look like publication pages. Example:
* <pre>Computing Complete Answers to Queries in the Presence of Limited Access Patterns.
* Chen Li. VLDB J. 12(3): 211-227 (2003).</pre>
*
* The string "211-227 (2003)" is not a telephone number.
*/
var PUB_PAGES = /\d{1,5}-+\d{1,5}\s{0,4}\(\d{1,4}/;
function isValidCandidate(candidate, offset, text, leniency) {
// Check the candidate doesn't contain any formatting
// which would indicate that it really isn't a phone number.
if (!MATCHING_BRACKETS_ENTIRE.test(candidate) || PUB_PAGES.test(candidate)) {
return;
} // If leniency is set to VALID or stricter, we also want to skip numbers that are surrounded
// by Latin alphabetic characters, to skip cases like abc8005001234 or 8005001234def.
if (leniency !== 'POSSIBLE') {
// If the candidate is not at the start of the text,
// and does not start with phone-number punctuation,
// check the previous character.
if (offset > 0 && !LEAD_CLASS_LEADING.test(candidate)) {
var previousChar = text[offset - 1]; // We return null if it is a latin letter or an invalid punctuation symbol.
if ((0, _utf.isInvalidPunctuationSymbol)(previousChar) || (0, _utf.isLatinLetter)(previousChar)) {
return false;
}
}
var lastCharIndex = offset + candidate.length;
if (lastCharIndex < text.length) {
var nextChar = text[lastCharIndex];
if ((0, _utf.isInvalidPunctuationSymbol)(nextChar) || (0, _utf.isLatinLetter)(nextChar)) {
return false;
}
}
}
return true;
}
//# sourceMappingURL=isValidCandidate.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = isValidPreCandidate;
// Matches strings that look like dates using "/" as a separator.
// Examples: 3/10/2011, 31/10/96 or 08/31/95.
var SLASH_SEPARATED_DATES = /(?:(?:[0-3]?\d\/[01]?\d)|(?:[01]?\d\/[0-3]?\d))\/(?:[12]\d)?\d{2}/; // Matches timestamps.
// Examples: "2012-01-02 08:00".
// Note that the reg-ex does not include the
// trailing ":\d\d" -- that is covered by TIME_STAMPS_SUFFIX.
var TIME_STAMPS = /[12]\d{3}[-/]?[01]\d[-/]?[0-3]\d +[0-2]\d$/;
var TIME_STAMPS_SUFFIX_LEADING = /^:[0-5]\d/;
function isValidPreCandidate(candidate, offset, text) {
// Skip a match that is more likely to be a date.
if (SLASH_SEPARATED_DATES.test(candidate)) {
return false;
} // Skip potential time-stamps.
if (TIME_STAMPS.test(candidate)) {
var followingText = text.slice(offset + candidate.length);
if (TIME_STAMPS_SUFFIX_LEADING.test(followingText)) {
return false;
}
}
return true;
}
//# sourceMappingURL=isValidPreCandidate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"isValidPreCandidate.js","names":["SLASH_SEPARATED_DATES","TIME_STAMPS","TIME_STAMPS_SUFFIX_LEADING","isValidPreCandidate","candidate","offset","text","test","followingText","slice","length"],"sources":["../../source/findNumbers/isValidPreCandidate.js"],"sourcesContent":["// Matches strings that look like dates using \"/\" as a separator.\r\n// Examples: 3/10/2011, 31/10/96 or 08/31/95.\r\nconst SLASH_SEPARATED_DATES = /(?:(?:[0-3]?\\d\\/[01]?\\d)|(?:[01]?\\d\\/[0-3]?\\d))\\/(?:[12]\\d)?\\d{2}/\r\n\r\n// Matches timestamps.\r\n// Examples: \"2012-01-02 08:00\".\r\n// Note that the reg-ex does not include the\r\n// trailing \":\\d\\d\" -- that is covered by TIME_STAMPS_SUFFIX.\r\nconst TIME_STAMPS = /[12]\\d{3}[-/]?[01]\\d[-/]?[0-3]\\d +[0-2]\\d$/\r\nconst TIME_STAMPS_SUFFIX_LEADING = /^:[0-5]\\d/\r\n\r\nexport default function isValidPreCandidate(candidate, offset, text)\r\n{\r\n\t// Skip a match that is more likely to be a date.\r\n\tif (SLASH_SEPARATED_DATES.test(candidate)) {\r\n\t\treturn false\r\n\t}\r\n\r\n\t// Skip potential time-stamps.\r\n\tif (TIME_STAMPS.test(candidate))\r\n\t{\r\n\t\tconst followingText = text.slice(offset + candidate.length)\r\n\t\tif (TIME_STAMPS_SUFFIX_LEADING.test(followingText)) {\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\r\n\treturn true\r\n}"],"mappings":";;;;;;AAAA;AACA;AACA,IAAMA,qBAAqB,GAAG,mEAA9B,C,CAEA;AACA;AACA;AACA;;AACA,IAAMC,WAAW,GAAG,4CAApB;AACA,IAAMC,0BAA0B,GAAG,WAAnC;;AAEe,SAASC,mBAAT,CAA6BC,SAA7B,EAAwCC,MAAxC,EAAgDC,IAAhD,EACf;EACC;EACA,IAAIN,qBAAqB,CAACO,IAAtB,CAA2BH,SAA3B,CAAJ,EAA2C;IAC1C,OAAO,KAAP;EACA,CAJF,CAMC;;;EACA,IAAIH,WAAW,CAACM,IAAZ,CAAiBH,SAAjB,CAAJ,EACA;IACC,IAAMI,aAAa,GAAGF,IAAI,CAACG,KAAL,CAAWJ,MAAM,GAAGD,SAAS,CAACM,MAA9B,CAAtB;;IACA,IAAIR,0BAA0B,CAACK,IAA3B,CAAgCC,aAAhC,CAAJ,EAAoD;MACnD,OAAO,KAAP;IACA;EACD;;EAED,OAAO,IAAP;AACA"}

View File

@@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = matchPhoneNumberStringAgainstPhoneNumber;
var _parsePhoneNumber = _interopRequireDefault(require("../parsePhoneNumber.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**
* Matches a phone number object against a phone number string.
* @param {string} phoneNumberString
* @param {PhoneNumber} phoneNumber
* @param {object} metadata — Metadata JSON
* @return {'INVALID_NUMBER'|'NO_MATCH'|'SHORT_NSN_MATCH'|'NSN_MATCH'|'EXACT_MATCH'}
*/
function matchPhoneNumberStringAgainstPhoneNumber(phoneNumberString, phoneNumber, metadata) {
// Parse `phoneNumberString`.
var phoneNumberStringContainsCallingCode = true;
var parsedPhoneNumber = (0, _parsePhoneNumber["default"])(phoneNumberString, metadata);
if (!parsedPhoneNumber) {
// If `phoneNumberString` didn't contain a country calling code
// then substitute it with the `phoneNumber`'s country calling code.
phoneNumberStringContainsCallingCode = false;
parsedPhoneNumber = (0, _parsePhoneNumber["default"])(phoneNumberString, {
defaultCallingCode: phoneNumber.countryCallingCode
}, metadata);
}
if (!parsedPhoneNumber) {
return 'INVALID_NUMBER';
} // Check that the extensions match.
if (phoneNumber.ext) {
if (parsedPhoneNumber.ext !== phoneNumber.ext) {
return 'NO_MATCH';
}
} else {
if (parsedPhoneNumber.ext) {
return 'NO_MATCH';
}
} // Check that country calling codes match.
if (phoneNumberStringContainsCallingCode) {
if (phoneNumber.countryCallingCode !== parsedPhoneNumber.countryCallingCode) {
return 'NO_MATCH';
}
} // Check if the whole numbers match.
if (phoneNumber.number === parsedPhoneNumber.number) {
if (phoneNumberStringContainsCallingCode) {
return 'EXACT_MATCH';
} else {
return 'NSN_MATCH';
}
} // Check if one national number is a "suffix" of the other.
if (phoneNumber.nationalNumber.indexOf(parsedPhoneNumber.nationalNumber) === 0 || parsedPhoneNumber.nationalNumber.indexOf(phoneNumber.nationalNumber) === 0) {
// "A SHORT_NSN_MATCH occurs if there is a difference because of the
// presence or absence of an 'Italian leading zero', the presence or
// absence of an extension, or one NSN being a shorter variant of the
// other."
return 'SHORT_NSN_MATCH';
}
return 'NO_MATCH';
}
//# sourceMappingURL=matchPhoneNumberStringAgainstPhoneNumber.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"matchPhoneNumberStringAgainstPhoneNumber.js","names":["matchPhoneNumberStringAgainstPhoneNumber","phoneNumberString","phoneNumber","metadata","phoneNumberStringContainsCallingCode","parsedPhoneNumber","parsePhoneNumber","defaultCallingCode","countryCallingCode","ext","number","nationalNumber","indexOf"],"sources":["../../source/findNumbers/matchPhoneNumberStringAgainstPhoneNumber.js"],"sourcesContent":["import parsePhoneNumber from '../parsePhoneNumber.js'\r\n\r\n/**\r\n * Matches a phone number object against a phone number string.\r\n * @param {string} phoneNumberString\r\n * @param {PhoneNumber} phoneNumber\r\n * @param {object} metadata — Metadata JSON\r\n * @return {'INVALID_NUMBER'|'NO_MATCH'|'SHORT_NSN_MATCH'|'NSN_MATCH'|'EXACT_MATCH'}\r\n */\r\nexport default function matchPhoneNumberStringAgainstPhoneNumber(phoneNumberString, phoneNumber, metadata) {\r\n\t// Parse `phoneNumberString`.\r\n\tlet phoneNumberStringContainsCallingCode = true\r\n\tlet parsedPhoneNumber = parsePhoneNumber(phoneNumberString, metadata)\r\n\tif (!parsedPhoneNumber) {\r\n\t\t// If `phoneNumberString` didn't contain a country calling code\r\n\t\t// then substitute it with the `phoneNumber`'s country calling code.\r\n\t\tphoneNumberStringContainsCallingCode = false\r\n\t\tparsedPhoneNumber = parsePhoneNumber(phoneNumberString, { defaultCallingCode: phoneNumber.countryCallingCode }, metadata)\r\n\t}\r\n\tif (!parsedPhoneNumber) {\r\n\t\treturn 'INVALID_NUMBER'\r\n\t}\r\n\r\n\t// Check that the extensions match.\r\n\tif (phoneNumber.ext) {\r\n\t\tif (parsedPhoneNumber.ext !== phoneNumber.ext) {\r\n\t\t\treturn 'NO_MATCH'\r\n\t\t}\r\n\t} else {\r\n\t\tif (parsedPhoneNumber.ext) {\r\n\t\t\treturn 'NO_MATCH'\r\n\t\t}\r\n\t}\r\n\r\n\t// Check that country calling codes match.\r\n\tif (phoneNumberStringContainsCallingCode) {\r\n\t\tif (phoneNumber.countryCallingCode !== parsedPhoneNumber.countryCallingCode) {\r\n\t\t\treturn 'NO_MATCH'\r\n\t\t}\r\n\t}\r\n\r\n\t// Check if the whole numbers match.\r\n\tif (phoneNumber.number === parsedPhoneNumber.number) {\r\n\t\tif (phoneNumberStringContainsCallingCode) {\r\n\t\t\treturn 'EXACT_MATCH'\r\n\t\t} else {\r\n\t\t\treturn 'NSN_MATCH'\r\n\t\t}\r\n\t}\r\n\r\n\t// Check if one national number is a \"suffix\" of the other.\r\n\tif (\r\n\t\tphoneNumber.nationalNumber.indexOf(parsedPhoneNumber.nationalNumber) === 0 ||\r\n\t\tparsedPhoneNumber.nationalNumber.indexOf(phoneNumber.nationalNumber) === 0\r\n\t) {\r\n\t\t// \"A SHORT_NSN_MATCH occurs if there is a difference because of the\r\n\t\t// presence or absence of an 'Italian leading zero', the presence or\r\n\t\t// absence of an extension, or one NSN being a shorter variant of the\r\n\t\t// other.\"\r\n\t\treturn 'SHORT_NSN_MATCH'\r\n\t}\r\n\r\n\treturn 'NO_MATCH'\r\n}"],"mappings":";;;;;;;AAAA;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,wCAAT,CAAkDC,iBAAlD,EAAqEC,WAArE,EAAkFC,QAAlF,EAA4F;EAC1G;EACA,IAAIC,oCAAoC,GAAG,IAA3C;EACA,IAAIC,iBAAiB,GAAG,IAAAC,4BAAA,EAAiBL,iBAAjB,EAAoCE,QAApC,CAAxB;;EACA,IAAI,CAACE,iBAAL,EAAwB;IACvB;IACA;IACAD,oCAAoC,GAAG,KAAvC;IACAC,iBAAiB,GAAG,IAAAC,4BAAA,EAAiBL,iBAAjB,EAAoC;MAAEM,kBAAkB,EAAEL,WAAW,CAACM;IAAlC,CAApC,EAA4FL,QAA5F,CAApB;EACA;;EACD,IAAI,CAACE,iBAAL,EAAwB;IACvB,OAAO,gBAAP;EACA,CAZyG,CAc1G;;;EACA,IAAIH,WAAW,CAACO,GAAhB,EAAqB;IACpB,IAAIJ,iBAAiB,CAACI,GAAlB,KAA0BP,WAAW,CAACO,GAA1C,EAA+C;MAC9C,OAAO,UAAP;IACA;EACD,CAJD,MAIO;IACN,IAAIJ,iBAAiB,CAACI,GAAtB,EAA2B;MAC1B,OAAO,UAAP;IACA;EACD,CAvByG,CAyB1G;;;EACA,IAAIL,oCAAJ,EAA0C;IACzC,IAAIF,WAAW,CAACM,kBAAZ,KAAmCH,iBAAiB,CAACG,kBAAzD,EAA6E;MAC5E,OAAO,UAAP;IACA;EACD,CA9ByG,CAgC1G;;;EACA,IAAIN,WAAW,CAACQ,MAAZ,KAAuBL,iBAAiB,CAACK,MAA7C,EAAqD;IACpD,IAAIN,oCAAJ,EAA0C;MACzC,OAAO,aAAP;IACA,CAFD,MAEO;MACN,OAAO,WAAP;IACA;EACD,CAvCyG,CAyC1G;;;EACA,IACCF,WAAW,CAACS,cAAZ,CAA2BC,OAA3B,CAAmCP,iBAAiB,CAACM,cAArD,MAAyE,CAAzE,IACAN,iBAAiB,CAACM,cAAlB,CAAiCC,OAAjC,CAAyCV,WAAW,CAACS,cAArD,MAAyE,CAF1E,EAGE;IACD;IACA;IACA;IACA;IACA,OAAO,iBAAP;EACA;;EAED,OAAO,UAAP;AACA"}

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = parsePreCandidate;
var _util = require("./util.js");
// Regular expression of characters typically used to start a second phone number for the purposes
// of parsing. This allows us to strip off parts of the number that are actually the start of
// another number, such as for: (530) 583-6985 x302/x2303 -> the second extension here makes this
// actually two phone numbers, (530) 583-6985 x302 and (530) 583-6985 x2303. We remove the second
// extension so that the first number is parsed correctly.
//
// Matches a slash (\ or /) followed by a space followed by an `x`.
//
var SECOND_NUMBER_START_PATTERN = /[\\/] *x/;
function parsePreCandidate(candidate) {
// Check for extra numbers at the end.
// TODO: This is the place to start when trying to support extraction of multiple phone number
// from split notations (+41 79 123 45 67 / 68).
return (0, _util.trimAfterFirstMatch)(SECOND_NUMBER_START_PATTERN, candidate);
}
//# sourceMappingURL=parsePreCandidate.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parsePreCandidate.js","names":["SECOND_NUMBER_START_PATTERN","parsePreCandidate","candidate","trimAfterFirstMatch"],"sources":["../../source/findNumbers/parsePreCandidate.js"],"sourcesContent":["import { trimAfterFirstMatch } from './util.js'\r\n\r\n// Regular expression of characters typically used to start a second phone number for the purposes\r\n// of parsing. This allows us to strip off parts of the number that are actually the start of\r\n// another number, such as for: (530) 583-6985 x302/x2303 -> the second extension here makes this\r\n// actually two phone numbers, (530) 583-6985 x302 and (530) 583-6985 x2303. We remove the second\r\n// extension so that the first number is parsed correctly.\r\n//\r\n// Matches a slash (\\ or /) followed by a space followed by an `x`.\r\n//\r\nconst SECOND_NUMBER_START_PATTERN = /[\\\\/] *x/\r\n\r\nexport default function parsePreCandidate(candidate)\r\n{\r\n\t// Check for extra numbers at the end.\r\n\t// TODO: This is the place to start when trying to support extraction of multiple phone number\r\n\t// from split notations (+41 79 123 45 67 / 68).\r\n\treturn trimAfterFirstMatch(SECOND_NUMBER_START_PATTERN, candidate)\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMA,2BAA2B,GAAG,UAApC;;AAEe,SAASC,iBAAT,CAA2BC,SAA3B,EACf;EACC;EACA;EACA;EACA,OAAO,IAAAC,yBAAA,EAAoBH,2BAApB,EAAiDE,SAAjD,CAAP;AACA"}

View File

@@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports._pN = exports._pL = exports.PZ = void 0;
exports.isInvalidPunctuationSymbol = isInvalidPunctuationSymbol;
exports.isLatinLetter = isLatinLetter;
exports.pZ = exports.pNd = void 0;
// Javascript doesn't support UTF-8 regular expressions.
// So mimicking them here.
// Copy-pasted from `PhoneNumberMatcher.js`.
/**
* "\p{Z}" is any kind of whitespace or invisible separator ("Separator").
* http://www.regular-expressions.info/unicode.html
* "\P{Z}" is the reverse of "\p{Z}".
* "\p{N}" is any kind of numeric character in any script ("Number").
* "\p{Nd}" is a digit zero through nine in any script except "ideographic scripts" ("Decimal_Digit_Number").
* "\p{Sc}" is a currency symbol ("Currency_Symbol").
* "\p{L}" is any kind of letter from any language ("Letter").
* "\p{Mn}" is "non-spacing mark".
*
* Javascript doesn't support Unicode Regular Expressions
* so substituting it with this explicit set of characters.
*
* https://stackoverflow.com/questions/13210194/javascript-regex-equivalent-of-a-za-z-using-pl
* https://github.com/danielberndt/babel-plugin-utf-8-regex/blob/master/src/transformer.js
*/
var _pZ = " \xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000";
var pZ = "[".concat(_pZ, "]");
exports.pZ = pZ;
var PZ = "[^".concat(_pZ, "]");
exports.PZ = PZ;
var _pN = "0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D66-\u0D75\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19"; // const pN = `[${_pN}]`
exports._pN = _pN;
var _pNd = "0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19";
var pNd = "[".concat(_pNd, "]");
exports.pNd = pNd;
var _pL = "A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC";
exports._pL = _pL;
var pL = "[".concat(_pL, "]");
var pL_regexp = new RegExp(pL);
var _pSc = "$\xA2-\xA5\u058F\u060B\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u17DB\u20A0-\u20B9\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6";
var pSc = "[".concat(_pSc, "]");
var pSc_regexp = new RegExp(pSc);
var _pMn = "\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u08FE\u0900-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2\u09E3\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0CBC\u0CBF\u0CC6\u0CCC\u0CCD\u0CE2\u0CE3\u0D41-\u0D44\u0D4D\u0D62\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1DC0-\u1DE6\u1DFC-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099\u309A\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE26";
var pMn = "[".concat(_pMn, "]");
var pMn_regexp = new RegExp(pMn);
var _InBasic_Latin = "\0-\x7F";
var _InLatin_1_Supplement = "\x80-\xFF";
var _InLatin_Extended_A = "\u0100-\u017F";
var _InLatin_Extended_Additional = "\u1E00-\u1EFF";
var _InLatin_Extended_B = "\u0180-\u024F";
var _InCombining_Diacritical_Marks = "\u0300-\u036F";
var latinLetterRegexp = new RegExp('[' + _InBasic_Latin + _InLatin_1_Supplement + _InLatin_Extended_A + _InLatin_Extended_Additional + _InLatin_Extended_B + _InCombining_Diacritical_Marks + ']');
/**
* Helper method to determine if a character is a Latin-script letter or not.
* For our purposes, combining marks should also return true since we assume
* they have been added to a preceding Latin character.
*/
function isLatinLetter(letter) {
// Combining marks are a subset of non-spacing-mark.
if (!pL_regexp.test(letter) && !pMn_regexp.test(letter)) {
return false;
}
return latinLetterRegexp.test(letter);
}
function isInvalidPunctuationSymbol(character) {
return character === '%' || pSc_regexp.test(character);
}
//# sourceMappingURL=utf-8.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.endsWith = endsWith;
exports.limit = limit;
exports.startsWith = startsWith;
exports.trimAfterFirstMatch = trimAfterFirstMatch;
/** Returns a regular expression quantifier with an upper and lower limit. */
function limit(lower, upper) {
if (lower < 0 || upper <= 0 || upper < lower) {
throw new TypeError();
}
return "{".concat(lower, ",").concat(upper, "}");
}
/**
* Trims away any characters after the first match of {@code pattern} in {@code candidate},
* returning the trimmed version.
*/
function trimAfterFirstMatch(regexp, string) {
var index = string.search(regexp);
if (index >= 0) {
return string.slice(0, index);
}
return string;
}
function startsWith(string, substring) {
return string.indexOf(substring) === 0;
}
function endsWith(string, substring) {
return string.indexOf(substring, string.length - substring.length) === string.length - substring.length;
}
//# sourceMappingURL=util.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"util.js","names":["limit","lower","upper","TypeError","trimAfterFirstMatch","regexp","string","index","search","slice","startsWith","substring","indexOf","endsWith","length"],"sources":["../../source/findNumbers/util.js"],"sourcesContent":["/** Returns a regular expression quantifier with an upper and lower limit. */\r\nexport function limit(lower, upper)\r\n{\r\n\tif ((lower < 0) || (upper <= 0) || (upper < lower)) {\r\n\t\tthrow new TypeError()\r\n\t}\r\n\treturn `{${lower},${upper}}`\r\n}\r\n\r\n/**\r\n * Trims away any characters after the first match of {@code pattern} in {@code candidate},\r\n * returning the trimmed version.\r\n */\r\nexport function trimAfterFirstMatch(regexp, string)\r\n{\r\n\tconst index = string.search(regexp)\r\n\r\n\tif (index >= 0) {\r\n\t\treturn string.slice(0, index)\r\n\t}\r\n\r\n\treturn string\r\n}\r\n\r\nexport function startsWith(string, substring)\r\n{\r\n\treturn string.indexOf(substring) === 0\r\n}\r\n\r\nexport function endsWith(string, substring)\r\n{\r\n\treturn string.indexOf(substring, string.length - substring.length) === string.length - substring.length\r\n}\r\n"],"mappings":";;;;;;;;;;AAAA;AACO,SAASA,KAAT,CAAeC,KAAf,EAAsBC,KAAtB,EACP;EACC,IAAKD,KAAK,GAAG,CAAT,IAAgBC,KAAK,IAAI,CAAzB,IAAgCA,KAAK,GAAGD,KAA5C,EAAoD;IACnD,MAAM,IAAIE,SAAJ,EAAN;EACA;;EACD,kBAAWF,KAAX,cAAoBC,KAApB;AACA;AAED;AACA;AACA;AACA;;;AACO,SAASE,mBAAT,CAA6BC,MAA7B,EAAqCC,MAArC,EACP;EACC,IAAMC,KAAK,GAAGD,MAAM,CAACE,MAAP,CAAcH,MAAd,CAAd;;EAEA,IAAIE,KAAK,IAAI,CAAb,EAAgB;IACf,OAAOD,MAAM,CAACG,KAAP,CAAa,CAAb,EAAgBF,KAAhB,CAAP;EACA;;EAED,OAAOD,MAAP;AACA;;AAEM,SAASI,UAAT,CAAoBJ,MAApB,EAA4BK,SAA5B,EACP;EACC,OAAOL,MAAM,CAACM,OAAP,CAAeD,SAAf,MAA8B,CAArC;AACA;;AAEM,SAASE,QAAT,CAAkBP,MAAlB,EAA0BK,SAA1B,EACP;EACC,OAAOL,MAAM,CAACM,OAAP,CAAeD,SAAf,EAA0BL,MAAM,CAACQ,MAAP,GAAgBH,SAAS,CAACG,MAApD,MAAgER,MAAM,CAACQ,MAAP,GAAgBH,SAAS,CAACG,MAAjG;AACA"}

View File

@@ -0,0 +1,38 @@
"use strict";
var _util = require("./util.js");
describe('findNumbers/util', function () {
it('should generate regexp limit', function () {
var thrower = function thrower() {
return (0, _util.limit)(1, 0);
};
thrower.should["throw"]();
thrower = function thrower() {
return (0, _util.limit)(-1, 1);
};
thrower.should["throw"]();
thrower = function thrower() {
return (0, _util.limit)(0, 0);
};
thrower.should["throw"]();
});
it('should trimAfterFirstMatch', function () {
(0, _util.trimAfterFirstMatch)(/\d/, 'abc123').should.equal('abc');
(0, _util.trimAfterFirstMatch)(/\d/, 'abc').should.equal('abc');
});
it('should determine if a string starts with a substring', function () {
(0, _util.startsWith)('𐍈123', '𐍈').should.equal(true);
(0, _util.startsWith)('1𐍈', '𐍈').should.equal(false);
});
it('should determine if a string ends with a substring', function () {
(0, _util.endsWith)('123𐍈', '𐍈').should.equal(true);
(0, _util.endsWith)('𐍈1', '𐍈').should.equal(false);
});
});
//# sourceMappingURL=util.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"util.test.js","names":["describe","it","thrower","limit","should","trimAfterFirstMatch","equal","startsWith","endsWith"],"sources":["../../source/findNumbers/util.test.js"],"sourcesContent":["import {\r\n\tlimit,\r\n\ttrimAfterFirstMatch,\r\n\tstartsWith,\r\n\tendsWith\r\n} from './util.js'\r\n\r\ndescribe('findNumbers/util', () =>\r\n{\r\n\tit('should generate regexp limit', () =>\r\n\t{\r\n\t\tlet thrower = () => limit(1, 0)\r\n\t\tthrower.should.throw()\r\n\r\n\t\tthrower = () => limit(-1, 1)\r\n\t\tthrower.should.throw()\r\n\r\n\t\tthrower = () => limit(0, 0)\r\n\t\tthrower.should.throw()\r\n\t})\r\n\r\n\tit('should trimAfterFirstMatch', () =>\r\n\t{\r\n\t\ttrimAfterFirstMatch(/\\d/, 'abc123').should.equal('abc')\r\n\t\ttrimAfterFirstMatch(/\\d/, 'abc').should.equal('abc')\r\n\t})\r\n\r\n\tit('should determine if a string starts with a substring', () =>\r\n\t{\r\n\t\tstartsWith('𐍈123', '𐍈').should.equal(true)\r\n\t\tstartsWith('1𐍈', '𐍈').should.equal(false)\r\n\t})\r\n\r\n\tit('should determine if a string ends with a substring', () =>\r\n\t{\r\n\t\tendsWith('123𐍈', '𐍈').should.equal(true)\r\n\t\tendsWith('𐍈1', '𐍈').should.equal(false)\r\n\t})\r\n})"],"mappings":";;AAAA;;AAOAA,QAAQ,CAAC,kBAAD,EAAqB,YAC7B;EACCC,EAAE,CAAC,8BAAD,EAAiC,YACnC;IACC,IAAIC,OAAO,GAAG;MAAA,OAAM,IAAAC,WAAA,EAAM,CAAN,EAAS,CAAT,CAAN;IAAA,CAAd;;IACAD,OAAO,CAACE,MAAR;;IAEAF,OAAO,GAAG;MAAA,OAAM,IAAAC,WAAA,EAAM,CAAC,CAAP,EAAU,CAAV,CAAN;IAAA,CAAV;;IACAD,OAAO,CAACE,MAAR;;IAEAF,OAAO,GAAG;MAAA,OAAM,IAAAC,WAAA,EAAM,CAAN,EAAS,CAAT,CAAN;IAAA,CAAV;;IACAD,OAAO,CAACE,MAAR;EACA,CAVC,CAAF;EAYAH,EAAE,CAAC,4BAAD,EAA+B,YACjC;IACC,IAAAI,yBAAA,EAAoB,IAApB,EAA0B,QAA1B,EAAoCD,MAApC,CAA2CE,KAA3C,CAAiD,KAAjD;IACA,IAAAD,yBAAA,EAAoB,IAApB,EAA0B,KAA1B,EAAiCD,MAAjC,CAAwCE,KAAxC,CAA8C,KAA9C;EACA,CAJC,CAAF;EAMAL,EAAE,CAAC,sDAAD,EAAyD,YAC3D;IACC,IAAAM,gBAAA,EAAW,OAAX,EAAoB,IAApB,EAA0BH,MAA1B,CAAiCE,KAAjC,CAAuC,IAAvC;IACA,IAAAC,gBAAA,EAAW,KAAX,EAAkB,IAAlB,EAAwBH,MAAxB,CAA+BE,KAA/B,CAAqC,KAArC;EACA,CAJC,CAAF;EAMAL,EAAE,CAAC,oDAAD,EAAuD,YACzD;IACC,IAAAO,cAAA,EAAS,OAAT,EAAkB,IAAlB,EAAwBJ,MAAxB,CAA+BE,KAA/B,CAAqC,IAArC;IACA,IAAAE,cAAA,EAAS,KAAT,EAAgB,IAAhB,EAAsBJ,MAAtB,CAA6BE,KAA7B,CAAmC,KAAnC;EACA,CAJC,CAAF;AAKA,CA/BO,CAAR"}

View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = findPhoneNumbersInText;
var _PhoneNumberMatcher = _interopRequireDefault(require("./PhoneNumberMatcher.js"));
var _normalizeArguments2 = _interopRequireDefault(require("./normalizeArguments.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
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; }
function findPhoneNumbersInText() {
var _normalizeArguments = (0, _normalizeArguments2["default"])(arguments),
text = _normalizeArguments.text,
options = _normalizeArguments.options,
metadata = _normalizeArguments.metadata;
var matcher = new _PhoneNumberMatcher["default"](text, _objectSpread(_objectSpread({}, options), {}, {
v2: true
}), metadata);
var results = [];
while (matcher.hasNext()) {
results.push(matcher.next());
}
return results;
}
//# sourceMappingURL=findPhoneNumbersInText.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"findPhoneNumbersInText.js","names":["findPhoneNumbersInText","normalizeArguments","arguments","text","options","metadata","matcher","PhoneNumberMatcher","v2","results","hasNext","push","next"],"sources":["../source/findPhoneNumbersInText.js"],"sourcesContent":["import PhoneNumberMatcher from './PhoneNumberMatcher.js'\r\nimport normalizeArguments from './normalizeArguments.js'\r\n\r\nexport default function findPhoneNumbersInText() {\r\n\tconst { text, options, metadata } = normalizeArguments(arguments)\r\n\tconst matcher = new PhoneNumberMatcher(text, { ...options, v2: true }, metadata)\r\n\tconst results = []\r\n\twhile (matcher.hasNext()) {\r\n\t\tresults.push(matcher.next())\r\n\t}\r\n\treturn results\r\n}"],"mappings":";;;;;;;AAAA;;AACA;;;;;;;;;;AAEe,SAASA,sBAAT,GAAkC;EAChD,0BAAoC,IAAAC,+BAAA,EAAmBC,SAAnB,CAApC;EAAA,IAAQC,IAAR,uBAAQA,IAAR;EAAA,IAAcC,OAAd,uBAAcA,OAAd;EAAA,IAAuBC,QAAvB,uBAAuBA,QAAvB;;EACA,IAAMC,OAAO,GAAG,IAAIC,8BAAJ,CAAuBJ,IAAvB,kCAAkCC,OAAlC;IAA2CI,EAAE,EAAE;EAA/C,IAAuDH,QAAvD,CAAhB;EACA,IAAMI,OAAO,GAAG,EAAhB;;EACA,OAAOH,OAAO,CAACI,OAAR,EAAP,EAA0B;IACzBD,OAAO,CAACE,IAAR,CAAaL,OAAO,CAACM,IAAR,EAAb;EACA;;EACD,OAAOH,OAAP;AACA"}

View File

@@ -0,0 +1,291 @@
"use strict";
var _findPhoneNumbersInText = _interopRequireDefault(require("./findPhoneNumbersInText.js"));
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
var _metadataMax = _interopRequireDefault(require("../metadata.max.json"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function findPhoneNumbersInTextWithResults(input, options, metadata) {
var results = (0, _findPhoneNumbersInText["default"])(input, options, metadata);
return results.map(function (result) {
var startsAt = result.startsAt,
endsAt = result.endsAt,
number = result.number;
var data = {
phone: number.nationalNumber,
startsAt: startsAt,
endsAt: endsAt
};
if (number.country) {
data.country = number.country;
}
if (number.ext) {
data.ext = number.ext;
}
return data;
});
}
describe('findPhoneNumbersInText', function () {
it('should find phone numbers in text (with default country)', function () {
(0, _findPhoneNumbersInText["default"])('+7 (800) 555-35-35', 'US', _metadataMin["default"])[0].number.number.should.equal('+78005553535');
});
it('should find phone numbers in text (with default country in options)', function () {
(0, _findPhoneNumbersInText["default"])('+7 (800) 555-35-35', {
defaultCountry: 'US'
}, _metadataMin["default"])[0].number.number.should.equal('+78005553535');
});
it('should find phone numbers in text (with default country and options)', function () {
(0, _findPhoneNumbersInText["default"])('+7 (800) 555-35-35', 'US', {}, _metadataMin["default"])[0].number.number.should.equal('+78005553535');
});
it('should find phone numbers in text (without default country, with options)', function () {
(0, _findPhoneNumbersInText["default"])('+7 (800) 555-35-35', undefined, {}, _metadataMin["default"])[0].number.number.should.equal('+78005553535');
});
it('should find phone numbers in text (with default country, without options)', function () {
(0, _findPhoneNumbersInText["default"])('+7 (800) 555-35-35', 'US', undefined, _metadataMin["default"])[0].number.number.should.equal('+78005553535');
});
it('should find phone numbers in text (with empty default country)', function () {
(0, _findPhoneNumbersInText["default"])('+7 (800) 555-35-35', undefined, _metadataMin["default"])[0].number.number.should.equal('+78005553535');
});
it('should find phone numbers in text', function () {
var NUMBERS = ['+78005553535', '+12133734253'];
var results = (0, _findPhoneNumbersInText["default"])('The number is +7 (800) 555-35-35 and not (213) 373-4253 as written in the document.', _metadataMin["default"]);
var i = 0;
while (i < results.length) {
results[i].number.number.should.equal(NUMBERS[i]);
i++;
}
});
it('should find phone numbers in text (default country calling code)', function () {
var NUMBERS = ['+870773111632'];
var results = (0, _findPhoneNumbersInText["default"])('The number is 773 111 632', {
defaultCallingCode: '870'
}, _metadataMin["default"]);
var i = 0;
while (i < results.length) {
results[i].number.number.should.equal(NUMBERS[i]);
i++;
}
});
it('should find numbers', function () {
findPhoneNumbersInTextWithResults('2133734253', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([{
phone: '2133734253',
country: 'US',
startsAt: 0,
endsAt: 10
}]);
findPhoneNumbersInTextWithResults('(213) 373-4253', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([{
phone: '2133734253',
country: 'US',
startsAt: 0,
endsAt: 14
}]);
findPhoneNumbersInTextWithResults('The number is +7 (800) 555-35-35 and not (213) 373-4253 as written in the document.', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
startsAt: 14,
endsAt: 32
}, {
phone: '2133734253',
country: 'US',
startsAt: 41,
endsAt: 55
}]); // Opening parenthesis issue.
// https://github.com/catamphetamine/libphonenumber-js/issues/252
findPhoneNumbersInTextWithResults('The number is +7 (800) 555-35-35 and not (213) 373-4253 (that\'s not even in the same country!) as written in the document.', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
startsAt: 14,
endsAt: 32
}, {
phone: '2133734253',
country: 'US',
startsAt: 41,
endsAt: 55
}]); // No default country.
findPhoneNumbersInTextWithResults('The number is +7 (800) 555-35-35 as written in the document.', undefined, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
startsAt: 14,
endsAt: 32
}]); // Passing `options` and default country.
findPhoneNumbersInTextWithResults('The number is +7 (800) 555-35-35 as written in the document.', {
defaultCountry: 'US',
leniency: 'VALID'
}, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
startsAt: 14,
endsAt: 32
}]); // Passing `options`.
findPhoneNumbersInTextWithResults('The number is +7 (800) 555-35-35 as written in the document.', {
leniency: 'VALID'
}, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
startsAt: 14,
endsAt: 32
}]); // Not a phone number and a phone number.
findPhoneNumbersInTextWithResults('Digits 12 are not a number, but +7 (800) 555-35-35 is.', {
leniency: 'VALID'
}, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
startsAt: 32,
endsAt: 50
}]); // Phone number extension.
findPhoneNumbersInTextWithResults('Date 02/17/2018 is not a number, but +7 (800) 555-35-35 ext. 123 is.', {
leniency: 'VALID'
}, _metadataMin["default"]).should.deep.equal([{
phone: '8005553535',
country: 'RU',
ext: '123',
startsAt: 37,
endsAt: 64
}]);
});
it('should find numbers (v2)', function () {
var phoneNumbers = (0, _findPhoneNumbersInText["default"])('The number is +7 (800) 555-35-35 ext. 1234 and not (213) 373-4253 as written in the document.', {
defaultCountry: 'US',
v2: true
}, _metadataMin["default"]);
phoneNumbers.length.should.equal(2);
phoneNumbers[0].startsAt.should.equal(14);
phoneNumbers[0].endsAt.should.equal(42);
phoneNumbers[0].number.number.should.equal('+78005553535');
phoneNumbers[0].number.nationalNumber.should.equal('8005553535');
phoneNumbers[0].number.country.should.equal('RU');
phoneNumbers[0].number.countryCallingCode.should.equal('7');
phoneNumbers[0].number.ext.should.equal('1234');
phoneNumbers[1].startsAt.should.equal(51);
phoneNumbers[1].endsAt.should.equal(65);
phoneNumbers[1].number.number.should.equal('+12133734253');
phoneNumbers[1].number.nationalNumber.should.equal('2133734253');
phoneNumbers[1].number.country.should.equal('US');
phoneNumbers[1].number.countryCallingCode.should.equal('1');
});
it('shouldn\'t find non-valid numbers', function () {
// Not a valid phone number for US.
findPhoneNumbersInTextWithResults('1111111111', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([]);
});
it('should find non-European digits', function () {
// E.g. in Iraq they don't write `+442323234` but rather `+٤٤٢٣٢٣٢٣٤`.
findPhoneNumbersInTextWithResults('العَرَبِيَّة‎ +٤٤٣٣٣٣٣٣٣٣٣٣عَرَبِيّ‎', undefined, _metadataMin["default"]).should.deep.equal([{
country: 'GB',
phone: '3333333333',
startsAt: 14,
endsAt: 27
}]);
});
it('should work in edge cases', function () {
var thrower; // No input
findPhoneNumbersInTextWithResults('', undefined, _metadataMin["default"]).should.deep.equal([]); // // No country metadata for this `require` country code
// thrower = () => findPhoneNumbersInTextWithResults('123', { defaultCountry: 'ZZ' }, metadata)
// thrower.should.throw('Unknown country')
// Numerical `value`
thrower = function thrower() {
return findPhoneNumbersInTextWithResults(2141111111, {
defaultCountry: 'US'
});
};
thrower.should["throw"]('A text for parsing must be a string.'); // // No metadata
// thrower = () => findPhoneNumbersInTextWithResults('')
// thrower.should.throw('`metadata` argument not passed')
// No metadata, no default country, no phone numbers.
findPhoneNumbersInTextWithResults('').should.deep.equal([]);
});
it('should find international numbers when passed a non-existent default country', function () {
var numbers = (0, _findPhoneNumbersInText["default"])('Phone: +7 (800) 555 35 35. National: 8 (800) 555-55-55', {
defaultCountry: 'XX',
v2: true
}, _metadataMin["default"]);
numbers.length.should.equal(1);
numbers[0].number.nationalNumber.should.equal('8005553535');
});
it('shouldn\'t find phone numbers which are not phone numbers', function () {
// A timestamp.
findPhoneNumbersInTextWithResults('2012-01-02 08:00', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([]); // A valid number (not a complete timestamp).
findPhoneNumbersInTextWithResults('2012-01-02 08', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([{
country: 'US',
phone: '2012010208',
startsAt: 0,
endsAt: 13
}]); // Invalid parens.
findPhoneNumbersInTextWithResults('213(3734253', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([]); // Letters after phone number.
findPhoneNumbersInTextWithResults('2133734253a', {
defaultCountry: 'US'
}, _metadataMin["default"]).should.deep.equal([]); // Valid phone (same as the one found in the UUID below).
findPhoneNumbersInTextWithResults('The phone number is 231354125.', {
defaultCountry: 'FR'
}, _metadataMin["default"]).should.deep.equal([{
country: 'FR',
phone: '231354125',
startsAt: 20,
endsAt: 29
}]); // Not a phone number (part of a UUID).
// Should parse in `{ extended: true }` mode.
var possibleNumbers = findPhoneNumbersInTextWithResults('The UUID is CA801c26f98cd16e231354125ad046e40b.', {
defaultCountry: 'FR',
extended: true
}, _metadataMin["default"]);
possibleNumbers.length.should.equal(1);
possibleNumbers[0].country.should.equal('FR');
possibleNumbers[0].phone.should.equal('231354125'); // Not a phone number (part of a UUID).
// Shouldn't parse by default.
findPhoneNumbersInTextWithResults('The UUID is CA801c26f98cd16e231354125ad046e40b.', {
defaultCountry: 'FR'
}, _metadataMin["default"]).should.deep.equal([]);
}); // https://gitlab.com/catamphetamine/libphonenumber-js/-/merge_requests/4
it('should return correct `startsAt` and `endsAt` when matching "inner" candidates in a could-be-a-candidate substring', function () {
findPhoneNumbersInTextWithResults('39945926 77200596 16533084', {
defaultCountry: 'ID'
}, _metadataMax["default"]).should.deep.equal([{
country: 'ID',
phone: '77200596',
startsAt: 9,
endsAt: 17
}]);
});
});
//# sourceMappingURL=findPhoneNumbersInText.test.js.map

File diff suppressed because one or more lines are too long

207
backend/node_modules/libphonenumber-js/build/format.js generated vendored Normal file
View File

@@ -0,0 +1,207 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.chooseFormatForNumber = chooseFormatForNumber;
exports["default"] = formatNumber;
var _matchesEntirely = _interopRequireDefault(require("./helpers/matchesEntirely.js"));
var _formatNationalNumberUsingFormat = _interopRequireDefault(require("./helpers/formatNationalNumberUsingFormat.js"));
var _metadata = _interopRequireWildcard(require("./metadata.js"));
var _getIddPrefix = _interopRequireDefault(require("./helpers/getIddPrefix.js"));
var _RFC = require("./helpers/RFC3966.js");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
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; }
var DEFAULT_OPTIONS = {
formatExtension: function formatExtension(formattedNumber, extension, metadata) {
return "".concat(formattedNumber).concat(metadata.ext()).concat(extension);
}
};
/**
* Formats a phone number.
*
* format(phoneNumberInstance, 'INTERNATIONAL', { ..., v2: true }, metadata)
* format(phoneNumberInstance, 'NATIONAL', { ..., v2: true }, metadata)
*
* format({ phone: '8005553535', country: 'RU' }, 'INTERNATIONAL', { ... }, metadata)
* format({ phone: '8005553535', country: 'RU' }, 'NATIONAL', undefined, metadata)
*
* @param {object|PhoneNumber} input — If `options.v2: true` flag is passed, the `input` should be a `PhoneNumber` instance. Otherwise, it should be an object of shape `{ phone: '...', country: '...' }`.
* @param {string} format
* @param {object} [options]
* @param {object} metadata
* @return {string}
*/
function formatNumber(input, format, options, metadata) {
// Apply default options.
if (options) {
options = _objectSpread(_objectSpread({}, DEFAULT_OPTIONS), options);
} else {
options = DEFAULT_OPTIONS;
}
metadata = new _metadata["default"](metadata);
if (input.country && input.country !== '001') {
// Validate `input.country`.
if (!metadata.hasCountry(input.country)) {
throw new Error("Unknown country: ".concat(input.country));
}
metadata.country(input.country);
} else if (input.countryCallingCode) {
metadata.selectNumberingPlan(input.countryCallingCode);
} else return input.phone || '';
var countryCallingCode = metadata.countryCallingCode();
var nationalNumber = options.v2 ? input.nationalNumber : input.phone; // This variable should have been declared inside `case`s
// but Babel has a bug and it says "duplicate variable declaration".
var number;
switch (format) {
case 'NATIONAL':
// Legacy argument support.
// (`{ country: ..., phone: '' }`)
if (!nationalNumber) {
return '';
}
number = formatNationalNumber(nationalNumber, input.carrierCode, 'NATIONAL', metadata, options);
return addExtension(number, input.ext, metadata, options.formatExtension);
case 'INTERNATIONAL':
// Legacy argument support.
// (`{ country: ..., phone: '' }`)
if (!nationalNumber) {
return "+".concat(countryCallingCode);
}
number = formatNationalNumber(nationalNumber, null, 'INTERNATIONAL', metadata, options);
number = "+".concat(countryCallingCode, " ").concat(number);
return addExtension(number, input.ext, metadata, options.formatExtension);
case 'E.164':
// `E.164` doesn't define "phone number extensions".
return "+".concat(countryCallingCode).concat(nationalNumber);
case 'RFC3966':
return (0, _RFC.formatRFC3966)({
number: "+".concat(countryCallingCode).concat(nationalNumber),
ext: input.ext
});
// For reference, here's Google's IDD formatter:
// https://github.com/google/libphonenumber/blob/32719cf74e68796788d1ca45abc85dcdc63ba5b9/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java#L1546
// Not saying that this IDD formatter replicates it 1:1, but it seems to work.
// Who would even need to format phone numbers in IDD format anyway?
case 'IDD':
if (!options.fromCountry) {
return; // throw new Error('`fromCountry` option not passed for IDD-prefixed formatting.')
}
var formattedNumber = formatIDD(nationalNumber, input.carrierCode, countryCallingCode, options.fromCountry, metadata);
return addExtension(formattedNumber, input.ext, metadata, options.formatExtension);
default:
throw new Error("Unknown \"format\" argument passed to \"formatNumber()\": \"".concat(format, "\""));
}
}
function formatNationalNumber(number, carrierCode, formatAs, metadata, options) {
var format = chooseFormatForNumber(metadata.formats(), number);
if (!format) {
return number;
}
return (0, _formatNationalNumberUsingFormat["default"])(number, format, {
useInternationalFormat: formatAs === 'INTERNATIONAL',
withNationalPrefix: format.nationalPrefixIsOptionalWhenFormattingInNationalFormat() && options && options.nationalPrefix === false ? false : true,
carrierCode: carrierCode,
metadata: metadata
});
}
function chooseFormatForNumber(availableFormats, nationalNnumber) {
for (var _iterator = _createForOfIteratorHelperLoose(availableFormats), _step; !(_step = _iterator()).done;) {
var format = _step.value;
// Validate leading digits.
// The test case for "else path" could be found by searching for
// "format.leadingDigitsPatterns().length === 0".
if (format.leadingDigitsPatterns().length > 0) {
// The last leading_digits_pattern is used here, as it is the most detailed
var lastLeadingDigitsPattern = format.leadingDigitsPatterns()[format.leadingDigitsPatterns().length - 1]; // If leading digits don't match then move on to the next phone number format
if (nationalNnumber.search(lastLeadingDigitsPattern) !== 0) {
continue;
}
} // Check that the national number matches the phone number format regular expression
if ((0, _matchesEntirely["default"])(nationalNnumber, format.pattern())) {
return format;
}
}
}
function addExtension(formattedNumber, ext, metadata, formatExtension) {
return ext ? formatExtension(formattedNumber, ext, metadata) : formattedNumber;
}
function formatIDD(nationalNumber, carrierCode, countryCallingCode, fromCountry, metadata) {
var fromCountryCallingCode = (0, _metadata.getCountryCallingCode)(fromCountry, metadata.metadata); // When calling within the same country calling code.
if (fromCountryCallingCode === countryCallingCode) {
var formattedNumber = formatNationalNumber(nationalNumber, carrierCode, 'NATIONAL', metadata); // For NANPA regions, return the national format for these regions
// but prefix it with the country calling code.
if (countryCallingCode === '1') {
return countryCallingCode + ' ' + formattedNumber;
} // If regions share a country calling code, the country calling code need
// not be dialled. This also applies when dialling within a region, so this
// if clause covers both these cases. Technically this is the case for
// dialling from La Reunion to other overseas departments of France (French
// Guiana, Martinique, Guadeloupe), but not vice versa - so we don't cover
// this edge case for now and for those cases return the version including
// country calling code. Details here:
// http://www.petitfute.com/voyage/225-info-pratiques-reunion
//
return formattedNumber;
}
var iddPrefix = (0, _getIddPrefix["default"])(fromCountry, undefined, metadata.metadata);
if (iddPrefix) {
return "".concat(iddPrefix, " ").concat(countryCallingCode, " ").concat(formatNationalNumber(nationalNumber, null, 'INTERNATIONAL', metadata));
}
}
//# sourceMappingURL=format.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,326 @@
"use strict";
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
var _format = _interopRequireDefault(require("./format.js"));
var _parsePhoneNumber = _interopRequireDefault(require("./parsePhoneNumber.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
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; }
function formatNumber() {
var v2;
for (var _len = arguments.length, parameters = new Array(_len), _key = 0; _key < _len; _key++) {
parameters[_key] = arguments[_key];
}
if (parameters.length < 1) {
// `input` parameter.
parameters.push(undefined);
} else {
// Convert string `input` to a `PhoneNumber` instance.
if (typeof parameters[0] === 'string') {
v2 = true;
parameters[0] = (0, _parsePhoneNumber["default"])(parameters[0], _objectSpread(_objectSpread({}, parameters[2]), {}, {
extract: false
}), _metadataMin["default"]);
}
}
if (parameters.length < 2) {
// `format` parameter.
parameters.push(undefined);
}
if (parameters.length < 3) {
// `options` parameter.
parameters.push(undefined);
} // Set `v2` flag.
parameters[2] = _objectSpread({
v2: v2
}, parameters[2]); // Add `metadata` parameter.
parameters.push(_metadataMin["default"]); // Call the function.
return _format["default"].apply(this, parameters);
}
describe('format', function () {
it('should work with the first argument being a E.164 number', function () {
formatNumber('+12133734253', 'NATIONAL').should.equal('(213) 373-4253');
formatNumber('+12133734253', 'INTERNATIONAL').should.equal('+1 213 373 4253'); // Invalid number.
formatNumber('+12111111111', 'NATIONAL').should.equal('(211) 111-1111'); // Formatting invalid E.164 numbers.
formatNumber('+11111', 'INTERNATIONAL').should.equal('+1 1111');
formatNumber('+11111', 'NATIONAL').should.equal('1111');
});
it('should work with the first object argument expanded', function () {
formatNumber('2133734253', 'NATIONAL', {
defaultCountry: 'US'
}).should.equal('(213) 373-4253');
formatNumber('2133734253', 'INTERNATIONAL', {
defaultCountry: 'US'
}).should.equal('+1 213 373 4253');
});
it('should format using formats with no leading digits (`format.leadingDigitsPatterns().length === 0`)', function () {
formatNumber({
phone: '12345678901',
countryCallingCode: 888
}, 'INTERNATIONAL').should.equal('+888 123 456 78901');
});
it('should sort out the arguments', function () {
var options = {
formatExtension: function formatExtension(number, extension) {
return "".concat(number, " \u0434\u043E\u0431. ").concat(extension);
}
};
formatNumber({
phone: '8005553535',
country: 'RU',
ext: '123'
}, 'NATIONAL', options).should.equal('8 (800) 555-35-35 доб. 123'); // Parse number from string.
formatNumber('+78005553535', 'NATIONAL', options).should.equal('8 (800) 555-35-35');
formatNumber('8005553535', 'NATIONAL', _objectSpread(_objectSpread({}, options), {}, {
defaultCountry: 'RU'
})).should.equal('8 (800) 555-35-35');
});
it('should format with national prefix when specifically instructed', function () {
// With national prefix.
formatNumber('88005553535', 'NATIONAL', {
defaultCountry: 'RU'
}).should.equal('8 (800) 555-35-35'); // Without national prefix via an explicitly set option.
formatNumber('88005553535', 'NATIONAL', {
nationalPrefix: false,
defaultCountry: 'RU'
}).should.equal('800 555-35-35');
});
it('should format valid phone numbers', function () {
// Switzerland
formatNumber({
country: 'CH',
phone: '446681800'
}, 'INTERNATIONAL').should.equal('+41 44 668 18 00');
formatNumber({
country: 'CH',
phone: '446681800'
}, 'E.164').should.equal('+41446681800');
formatNumber({
country: 'CH',
phone: '446681800'
}, 'RFC3966').should.equal('tel:+41446681800');
formatNumber({
country: 'CH',
phone: '446681800'
}, 'NATIONAL').should.equal('044 668 18 00'); // France
formatNumber({
country: 'FR',
phone: '169454850'
}, 'NATIONAL').should.equal('01 69 45 48 50'); // Kazakhstan
formatNumber('+7 702 211 1111', 'NATIONAL').should.deep.equal('8 (702) 211 1111');
});
it('should format national numbers with national prefix even if it\'s optional', function () {
// Russia
formatNumber({
country: 'RU',
phone: '9991234567'
}, 'NATIONAL').should.equal('8 (999) 123-45-67');
});
it('should work in edge cases', function () {
var thrower; // // No phone number
// formatNumber('', 'INTERNATIONAL', { defaultCountry: 'RU' }).should.equal('')
// formatNumber('', 'NATIONAL', { defaultCountry: 'RU' }).should.equal('')
formatNumber({
country: 'RU',
phone: ''
}, 'INTERNATIONAL').should.equal('+7');
formatNumber({
country: 'RU',
phone: ''
}, 'NATIONAL').should.equal(''); // No suitable format
formatNumber('+121337342530', 'NATIONAL', {
defaultCountry: 'US'
}).should.equal('21337342530'); // No suitable format (leading digits mismatch)
formatNumber('28199999', 'NATIONAL', {
defaultCountry: 'AD'
}).should.equal('28199999'); // // Numerical `value`
// thrower = () => formatNumber(89150000000, 'NATIONAL', { defaultCountry: 'RU' })
// thrower.should.throw('A phone number must either be a string or an object of shape { phone, [country] }.')
// // No metadata for country
// expect(() => formatNumber('+121337342530', 'NATIONAL', { defaultCountry: 'USA' })).to.throw('Unknown country')
// expect(() => formatNumber('21337342530', 'NATIONAL', { defaultCountry: 'USA' })).to.throw('Unknown country')
// No format type
thrower = function thrower() {
return formatNumber('+123');
};
thrower.should["throw"]('Unknown "format" argument'); // Unknown format type
thrower = function thrower() {
return formatNumber('123', 'Gay', {
defaultCountry: 'US'
});
};
thrower.should["throw"]('Unknown "format" argument'); // // No metadata
// thrower = () => _formatNumber('123', 'E.164', { defaultCountry: 'RU' })
// thrower.should.throw('`metadata`')
// No formats
formatNumber('012345', 'NATIONAL', {
defaultCountry: 'AC'
}).should.equal('012345'); // No `fromCountry` for `IDD` format.
expect(formatNumber('+78005553535', 'IDD')).to.be.undefined; // `fromCountry` has no default IDD prefix.
expect(formatNumber('+78005553535', 'IDD', {
fromCountry: 'BO'
})).to.be.undefined; // No such country.
expect(function () {
return formatNumber({
phone: '123',
country: 'USA'
}, 'NATIONAL');
}).to["throw"]('Unknown country');
});
it('should format phone number extensions', function () {
// National
formatNumber({
country: 'US',
phone: '2133734253',
ext: '123'
}, 'NATIONAL').should.equal('(213) 373-4253 ext. 123'); // International
formatNumber({
country: 'US',
phone: '2133734253',
ext: '123'
}, 'INTERNATIONAL').should.equal('+1 213 373 4253 ext. 123'); // International
formatNumber({
country: 'US',
phone: '2133734253',
ext: '123'
}, 'INTERNATIONAL').should.equal('+1 213 373 4253 ext. 123'); // E.164
formatNumber({
country: 'US',
phone: '2133734253',
ext: '123'
}, 'E.164').should.equal('+12133734253'); // RFC3966
formatNumber({
country: 'US',
phone: '2133734253',
ext: '123'
}, 'RFC3966').should.equal('tel:+12133734253;ext=123'); // Custom ext prefix.
formatNumber({
country: 'GB',
phone: '7912345678',
ext: '123'
}, 'INTERNATIONAL').should.equal('+44 7912 345678 x123');
});
it('should work with Argentina numbers', function () {
// The same mobile number is written differently
// in different formats in Argentina:
// `9` gets prepended in international format.
formatNumber({
country: 'AR',
phone: '3435551212'
}, 'INTERNATIONAL').should.equal('+54 3435 55 1212');
formatNumber({
country: 'AR',
phone: '3435551212'
}, 'NATIONAL').should.equal('03435 55-1212');
});
it('should work with Mexico numbers', function () {
// Fixed line.
formatNumber({
country: 'MX',
phone: '4499780001'
}, 'INTERNATIONAL').should.equal('+52 449 978 0001');
formatNumber({
country: 'MX',
phone: '4499780001'
}, 'NATIONAL').should.equal('449 978 0001'); // or '(449)978-0001'.
// Mobile.
// `1` is prepended before area code to mobile numbers in international format.
formatNumber({
country: 'MX',
phone: '3312345678'
}, 'INTERNATIONAL').should.equal('+52 33 1234 5678');
formatNumber({
country: 'MX',
phone: '3312345678'
}, 'NATIONAL').should.equal('33 1234 5678'); // or '045 33 1234-5678'.
});
it('should format possible numbers', function () {
formatNumber({
countryCallingCode: '7',
phone: '1111111111'
}, 'E.164').should.equal('+71111111111');
formatNumber({
countryCallingCode: '7',
phone: '1111111111'
}, 'NATIONAL').should.equal('1111111111');
formatNumber({
countryCallingCode: '7',
phone: '1111111111'
}, 'INTERNATIONAL').should.equal('+7 1111111111');
});
it('should format IDD-prefixed number', function () {
// No `fromCountry`.
expect(formatNumber('+78005553535', 'IDD')).to.be.undefined; // No default IDD prefix.
expect(formatNumber('+78005553535', 'IDD', {
fromCountry: 'BO'
})).to.be.undefined; // Same country calling code.
formatNumber('+12133734253', 'IDD', {
fromCountry: 'CA',
humanReadable: true
}).should.equal('1 (213) 373-4253');
formatNumber('+78005553535', 'IDD', {
fromCountry: 'KZ',
humanReadable: true
}).should.equal('8 (800) 555-35-35'); // formatNumber('+78005553535', 'IDD', { fromCountry: 'US' }).should.equal('01178005553535')
formatNumber('+78005553535', 'IDD', {
fromCountry: 'US',
humanReadable: true
}).should.equal('011 7 800 555 35 35');
});
it('should format non-geographic numbering plan phone numbers', function () {
// https://github.com/catamphetamine/libphonenumber-js/issues/323
formatNumber('+870773111632', 'INTERNATIONAL').should.equal('+870 773 111 632');
formatNumber('+870773111632', 'NATIONAL').should.equal('773 111 632');
});
it('should use the default IDD prefix when formatting a phone number', function () {
// Testing preferred international prefixes with ~ are supported.
// ("~" designates waiting on a line until proceeding with the input).
formatNumber('+390236618300', 'IDD', {
fromCountry: 'BY'
}).should.equal('8~10 39 02 3661 8300');
});
});
//# sourceMappingURL=format.test.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = formatIncompletePhoneNumber;
var _AsYouType = _interopRequireDefault(require("./AsYouType.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**
* Formats a (possibly incomplete) phone number.
* The phone number can be either in E.164 format
* or in a form of national number digits.
* @param {string} value - A possibly incomplete phone number. Either in E.164 format or in a form of national number digits.
* @param {string|object} [optionsOrDefaultCountry] - A two-letter ("ISO 3166-1 alpha-2") country code, or an object of shape `{ defaultCountry?: string, defaultCallingCode?: string }`.
* @return {string} Formatted (possibly incomplete) phone number.
*/
function formatIncompletePhoneNumber(value, optionsOrDefaultCountry, metadata) {
if (!metadata) {
metadata = optionsOrDefaultCountry;
optionsOrDefaultCountry = undefined;
}
return new _AsYouType["default"](optionsOrDefaultCountry, metadata).input(value);
}
//# sourceMappingURL=formatIncompletePhoneNumber.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"formatIncompletePhoneNumber.js","names":["formatIncompletePhoneNumber","value","optionsOrDefaultCountry","metadata","undefined","AsYouType","input"],"sources":["../source/formatIncompletePhoneNumber.js"],"sourcesContent":["import AsYouType from './AsYouType.js'\r\n\r\n/**\r\n * Formats a (possibly incomplete) phone number.\r\n * The phone number can be either in E.164 format\r\n * or in a form of national number digits.\r\n * @param {string} value - A possibly incomplete phone number. Either in E.164 format or in a form of national number digits.\r\n * @param {string|object} [optionsOrDefaultCountry] - A two-letter (\"ISO 3166-1 alpha-2\") country code, or an object of shape `{ defaultCountry?: string, defaultCallingCode?: string }`.\r\n * @return {string} Formatted (possibly incomplete) phone number.\r\n */\r\nexport default function formatIncompletePhoneNumber(value, optionsOrDefaultCountry, metadata) {\r\n\tif (!metadata) {\r\n\t\tmetadata = optionsOrDefaultCountry\r\n\t\toptionsOrDefaultCountry = undefined\r\n\t}\r\n\treturn new AsYouType(optionsOrDefaultCountry, metadata).input(value)\r\n}"],"mappings":";;;;;;;AAAA;;;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,2BAAT,CAAqCC,KAArC,EAA4CC,uBAA5C,EAAqEC,QAArE,EAA+E;EAC7F,IAAI,CAACA,QAAL,EAAe;IACdA,QAAQ,GAAGD,uBAAX;IACAA,uBAAuB,GAAGE,SAA1B;EACA;;EACD,OAAO,IAAIC,qBAAJ,CAAcH,uBAAd,EAAuCC,QAAvC,EAAiDG,KAAjD,CAAuDL,KAAvD,CAAP;AACA"}

View File

@@ -0,0 +1,30 @@
"use strict";
var _formatIncompletePhoneNumber = _interopRequireDefault(require("./formatIncompletePhoneNumber.js"));
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('formatIncompletePhoneNumber', function () {
it('should format parsed input value', function () {
var result; // National input.
(0, _formatIncompletePhoneNumber["default"])('880055535', 'RU', _metadataMin["default"]).should.equal('8 (800) 555-35'); // International input, no country.
(0, _formatIncompletePhoneNumber["default"])('+780055535', null, _metadataMin["default"]).should.equal('+7 800 555 35'); // International input, no country argument.
(0, _formatIncompletePhoneNumber["default"])('+780055535', _metadataMin["default"]).should.equal('+7 800 555 35'); // International input, with country.
(0, _formatIncompletePhoneNumber["default"])('+780055535', 'RU', _metadataMin["default"]).should.equal('+7 800 555 35');
});
it('should support an object argument', function () {
(0, _formatIncompletePhoneNumber["default"])('880055535', {
defaultCountry: 'RU'
}, _metadataMin["default"]).should.equal('8 (800) 555-35');
(0, _formatIncompletePhoneNumber["default"])('880055535', {
defaultCallingCode: '7'
}, _metadataMin["default"]).should.equal('8 (800) 555-35');
});
});
//# sourceMappingURL=formatIncompletePhoneNumber.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"formatIncompletePhoneNumber.test.js","names":["describe","it","result","formatIncompletePhoneNumber","metadata","should","equal","defaultCountry","defaultCallingCode"],"sources":["../source/formatIncompletePhoneNumber.test.js"],"sourcesContent":["import formatIncompletePhoneNumber from './formatIncompletePhoneNumber.js'\r\n\r\nimport metadata from '../metadata.min.json' assert { type: 'json' }\r\n\r\ndescribe('formatIncompletePhoneNumber', () => {\r\n\tit('should format parsed input value', () => {\r\n\t\tlet result\r\n\r\n\t\t// National input.\r\n\t\tformatIncompletePhoneNumber('880055535', 'RU', metadata).should.equal('8 (800) 555-35')\r\n\r\n\t\t// International input, no country.\r\n\t\tformatIncompletePhoneNumber('+780055535', null, metadata).should.equal('+7 800 555 35')\r\n\r\n\t\t// International input, no country argument.\r\n\t\tformatIncompletePhoneNumber('+780055535', metadata).should.equal('+7 800 555 35')\r\n\r\n\t\t// International input, with country.\r\n\t\tformatIncompletePhoneNumber('+780055535', 'RU', metadata).should.equal('+7 800 555 35')\r\n\t})\r\n\r\n\tit('should support an object argument', () => {\r\n\t\tformatIncompletePhoneNumber('880055535', { defaultCountry: 'RU' }, metadata).should.equal('8 (800) 555-35')\r\n\t\tformatIncompletePhoneNumber('880055535', { defaultCallingCode: '7' }, metadata).should.equal('8 (800) 555-35')\r\n\t})\r\n})"],"mappings":";;AAAA;;AAEA;;;;AAEAA,QAAQ,CAAC,6BAAD,EAAgC,YAAM;EAC7CC,EAAE,CAAC,kCAAD,EAAqC,YAAM;IAC5C,IAAIC,MAAJ,CAD4C,CAG5C;;IACA,IAAAC,uCAAA,EAA4B,WAA5B,EAAyC,IAAzC,EAA+CC,uBAA/C,EAAyDC,MAAzD,CAAgEC,KAAhE,CAAsE,gBAAtE,EAJ4C,CAM5C;;IACA,IAAAH,uCAAA,EAA4B,YAA5B,EAA0C,IAA1C,EAAgDC,uBAAhD,EAA0DC,MAA1D,CAAiEC,KAAjE,CAAuE,eAAvE,EAP4C,CAS5C;;IACA,IAAAH,uCAAA,EAA4B,YAA5B,EAA0CC,uBAA1C,EAAoDC,MAApD,CAA2DC,KAA3D,CAAiE,eAAjE,EAV4C,CAY5C;;IACA,IAAAH,uCAAA,EAA4B,YAA5B,EAA0C,IAA1C,EAAgDC,uBAAhD,EAA0DC,MAA1D,CAAiEC,KAAjE,CAAuE,eAAvE;EACA,CAdC,CAAF;EAgBAL,EAAE,CAAC,mCAAD,EAAsC,YAAM;IAC7C,IAAAE,uCAAA,EAA4B,WAA5B,EAAyC;MAAEI,cAAc,EAAE;IAAlB,CAAzC,EAAmEH,uBAAnE,EAA6EC,MAA7E,CAAoFC,KAApF,CAA0F,gBAA1F;IACA,IAAAH,uCAAA,EAA4B,WAA5B,EAAyC;MAAEK,kBAAkB,EAAE;IAAtB,CAAzC,EAAsEJ,uBAAtE,EAAgFC,MAAhF,CAAuFC,KAAvF,CAA6F,gBAA7F;EACA,CAHC,CAAF;AAIA,CArBO,CAAR"}

View File

@@ -0,0 +1,197 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = _default;
var _metadata = _interopRequireDefault(require("./metadata.js"));
var _format = _interopRequireDefault(require("./format.js"));
var _getNumberType = _interopRequireDefault(require("./helpers/getNumberType.js"));
var _checkNumberLength = _interopRequireDefault(require("./helpers/checkNumberLength.js"));
var _getCountryCallingCode = _interopRequireDefault(require("./getCountryCallingCode.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// This function is copy-pasted from
// https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js
// It hasn't been tested. It's not currently exported.
// Carriers codes aren't part of this library.
// Send a PR if you want to add them.
var REGION_CODE_FOR_NON_GEO_ENTITY = '001';
/**
* Returns a number formatted in such a way that it can be dialed from a mobile
* phone in a specific region. If the number cannot be reached from the region
* (e.g. some countries block toll-free numbers from being called outside of the
* country), the method returns an empty string.
*
* @param {object} number - a `parse()`d phone number to be formatted.
* @param {string} from_country - the region where the call is being placed.
* @param {boolean} with_formatting - whether the number should be returned with
* formatting symbols, such as spaces and dashes.
* @return {string}
*/
function _default(number, from_country, with_formatting, metadata) {
metadata = new _metadata["default"](metadata); // Validate `from_country`.
if (!metadata.hasCountry(from_country)) {
throw new Error("Unknown country: ".concat(from_country));
} // Not using the extension, as that part cannot normally be dialed
// together with the main number.
number = {
phone: number.phone,
country: number.country
};
var number_type = (0, _getNumberType["default"])(number, undefined, metadata.metadata);
var is_valid_number = number_type === number;
var formatted_number;
if (country === from_country) {
var is_fixed_line_or_mobile = number_type === 'FIXED_LINE' || number_type === 'MOBILE' || number_type === 'FIXED_LINE_OR_MOBILE'; // Carrier codes may be needed in some countries. We handle this here.
if (country == 'BR' && is_fixed_line_or_mobile) {
formatted_number = carrierCode ? formatNationalNumberWithPreferredCarrierCode(number) : // Brazilian fixed line and mobile numbers need to be dialed with a
// carrier code when called within Brazil. Without that, most of the
// carriers won't connect the call. Because of that, we return an
// empty string here.
'';
} else if ((0, _getCountryCallingCode["default"])(country, metadata.metadata) === '1') {
// For NANPA countries, we output international format for numbers that
// can be dialed internationally, since that always works, except for
// numbers which might potentially be short numbers, which are always
// dialled in national format.
// Select country for `checkNumberLength()`.
metadata.country(country);
if (can_be_internationally_dialled(number) && (0, _checkNumberLength["default"])(number.phone, metadata) !== 'TOO_SHORT') {
formatted_number = (0, _format["default"])(number, 'INTERNATIONAL', metadata.metadata);
} else {
formatted_number = (0, _format["default"])(number, 'NATIONAL', metadata.metadata);
}
} else {
// For non-geographic countries, Mexican and Chilean fixed line and
// mobile numbers, we output international format for numbers that can be
// dialed internationally, as that always works.
if ((country === REGION_CODE_FOR_NON_GEO_ENTITY || // MX fixed line and mobile numbers should always be formatted in
// international format, even when dialed within MX. For national
// format to work, a carrier code needs to be used, and the correct
// carrier code depends on if the caller and callee are from the
// same local area. It is trickier to get that to work correctly than
// using international format, which is tested to work fine on all
// carriers.
//
// CL fixed line numbers need the national prefix when dialing in the
// national format, but don't have it when used for display. The
// reverse is true for mobile numbers. As a result, we output them in
// the international format to make it work.
//
// UZ mobile and fixed-line numbers have to be formatted in
// international format or prefixed with special codes like 03, 04
// (for fixed-line) and 05 (for mobile) for dialling successfully
// from mobile devices. As we do not have complete information on
// special codes and to be consistent with formatting across all
// phone types we return the number in international format here.
//
(country === 'MX' || country === 'CL' || country == 'UZ') && is_fixed_line_or_mobile) && can_be_internationally_dialled(number)) {
formatted_number = (0, _format["default"])(number, 'INTERNATIONAL');
} else {
formatted_number = (0, _format["default"])(number, 'NATIONAL');
}
}
} else if (is_valid_number && can_be_internationally_dialled(number)) {
// We assume that short numbers are not diallable from outside their region,
// so if a number is not a valid regular length phone number, we treat it as
// if it cannot be internationally dialled.
return with_formatting ? (0, _format["default"])(number, 'INTERNATIONAL', metadata.metadata) : (0, _format["default"])(number, 'E.164', metadata.metadata);
}
if (!with_formatting) {
return diallable_chars(formatted_number);
}
return formatted_number;
}
function can_be_internationally_dialled(number) {
return true;
}
/**
* A map that contains characters that are essential when dialling. That means
* any of the characters in this map must not be removed from a number when
* dialling, otherwise the call will not reach the intended destination.
*/
var DIALLABLE_CHARACTERS = {
'0': '0',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'+': '+',
'*': '*',
'#': '#'
};
function diallable_chars(formatted_number) {
var result = '';
var i = 0;
while (i < formatted_number.length) {
var character = formatted_number[i];
if (DIALLABLE_CHARACTERS[character]) {
result += character;
}
i++;
}
return result;
}
function getPreferredDomesticCarrierCodeOrDefault() {
throw new Error('carrier codes are not part of this library');
}
function formatNationalNumberWithCarrierCode() {
throw new Error('carrier codes are not part of this library');
}
/**
* Formats a phone number in national format for dialing using the carrier as
* specified in the preferred_domestic_carrier_code field of the PhoneNumber
* object passed in. If that is missing, use the {@code fallbackCarrierCode}
* passed in instead. If there is no {@code preferred_domestic_carrier_code},
* and the {@code fallbackCarrierCode} contains an empty string, return the
* number in national format without any carrier code.
*
* <p>Use {@link #formatNationalNumberWithCarrierCode} instead if the carrier
* code passed in should take precedence over the number's
* {@code preferred_domestic_carrier_code} when formatting.
*
* @param {i18n.phonenumbers.PhoneNumber} number the phone number to be
* formatted.
* @param {string} fallbackCarrierCode the carrier selection code to be used, if
* none is found in the phone number itself.
* @return {string} the formatted phone number in national format for dialing
* using the number's preferred_domestic_carrier_code, or the
* {@code fallbackCarrierCode} passed in if none is found.
*/
function formatNationalNumberWithPreferredCarrierCode(number) {
return formatNationalNumberWithCarrierCode(number, carrierCode);
}
//# sourceMappingURL=formatPhoneNumberForMobileDialing.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
// Google's tests:
// https://github.com/googlei18n/libphonenumber/blob/597983dc4d56ed7e5337a8e74316dc7a3d02d794/javascript/i18n/phonenumbers/phonenumberutil_test.js
// import metadata from '../metadata.min.json' assert { type: 'json' }
// import formatPhoneNumberForMobileDialing from './formatPhoneNumberForMobileDialing.js'
// describe('formatPhoneNumberForMobileDialing', () =>
// {
// it('should format for mobile dialing', () =>
// {
// formatPhoneNumberForMobileDialing({ phone: '8005553535', country: 'RU' }, 'US', true, metadata).should.equal('+7 800 555 3535')
// formatPhoneNumberForMobileDialing({ phone: '8005553535', country: 'RU' }, 'US', false, metadata).should.equal('+78005553535')
// formatPhoneNumberForMobileDialing({ phone: '8005553535', country: 'RU' }, 'RU', false, metadata).should.equal('8005553535')
// })
// })
"use strict";
//# sourceMappingURL=formatPhoneNumberForMobileDialing.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"formatPhoneNumberForMobileDialing.test.js","names":[],"sources":["../source/formatPhoneNumberForMobileDialing.test.js"],"sourcesContent":["// Google's tests:\r\n// https://github.com/googlei18n/libphonenumber/blob/597983dc4d56ed7e5337a8e74316dc7a3d02d794/javascript/i18n/phonenumbers/phonenumberutil_test.js\r\n\r\n// import metadata from '../metadata.min.json' assert { type: 'json' }\r\n\r\n// import formatPhoneNumberForMobileDialing from './formatPhoneNumberForMobileDialing.js'\r\n\r\n// describe('formatPhoneNumberForMobileDialing', () =>\r\n// {\r\n// \tit('should format for mobile dialing', () =>\r\n// \t{\r\n// \t\tformatPhoneNumberForMobileDialing({ phone: '8005553535', country: 'RU' }, 'US', true, metadata).should.equal('+7 800 555 3535')\r\n// \t\tformatPhoneNumberForMobileDialing({ phone: '8005553535', country: 'RU' }, 'US', false, metadata).should.equal('+78005553535')\r\n// \t\tformatPhoneNumberForMobileDialing({ phone: '8005553535', country: 'RU' }, 'RU', false, metadata).should.equal('8005553535')\r\n// \t})\r\n// })"],"mappings":"AAAA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA"}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = getCountries;
var _metadata = _interopRequireDefault(require("./metadata.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function getCountries(metadata) {
return new _metadata["default"](metadata).getCountries();
}
//# sourceMappingURL=getCountries.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getCountries.js","names":["getCountries","metadata","Metadata"],"sources":["../source/getCountries.js"],"sourcesContent":["import Metadata from './metadata.js'\r\n\r\nexport default function getCountries(metadata) {\r\n\treturn new Metadata(metadata).getCountries()\r\n}"],"mappings":";;;;;;;AAAA;;;;AAEe,SAASA,YAAT,CAAsBC,QAAtB,EAAgC;EAC9C,OAAO,IAAIC,oBAAJ,CAAaD,QAAb,EAAuBD,YAAvB,EAAP;AACA"}

View File

@@ -0,0 +1,14 @@
"use strict";
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
var _getCountries = _interopRequireDefault(require("./getCountries.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('getCountries', function () {
it('should get countries list', function () {
expect((0, _getCountries["default"])(_metadataMin["default"]).indexOf('RU') > 0).to.be["true"];
});
});
//# sourceMappingURL=getCountries.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getCountries.test.js","names":["describe","it","expect","getCountries","metadata","indexOf","to","be"],"sources":["../source/getCountries.test.js"],"sourcesContent":["import metadata from '../metadata.min.json' assert { type: 'json' }\r\n\r\nimport getCountries from './getCountries.js'\r\n\r\ndescribe('getCountries', () => {\r\n\tit('should get countries list', () => {\r\n\t\texpect(getCountries(metadata).indexOf('RU') > 0).to.be.true;\r\n\t})\r\n})"],"mappings":";;AAAA;;AAEA;;;;AAEAA,QAAQ,CAAC,cAAD,EAAiB,YAAM;EAC9BC,EAAE,CAAC,2BAAD,EAA8B,YAAM;IACrCC,MAAM,CAAC,IAAAC,wBAAA,EAAaC,uBAAb,EAAuBC,OAAvB,CAA+B,IAA/B,IAAuC,CAAxC,CAAN,CAAiDC,EAAjD,CAAoDC,EAApD;EACA,CAFC,CAAF;AAGA,CAJO,CAAR"}

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function get() {
return _metadata.getCountryCallingCode;
}
});
var _metadata = require("./metadata.js");
//# sourceMappingURL=getCountryCallingCode.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getCountryCallingCode.js","names":[],"sources":["../source/getCountryCallingCode.js"],"sourcesContent":["// Deprecated. Import from 'metadata.js' directly instead.\r\nexport { getCountryCallingCode as default } from './metadata.js'"],"mappings":";;;;;;;;;;;;AACA"}

View File

@@ -0,0 +1,19 @@
"use strict";
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
var _getCountryCallingCode = _interopRequireDefault(require("./getCountryCallingCode.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('getCountryCallingCode', function () {
it('should get country calling code', function () {
(0, _getCountryCallingCode["default"])('US', _metadataMin["default"]).should.equal('1');
});
it('should throw if country is unknown', function () {
expect(function () {
return (0, _getCountryCallingCode["default"])('ZZ', _metadataMin["default"]);
}).to["throw"]('Unknown country: ZZ');
});
});
//# sourceMappingURL=getCountryCallingCode.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getCountryCallingCode.test.js","names":["describe","it","getCountryCallingCode","metadata","should","equal","expect","to"],"sources":["../source/getCountryCallingCode.test.js"],"sourcesContent":["import metadata from '../metadata.min.json' assert { type: 'json' }\r\n\r\nimport getCountryCallingCode from './getCountryCallingCode.js'\r\n\r\ndescribe('getCountryCallingCode', () => {\r\n\tit('should get country calling code', () => {\r\n\t\tgetCountryCallingCode('US', metadata).should.equal('1')\r\n\t})\r\n\r\n\tit('should throw if country is unknown', () => {\r\n\t\texpect(() => getCountryCallingCode('ZZ', metadata)).to.throw('Unknown country: ZZ')\r\n\t})\r\n})"],"mappings":";;AAAA;;AAEA;;;;AAEAA,QAAQ,CAAC,uBAAD,EAA0B,YAAM;EACvCC,EAAE,CAAC,iCAAD,EAAoC,YAAM;IAC3C,IAAAC,iCAAA,EAAsB,IAAtB,EAA4BC,uBAA5B,EAAsCC,MAAtC,CAA6CC,KAA7C,CAAmD,GAAnD;EACA,CAFC,CAAF;EAIAJ,EAAE,CAAC,oCAAD,EAAuC,YAAM;IAC9CK,MAAM,CAAC;MAAA,OAAM,IAAAJ,iCAAA,EAAsB,IAAtB,EAA4BC,uBAA5B,CAAN;IAAA,CAAD,CAAN,CAAoDI,EAApD,UAA6D,qBAA7D;EACA,CAFC,CAAF;AAGA,CARO,CAAR"}

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = getExampleNumber;
var _PhoneNumber = _interopRequireDefault(require("./PhoneNumber.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function getExampleNumber(country, examples, metadata) {
if (examples[country]) {
return new _PhoneNumber["default"](country, examples[country], metadata);
}
}
//# sourceMappingURL=getExampleNumber.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getExampleNumber.js","names":["getExampleNumber","country","examples","metadata","PhoneNumber"],"sources":["../source/getExampleNumber.js"],"sourcesContent":["import PhoneNumber from './PhoneNumber.js'\r\n\r\nexport default function getExampleNumber(country, examples, metadata) {\r\n\tif (examples[country]) {\r\n\t\treturn new PhoneNumber(country, examples[country], metadata)\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;;;AAEe,SAASA,gBAAT,CAA0BC,OAA1B,EAAmCC,QAAnC,EAA6CC,QAA7C,EAAuD;EACrE,IAAID,QAAQ,CAACD,OAAD,CAAZ,EAAuB;IACtB,OAAO,IAAIG,uBAAJ,CAAgBH,OAAhB,EAAyBC,QAAQ,CAACD,OAAD,CAAjC,EAA4CE,QAA5C,CAAP;EACA;AACD"}

View File

@@ -0,0 +1,23 @@
"use strict";
var _examplesMobile = _interopRequireDefault(require("../examples.mobile.json"));
var _metadataMin = _interopRequireDefault(require("../metadata.min.json"));
var _getExampleNumber = _interopRequireDefault(require("./getExampleNumber.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
describe('getExampleNumber', function () {
it('should get an example number', function () {
var phoneNumber = (0, _getExampleNumber["default"])('RU', _examplesMobile["default"], _metadataMin["default"]);
phoneNumber.nationalNumber.should.equal('9123456789');
phoneNumber.number.should.equal('+79123456789');
phoneNumber.countryCallingCode.should.equal('7');
phoneNumber.country.should.equal('RU');
});
it('should handle a non-existing country', function () {
expect((0, _getExampleNumber["default"])('XX', _examplesMobile["default"], _metadataMin["default"])).to.be.undefined;
});
});
//# sourceMappingURL=getExampleNumber.test.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getExampleNumber.test.js","names":["describe","it","phoneNumber","getExampleNumber","examples","metadata","nationalNumber","should","equal","number","countryCallingCode","country","expect","to","be","undefined"],"sources":["../source/getExampleNumber.test.js"],"sourcesContent":["import examples from '../examples.mobile.json' assert { type: 'json' }\r\nimport metadata from '../metadata.min.json' assert { type: 'json' }\r\nimport getExampleNumber from './getExampleNumber.js'\r\n\r\ndescribe('getExampleNumber', () => {\r\n\tit('should get an example number', () => {\r\n\t\tconst phoneNumber = getExampleNumber('RU', examples, metadata)\r\n\t\tphoneNumber.nationalNumber.should.equal('9123456789')\r\n\t\tphoneNumber.number.should.equal('+79123456789')\r\n\t\tphoneNumber.countryCallingCode.should.equal('7')\r\n\t\tphoneNumber.country.should.equal('RU')\r\n\t})\r\n\r\n\tit('should handle a non-existing country', () => {\r\n\t\texpect(getExampleNumber('XX', examples, metadata)).to.be.undefined\r\n\t})\r\n})"],"mappings":";;AAAA;;AACA;;AACA;;;;AAEAA,QAAQ,CAAC,kBAAD,EAAqB,YAAM;EAClCC,EAAE,CAAC,8BAAD,EAAiC,YAAM;IACxC,IAAMC,WAAW,GAAG,IAAAC,4BAAA,EAAiB,IAAjB,EAAuBC,0BAAvB,EAAiCC,uBAAjC,CAApB;IACAH,WAAW,CAACI,cAAZ,CAA2BC,MAA3B,CAAkCC,KAAlC,CAAwC,YAAxC;IACAN,WAAW,CAACO,MAAZ,CAAmBF,MAAnB,CAA0BC,KAA1B,CAAgC,cAAhC;IACAN,WAAW,CAACQ,kBAAZ,CAA+BH,MAA/B,CAAsCC,KAAtC,CAA4C,GAA5C;IACAN,WAAW,CAACS,OAAZ,CAAoBJ,MAApB,CAA2BC,KAA3B,CAAiC,IAAjC;EACA,CANC,CAAF;EAQAP,EAAE,CAAC,sCAAD,EAAyC,YAAM;IAChDW,MAAM,CAAC,IAAAT,4BAAA,EAAiB,IAAjB,EAAuBC,0BAAvB,EAAiCC,uBAAjC,CAAD,CAAN,CAAmDQ,EAAnD,CAAsDC,EAAtD,CAAyDC,SAAzD;EACA,CAFC,CAAF;AAGA,CAZO,CAAR"}

View File

@@ -0,0 +1,102 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.formatRFC3966 = formatRFC3966;
exports.parseRFC3966 = parseRFC3966;
var _isViablePhoneNumber = _interopRequireDefault(require("./isViablePhoneNumber.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
// https://www.ietf.org/rfc/rfc3966.txt
/**
* @param {string} text - Phone URI (RFC 3966).
* @return {object} `{ ?number, ?ext }`.
*/
function parseRFC3966(text) {
var number;
var ext; // Replace "tel:" with "tel=" for parsing convenience.
text = text.replace(/^tel:/, 'tel=');
for (var _iterator = _createForOfIteratorHelperLoose(text.split(';')), _step; !(_step = _iterator()).done;) {
var part = _step.value;
var _part$split = part.split('='),
_part$split2 = _slicedToArray(_part$split, 2),
name = _part$split2[0],
value = _part$split2[1];
switch (name) {
case 'tel':
number = value;
break;
case 'ext':
ext = value;
break;
case 'phone-context':
// Only "country contexts" are supported.
// "Domain contexts" are ignored.
if (value[0] === '+') {
number = value + number;
}
break;
}
} // If the phone number is not viable, then abort.
if (!(0, _isViablePhoneNumber["default"])(number)) {
return {};
}
var result = {
number: number
};
if (ext) {
result.ext = ext;
}
return result;
}
/**
* @param {object} - `{ ?number, ?extension }`.
* @return {string} Phone URI (RFC 3966).
*/
function formatRFC3966(_ref) {
var number = _ref.number,
ext = _ref.ext;
if (!number) {
return '';
}
if (number[0] !== '+') {
throw new Error("\"formatRFC3966()\" expects \"number\" to be in E.164 format.");
}
return "tel:".concat(number).concat(ext ? ';ext=' + ext : '');
}
//# sourceMappingURL=RFC3966.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RFC3966.js","names":["parseRFC3966","text","number","ext","replace","split","part","name","value","isViablePhoneNumber","result","formatRFC3966","Error"],"sources":["../../source/helpers/RFC3966.js"],"sourcesContent":["import isViablePhoneNumber from './isViablePhoneNumber.js'\r\n\r\n// https://www.ietf.org/rfc/rfc3966.txt\r\n\r\n/**\r\n * @param {string} text - Phone URI (RFC 3966).\r\n * @return {object} `{ ?number, ?ext }`.\r\n */\r\nexport function parseRFC3966(text) {\r\n\tlet number\r\n\tlet ext\r\n\r\n\t// Replace \"tel:\" with \"tel=\" for parsing convenience.\r\n\ttext = text.replace(/^tel:/, 'tel=')\r\n\r\n\tfor (const part of text.split(';')) {\r\n\t\tconst [name, value] = part.split('=')\r\n\t\tswitch (name) {\r\n\t\t\tcase 'tel':\r\n\t\t\t\tnumber = value\r\n\t\t\t\tbreak\r\n\t\t\tcase 'ext':\r\n\t\t\t\text = value\r\n\t\t\t\tbreak\r\n\t\t\tcase 'phone-context':\r\n\t\t\t\t// Only \"country contexts\" are supported.\r\n\t\t\t\t// \"Domain contexts\" are ignored.\r\n\t\t\t\tif (value[0] === '+') {\r\n\t\t\t\t\tnumber = value + number\r\n\t\t\t\t}\r\n\t\t\t\tbreak\r\n\t\t}\r\n\t}\r\n\r\n\t// If the phone number is not viable, then abort.\r\n\tif (!isViablePhoneNumber(number)) {\r\n\t\treturn {}\r\n\t}\r\n\r\n\tconst result = { number }\r\n\tif (ext) {\r\n\t\tresult.ext = ext\r\n\t}\r\n\treturn result\r\n}\r\n\r\n/**\r\n * @param {object} - `{ ?number, ?extension }`.\r\n * @return {string} Phone URI (RFC 3966).\r\n */\r\nexport function formatRFC3966({ number, ext }) {\r\n\tif (!number) {\r\n\t\treturn ''\r\n\t}\r\n\tif (number[0] !== '+') {\r\n\t\tthrow new Error(`\"formatRFC3966()\" expects \"number\" to be in E.164 format.`)\r\n\t}\r\n\treturn `tel:${number}${ext ? ';ext=' + ext : ''}`\r\n}"],"mappings":";;;;;;;;AAAA;;;;;;;;;;;;;;;;;;AAEA;;AAEA;AACA;AACA;AACA;AACO,SAASA,YAAT,CAAsBC,IAAtB,EAA4B;EAClC,IAAIC,MAAJ;EACA,IAAIC,GAAJ,CAFkC,CAIlC;;EACAF,IAAI,GAAGA,IAAI,CAACG,OAAL,CAAa,OAAb,EAAsB,MAAtB,CAAP;;EAEA,qDAAmBH,IAAI,CAACI,KAAL,CAAW,GAAX,CAAnB,wCAAoC;IAAA,IAAzBC,IAAyB;;IACnC,kBAAsBA,IAAI,CAACD,KAAL,CAAW,GAAX,CAAtB;IAAA;IAAA,IAAOE,IAAP;IAAA,IAAaC,KAAb;;IACA,QAAQD,IAAR;MACC,KAAK,KAAL;QACCL,MAAM,GAAGM,KAAT;QACA;;MACD,KAAK,KAAL;QACCL,GAAG,GAAGK,KAAN;QACA;;MACD,KAAK,eAAL;QACC;QACA;QACA,IAAIA,KAAK,CAAC,CAAD,CAAL,KAAa,GAAjB,EAAsB;UACrBN,MAAM,GAAGM,KAAK,GAAGN,MAAjB;QACA;;QACD;IAbF;EAeA,CAxBiC,CA0BlC;;;EACA,IAAI,CAAC,IAAAO,+BAAA,EAAoBP,MAApB,CAAL,EAAkC;IACjC,OAAO,EAAP;EACA;;EAED,IAAMQ,MAAM,GAAG;IAAER,MAAM,EAANA;EAAF,CAAf;;EACA,IAAIC,GAAJ,EAAS;IACRO,MAAM,CAACP,GAAP,GAAaA,GAAb;EACA;;EACD,OAAOO,MAAP;AACA;AAED;AACA;AACA;AACA;;;AACO,SAASC,aAAT,OAAwC;EAAA,IAAfT,MAAe,QAAfA,MAAe;EAAA,IAAPC,GAAO,QAAPA,GAAO;;EAC9C,IAAI,CAACD,MAAL,EAAa;IACZ,OAAO,EAAP;EACA;;EACD,IAAIA,MAAM,CAAC,CAAD,CAAN,KAAc,GAAlB,EAAuB;IACtB,MAAM,IAAIU,KAAJ,iEAAN;EACA;;EACD,qBAAcV,MAAd,SAAuBC,GAAG,GAAG,UAAUA,GAAb,GAAmB,EAA7C;AACA"}

Some files were not shown because too many files have changed in this diff Show More