An open API service indexing awesome lists of open source software.

https://github.com/grantila/awesome-phonenumber

Google's libphonenumber pre-compiled with the closure compiler
https://github.com/grantila/awesome-phonenumber

List: awesome-phonenumber

libphonenumber phone-number

Last synced: 23 days ago
JSON representation

Google's libphonenumber pre-compiled with the closure compiler

Awesome Lists containing this project

README

        

[![npm version][npm-image]][npm-url]
[![downloads][downloads-image]][npm-url]
[![build status][build-image]][build-url]
[![minzipped size][bundlephobia-image]][bundlephobia-url]
[![Dependency count][depcount-image]][npm-url]

# Awesome phonenumber parser

This library is a pre-compiled version of Google's `libphonenumber`, with a slightly simpler interface. It has a minimal footprint - is by far the smallest libphonenumber-based library available on npmjs, and has no dependencies.

Unlike libphonenumber, it includes a `findNumbers( )` function to find phone numbers in text.

TypeScript typings are provided within the package.

Uses libphonenumber v9.0.0

### Versions

- v3:
- Changed API (although with backwards compatible ABI)
- Added ESM export
- v4:
- Changed API to be much cleaner
- No constructor
- No functions on returned object
- No errors being thrown
- Not backwards compatible, although like v3 except:
- The second argument to `parsePhoneNumber` is an object
- E.g. `{ regionCode: 'SE' }` instead of a region code string
- The return value is like `toJSON( )` on v3
- v5:
- Dropped Node 12 support
- v6:
- Dropped Node 16 support
- v7:
- Added `findNumbers( )` feature, to find phone numbers in text
- Added support for _short_ numbers

## Comparison with other libraries

Since this library is pre-compiled, it doesn't depend on the closure compiler, and needs not load it on start. This makes the library faster and saves you a lot of space. It also means this library is trivial to use in any `webpack` project (or using any other means to run in the browser).

Among all the popular phone number using Google's `libphonenumber` (or mimicing it), only this one, `google-libphonenumber` and `libphonenumber-js` have decent README's with examples. *This may have changed since first doing these benchmarks*.

A library should be quick to load (`require()`), quick to parse first time and all consecutive times. It shouldn't bloat your `node_modules`, and it should have a small memory footprint, if possible.

The following is the result of a test program which loads the library, then parses a phone number, and then once again. It's called 100 times for each library and the mean values are shown here. Parsing a phone number first time might be slower because of initially compiling/optimizing regular expressions and whatnot. Parsing a phone number a second time will show the speed of likely all future parsing within that process.

Action | awesome-phonenumber
7.2.0
(lib 8.13.47) | google-libphonenumber
3.2.38
(lib 8.13.42) | libphonenumber-js
1.11.9
(lib -)
------------------------- | ------------------- | --------------------- | ----------------
Load library first time | 7.82 ms ✅ | 14.28 ms | 14.53 ms
Parse first phone number | 2.00 ms | 1.86 ms | 1.65 ms ✅
**⇒ Load + parse first number** | 9.82 ms ✅ | 16.14 ms | 16.18 ms
Format again | 0.09 ms ✅ | 0.22 ms | 0.13 ms
Parse again | 0.39 ms ✅ | 0.51 ms | 0.43 ms
Increased memory usage | 9.77 M ✅ | 12.71 M | 11.25 M
node_modules size | 720 K | * 604 K ✅ | 9.9 M
node_modules files | 9 | * 7 ✅ | 787

\* NOTE: google-libphonenumber only ships CJS, while awesome-phonenumber and libphonenumber-js ships _both_ CJS and ESM

## Basic usage
```ts
import { parsePhoneNumber } from 'awesome-phonenumber'

const pn = parsePhoneNumber( '0707123456', { regionCode: 'SE' } );
// or on e164 format:
const pn = parsePhoneNumber( '+46707123456' );

// pn is now the same as:
const pn = {
valid: true,

number: {
input: '0707123456',
e164: '+46707123456',
international: '+46 70 712 34 56',
national: '070-712 34 56',
rfc3966: 'tel:+46-70-712-34-56',
significant: '707123456',
},
possibility: 'is-possible',
regionCode: 'SE',
possible: true,
shortPossible: false,
shortValid: false,
canBeInternationallyDialled: true,
type: 'mobile',
countryCode: 46,
typeIsMobile: true,
typeIsFixedLine: false,
};
```

The return type is `ParsedPhoneNumber` which is either a `ParsedPhoneNumberValid` or a `ParsedPhoneNumberInvalid`. The `valid` property identifies whether the parsing was successful or not, hence which type is returned.

The format of a successful parsing is:

```ts
interface ParsedPhoneNumberValid {
valid: true;

number: {
input: string;
international: string;
national: string;
e164: string;
rfc3966: string;
significant: string;
};
possibility: PhoneNumberPossibility; // a string union, see below
regionCode: string;
possible: boolean;
shortPossible: boolean;
shortValid: boolean;
canBeInternationallyDialled: boolean;
type: PhoneNumberTypes; // a string union, see below
countryCode: number;
typeIsMobile: boolean;
typeIsFixedLine: boolean;
}
```

If the number failed to be parsed, or there was another error, the return type is:

```ts
interface ParsedPhoneNumberInvalid {
valid: false;

possible: false;
possibility: 'invalid';
shortPossible: boolean;
shortValid: boolean;
error?: unknown;
};
```

Note that an incorrect (invalid) phone number can still be a valid _short number_ for the given region.

## API

```ts
import {
parsePhoneNumber,
findNumbers,
getNumberFrom,
getExample,
getCountryCodeForRegionCode,
getRegionCodeForCountryCode,
getSupportedCallingCodes,
getSupportedRegionCodes,
getAsYouType,
} from 'awesome-phonenumber'
```

### parsePhoneNumber

`parsePhoneNumber( phoneNumber, { regionCode: string } )` parses a phone number as described above.

The first argument is the phone number to parse, on either _national_ or _international_ (e164, i.e. prefixed with a `+`) form. If _national_ form, the second argument is required to contain a `regionCode` string property, e.g. 'SE' for Sweden, 'CH' for Switzerland, etc.

### findNumbers

To find (extract) phone numbers in text, use `findNumbers( )`:

```ts
import { findNumbers } from 'awesome-phonenumber'

const text = 'My number is +46 707 123 456, otherwise call +33777777777.';
const numbers = findNumbers( text );
```

The returned list of numbers is of the type `PhoneNumberMatch` such as:

```ts
interface PhoneNumberMatch
{
text: string; // The raw string found
phoneNumber: object; // Same as the result of parsePhoneNumber()
start: number; // Start offset in the text
end: number; // End offset in the text
}
```

A second options argument to `findNumbers( text, options )` can be provided on the form:

```ts
interface FindNumbersOptions
{
defaultRegionCode?: string;
leniency?: FindNumbersLeniency;
maxTries?: number;
}
```

where `FindNumbersLeniency` is an enum of `'valid'` or `'possible'`. The default is `'valid'` meaning that only valid phone numbers are found. If this is set to `'possible'` also possible (but invalid) phone numbers are found.

`defaultRegionCode` can be set (e.g. to `'SE'` for Sweden), in which case phone numbers on _national_ form (i.e. without `+` prefix) will be found, as long as they are from that region.

For really large texts, `maxTries` will set the maximum number of phone numbers to _try_ to find (not necessary actually find).

### getNumberFrom

```ts
import { parsePhoneNumber, getNumberFrom } from 'awesome-phonenumber'

const pn = parsePhoneNumber( '0707654321', { regionCode: 'SE' } );
if ( pn.valid ) {
const fromJp = getNumberFrom( pn, 'JP' );
// fromJp is the number to call from Japan:
fromJp.number === "010 46 70 765 43 21";
}
```

The return value from `getNumberFrom` is a `PhoneNumberFrom` which is either a `PhoneNumberFromValid` or a `PhoneNumberFromInvalid`.

The `PhoneNumberFromValid` is defined as:

```ts
interface PhoneNumberFromValid
{
valid: true;
number: string;
}
```

The `PhoneNumberFromInvalid` is defined as:

```ts
interface PhoneNumberFromInvalid
{
valid: false;
error?: unknown;
}
```

## getExample

Sometimes you want to display a formatted example phone number for a certain country (and maybe also a certain type of phone number). The `getExample` function is used for this.

```ts
import { getExample } from 'awesome-phonenumber'

getExample( regionCode[, phoneNumberType] ); // Parsed phone number
```

The `phoneNumberType` is any of the [types defined above](#phone-number-types).

### Example

```ts
import { getExample } from 'awesome-phonenumber'

// Get an example Swedish phone number
const example = getExample( 'SE' ); // A ParsedPhoneNumberValid
const exampleMobile = getExample( 'SE', 'mobile' ); // A ParsedPhoneNumberValid

example.number.e164; // e.g. '+468123456'
exampleMobile.number.e164; // e.g. '+46701234567'
exampleMobile.number.national; // e.g. '070 123 45 67'
```

## Country codes

There are conversion functions between the 2-character ISO 3166-1 region codes (e.g. 'SE' for Sweden) and the corresponding country calling codes.

```ts
import {
getCountryCodeForRegionCode,
getRegionCodeForCountryCode,
getSupportedCallingCodes,
getSupportedRegionCodes,
} from 'awesome-phonenumber'

getCountryCodeForRegionCode( regionCode ); // -> countryCode
getRegionCodeForCountryCode( countryCode ); // -> regionCode
```

### Example

```ts
getCountryCodeForRegionCode( 'SE' ); // -> 46
getRegionCodeForCountryCode( 46 ); // -> 'SE'
```

### Supported calling codes

```ts
getSupportedCallingCodes( ); // -> [ calling codes... ]
```

### Supported region codes

```ts
getSupportedRegionCodes( ); // -> [ region codes... ]
```

## API types

The API consists of the `PhoneNumber` class which sometimes uses *enums*. These are:

### Phone number types
```ts
type PhoneNumberTypes =
| 'fixed-line'
| 'fixed-line-or-mobile'
| 'mobile'
| 'pager'
| 'personal-number'
| 'premium-rate'
| 'shared-cost'
| 'toll-free'
| 'uan'
| 'voip'
| 'unknown'
```

### Phone number possibilities

```ts
type PhoneNumberPossibility =
| 'is-possible'
| 'invalid-country-code'
| 'too-long'
| 'too-short'
| 'unknown'
```

### Phone number formats

```ts
'international'
'national'
'e164'
'rfc3966'
'significant'
```

## As-you-type formatting

You can create an `AsYouType` class with `getAsYouType()` to format a phone number as it is being typed.

```ts
import { getAsYouType } from 'awesome-phonenumber'

const ayt = getAsYouType( 'SE' );
```

The returned class instance has the following methods

```ts
// Add a character to the end of the number
ayt.addChar( nextChar: string );

// Get the current formatted number
ayt.number( );

// Remove the last character
ayt.removeChar( );

// Replace the whole number with a new number (or an empty number if undefined)
ayt.reset( number?: string );

// Get a ParsedPhoneNumber object representing the current number
ayt.getPhoneNumber( );
```

All the functions above except `getPhoneNumber( )` return the current formatted number as a string.

#### Example

```ts
import { getAsYouType } from 'awesome-phonenumber'

const ayt = getAsYouType( 'SE' );
ayt.addChar( '0' ); // -> '0'
ayt.addChar( '7' ); // -> '07'
ayt.addChar( '0' ); // -> '070'
ayt.addChar( '7' ); // -> '070 7'
ayt.addChar( '1' ); // -> '070 71'
ayt.addChar( '2' ); // -> '070 712'
ayt.addChar( '3' ); // -> '070 712 3'
ayt.addChar( '4' ); // -> '070 712 34'
ayt.addChar( '5' ); // -> '070 712 34 5'
ayt.addChar( '6' ); // -> '070 712 34 56'
ayt.removeChar( ); // -> '070 712 34 5'
ayt.addChar( '7' ); // -> '070 712 34 57'
```

[npm-image]: https://img.shields.io/npm/v/awesome-phonenumber.svg
[npm-url]: https://npmjs.org/package/awesome-phonenumber
[downloads-image]: https://img.shields.io/npm/dm/awesome-phonenumber.svg
[build-image]: https://img.shields.io/github/actions/workflow/status/grantila/awesome-phonenumber/master.yml?branch=master
[build-url]: https://github.com/grantila/awesome-phonenumber/actions?query=workflow%3AMaster
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/awesome-phonenumber
[bundlephobia-url]: https://bundlephobia.com/package/awesome-phonenumber
[depcount-image]: https://badgen.net/bundlephobia/dependency-count/awesome-phonenumber