1 | # google-libphonenumber
|
2 |
|
3 | The up-to-date and reliable Google's libphonenumber package for node.js. Zero dependencies.
|
4 |
|
5 | ## Status
|
6 |
|
7 | [![npm version][npm-image]][npm-url]
|
8 | [![build status][travis-image]][travis-url]
|
9 | [![install size][packagephobia-image]][packagephobia-url]
|
10 |
|
11 | ## Introduction
|
12 |
|
13 | Google's [libphonenumber](https://github.com/googlei18n/libphonenumber) is a library that parses, formats, stores and validates international phone numbers. It is used by Android since version 4.0 and is a phenomenal repository of carrier metadata.
|
14 |
|
15 | Although it compiles down to Java, C++ and JS, its JS port is tightly coupled to the Google Closure library. This makes it more difficult to directly require and use the code on a node.js project.
|
16 |
|
17 | Google eventually started publishing [google-closure-library](https://www.npmjs.com/package/google-closure-library) directly to NPM, ending years of ill-maintained community packages. However, running the original library on node.js [remains a cumbersome process](https://github.com/googlei18n/libphonenumber/tree/master/javascript).
|
18 |
|
19 | After all these years, Google's libphonenumber is still not officially available on NPM. What is the best way to use Google's libphonenumber on node.js then? If you're looking for a convenient and easy method, that's what this package is all about.
|
20 |
|
21 | ## Installation
|
22 |
|
23 | Install the package via `npm`:
|
24 |
|
25 | ```sh
|
26 | npm install --save-prod google-libphonenumber
|
27 | ```
|
28 |
|
29 | ## Usage
|
30 |
|
31 | The following is a simple phone information extraction example similar to what can be viewed on the official demo page.
|
32 |
|
33 | ```js
|
34 | // Require `PhoneNumberFormat`.
|
35 | const PNF = require('google-libphonenumber').PhoneNumberFormat;
|
36 |
|
37 | // Get an instance of `PhoneNumberUtil`.
|
38 | const phoneUtil = require('google-libphonenumber').PhoneNumberUtil.getInstance();
|
39 |
|
40 | // Parse number with country code and keep raw input.
|
41 | const number = phoneUtil.parseAndKeepRawInput('202-456-1414', 'US');
|
42 |
|
43 | // Print the phone's country code.
|
44 | console.log(number.getCountryCode());
|
45 | // => 1
|
46 |
|
47 | // Print the phone's national number.
|
48 | console.log(number.getNationalNumber());
|
49 | // => 2024561414
|
50 |
|
51 | // Print the phone's extension.
|
52 | console.log(number.getExtension());
|
53 | // =>
|
54 |
|
55 | // Print the phone's extension when compared to i18n.phonenumbers.CountryCodeSource.
|
56 | console.log(number.getCountryCodeSource());
|
57 | // => FROM_DEFAULT_COUNTRY
|
58 |
|
59 | // Print the phone's italian leading zero.
|
60 | console.log(number.getItalianLeadingZero());
|
61 | // => false
|
62 |
|
63 | // Print the phone's raw input.
|
64 | console.log(number.getRawInput());
|
65 | // => 202-456-1414
|
66 |
|
67 | // Result from isPossibleNumber().
|
68 | console.log(phoneUtil.isPossibleNumber(number));
|
69 | // => true
|
70 |
|
71 | // Result from isValidNumber().
|
72 | console.log(phoneUtil.isValidNumber(number));
|
73 | // => true
|
74 |
|
75 | // Result from isValidNumberForRegion().
|
76 | console.log(phoneUtil.isValidNumberForRegion(number, 'US'));
|
77 | // => true
|
78 |
|
79 | // Result from getRegionCodeForNumber().
|
80 | console.log(phoneUtil.getRegionCodeForNumber(number));
|
81 | // => US
|
82 |
|
83 | // Result from getNumberType() when compared to i18n.phonenumbers.PhoneNumberType.
|
84 | console.log(phoneUtil.getNumberType(number));
|
85 | // => FIXED_LINE_OR_MOBILE
|
86 |
|
87 | // Format number in the E164 format.
|
88 | console.log(phoneUtil.format(number, PNF.E164));
|
89 | // => +12024561414
|
90 |
|
91 | // Format number in the original format.
|
92 | console.log(phoneUtil.formatInOriginalFormat(number, 'US'));
|
93 | // => (202) 456-1414
|
94 |
|
95 | // Format number in the national format.
|
96 | console.log(phoneUtil.format(number, PNF.NATIONAL));
|
97 | // => (202) 456-1414
|
98 |
|
99 | // Format number in the international format.
|
100 | console.log(phoneUtil.format(number, PNF.INTERNATIONAL));
|
101 | // => +1 202-456-1414
|
102 |
|
103 | // Format number in the out-of-country format from US.
|
104 | console.log(phoneUtil.formatOutOfCountryCallingNumber(number, 'US'));
|
105 | // => 1 (202) 456-1414
|
106 |
|
107 | // Format number in the out-of-country format from CH.
|
108 | console.log(phoneUtil.formatOutOfCountryCallingNumber(number, 'CH'));
|
109 | // => 00 1 202-456-1414
|
110 | ```
|
111 |
|
112 | #### Using the "As You Type" Formatter
|
113 |
|
114 | The "As You Type" formatter is a specialized tool that show the formatting *progress* as it attempts to discover the right format for the given number. It requires registering every keystroke (input digit) on a new instance of the `AsYouTypeFormatter` as shown below.
|
115 |
|
116 | ```js
|
117 | // Require `AsYouTypeFormatter`.
|
118 | const AsYouTypeFormatter = require('google-libphonenumber').AsYouTypeFormatter;
|
119 | const formatter = new AsYouTypeFormatter('US');
|
120 |
|
121 | console.log(formatter.inputDigit('2')); // => 2
|
122 | console.log(formatter.inputDigit('0')); // => 20
|
123 | console.log(formatter.inputDigit('2')); // => 202
|
124 | console.log(formatter.inputDigit('-')); // => 202-
|
125 | console.log(formatter.inputDigit('4')); // => 202-4
|
126 | console.log(formatter.inputDigit('5')); // => 202-45
|
127 | console.log(formatter.inputDigit('6')); // => 202-456
|
128 | console.log(formatter.inputDigit('-')); // => 202-456-
|
129 | console.log(formatter.inputDigit('1')); // => 202-456-1
|
130 | console.log(formatter.inputDigit('4')); // => 202-456-14
|
131 | console.log(formatter.inputDigit('1')); // => 202-456-141
|
132 | console.log(formatter.inputDigit('4')); // => 202-456-1414
|
133 |
|
134 | // Cleanup all input digits from instance.
|
135 | formatter.clear();
|
136 | ```
|
137 |
|
138 | ## Methods
|
139 |
|
140 | A quick glance at Google's libphonenumber rich API. Descriptions sourced from original files.
|
141 |
|
142 | ### i18n.phonenumbers.PhoneNumberUtil
|
143 |
|
144 | The class that offers the main utilities to work with phone numbers, such as formatting, parsing and validating.
|
145 |
|
146 | Highlights:
|
147 |
|
148 | * **format(number, numberFormat)** - formats a phone number in the specified format using default rules.
|
149 | * **formatInOriginalFormat(number, regionCallingFrom)** - formats a phone number using the original phone number format that the number is parsed from.
|
150 | * **formatOutOfCountryCallingNumber(number, regionCallingFrom)** - formats a phone number for out-of-country dialing purposes.
|
151 | * **getNumberType(number)** - gets the type of a valid phone number.
|
152 | * **getRegionCodeForNumber(number)** - returns the region where a phone number is from.
|
153 | * **isPossibleNumber(number)** - returns true if the number is either a possible fully-qualified number (containing the area code and country code), or if the number could be a possible local number (with a country code, but missing an area code).
|
154 | * **isValidNumber(number)** - tests whether a phone number matches a valid pattern.
|
155 | * **isValidNumberForRegion(number, regionCode)** - tests whether a phone number is valid for a certain region.
|
156 | * **parseAndKeepRawInput(numberToParse, defaultRegion)** - parses a string and returns it in proto buffer format while keeping the raw input value.
|
157 | * **parse(numberToParse, defaultRegion)** - parses a string and returns it in proto buffer format.
|
158 |
|
159 | ### i18n.phonenumbers.PhoneNumber
|
160 |
|
161 | The type of the phone returned after a string number has been parsed via `PhoneNumberUtil.parse()` or `PhoneNumberUtil.parseAndKeepRawInput()`.
|
162 |
|
163 | Highlights:
|
164 |
|
165 | * **getCountryCode()**
|
166 | * **getCountryCodeSource()**
|
167 | * **getExtension()**
|
168 | * **getItalianLeadingZero()**
|
169 | * **getNationalNumber()**
|
170 | * **getRawInput()**
|
171 |
|
172 | ## i18n.phonenumbers.CountryCodeSource
|
173 |
|
174 | Lists the following enums in order to compare them with the output of `Phone.getCountryCodeSource()`:
|
175 |
|
176 | * `CountryCodeSource.UNSPECIFIED`
|
177 | * `CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN`
|
178 | * `CountryCodeSource.FROM_NUMBER_WITH_IDD`
|
179 | * `CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN`
|
180 | * `CountryCodeSource.FROM_DEFAULT_COUNTRY`
|
181 |
|
182 | ## i18n.phonenumbers.PhoneNumberFormat
|
183 |
|
184 | Lists the following enums in order to pass them to `PhoneNumberUtil.format()`:
|
185 |
|
186 | * `PhoneNumberFormat.E164`
|
187 | * `PhoneNumberFormat.INTERNATIONAL`
|
188 | * `PhoneNumberFormat.NATIONAL`
|
189 | * `PhoneNumberFormat.RFC3966`
|
190 |
|
191 | ## i18n.phonenumbers.PhoneNumberType
|
192 |
|
193 | Lists the following enums in order to compare them with the output of `PhoneNumberUtil.getNumberType()`:
|
194 |
|
195 | * `PhoneNumberType.FIXED_LINE`
|
196 | * `PhoneNumberType.MOBILE`
|
197 | * `PhoneNumberType.FIXED_LINE_OR_MOBILE`
|
198 | * `PhoneNumberType.TOLL_FREE`
|
199 | * `PhoneNumberType.PREMIUM_RATE`
|
200 | * `PhoneNumberType.SHARED_COST`
|
201 | * `PhoneNumberType.VOIP`
|
202 | * `PhoneNumberType.PERSONAL_NUMBER`
|
203 | * `PhoneNumberType.PAGER`
|
204 | * `PhoneNumberType.UAN`
|
205 | * `PhoneNumberType.VOICEMAIL`
|
206 | * `PhoneNumberType.UNKNOWN`
|
207 |
|
208 | ### i18n.phonenumbers.ShortNumberInfo
|
209 |
|
210 | Highlights:
|
211 |
|
212 | * **connectsToEmergencyNumber(number, regionCode)** - tests whether the short number can be used to connect to emergency services when dialed from the given region.
|
213 | * **isPossibleShortNumber(number)** - tests whether a short number is a possible number.
|
214 | * **isPossibleShortNumberForRegion(number, regionDialingFrom)** - tests whether a short number is a possible number when dialed from the given region.
|
215 | * **isValidShortNumber(number)** - tests whether a short number is a possible number.
|
216 | * **isValidShortNumberForRegion(number, regionDialingFrom)** - tests whether a short number matches a valid pattern in a region.
|
217 |
|
218 | ```js
|
219 | // Get an instance of `ShortNumberInfo`.
|
220 | const shortInfo = require('google-libphonenumber').ShortNumberInfo.getInstance();
|
221 |
|
222 | // Get an instance of `PhoneNumberUtil`.
|
223 | const phoneUtil = require('google-libphonenumber').PhoneNumberUtil.getInstance();
|
224 |
|
225 | // Result from connectsToEmergencyNumber().
|
226 | console.log(shortInfo.connectsToEmergencyNumber('911', 'US'));
|
227 | // => true
|
228 |
|
229 | // Result from isPossibleShortNumber().
|
230 | console.log(shortInfo.isPossibleShortNumber(phoneUtil.parse('123456', 'FR')));
|
231 | // => true
|
232 |
|
233 | // Result from isPossibleShortNumberForRegion().
|
234 | console.log(shortInfo.isPossibleShortNumberForRegion(phoneUtil.parse('123456', 'FR'), 'FR'));
|
235 | // => true
|
236 | ```
|
237 |
|
238 | ### Unavailable methods and classes
|
239 |
|
240 | The following methods or classes are unavailable on the original JS port of Google's libphonenumber:
|
241 |
|
242 | * findNumbers - finds numbers in text (useful for highlighting or linking phone numbers inside text messages).
|
243 | * PhoneNumberOfflineGeocoder - provides geographical information related to a phone number.
|
244 | * PhoneNumberToCarrierMapper - provides carrier information related to a phone number.
|
245 | * PhoneNumberToTimeZonesMapper - provides timezone information related to a phone number.
|
246 |
|
247 | ## Notes
|
248 |
|
249 | ### Metadata issues
|
250 |
|
251 | Most of the issues submitted to this repository are related to carrier metadata - things like unexpected phone validations, errors in formatting numbers, unknown carriers and so on.
|
252 |
|
253 | First, try the same input using the [official demo page](http://libphonenumber.appspot.com). If the result is different, then it might mean that a metadata update is due on this package, as the demo page always runs on the latest and official metadata version.
|
254 |
|
255 | If the result is the same, it means there might be an issue with the currently available metadata. In that case, you should report your issue in the original project's [issue tracker](https://issuetracker.google.com/issues?q=componentid:192347) ([moved out of GitHub on 05/12/2017](https://groups.google.com/forum/#!topic/libphonenumber-discuss/bcCh0175LME)).
|
256 |
|
257 | This note will be posted on every issue regarding metadata troubles and it will be automatically closed.
|
258 |
|
259 | ### Differences from other packages
|
260 |
|
261 | `google-libphonenumber` does not try to be more than what it really is - a pre-compiled Google libphonenumber bundle that works on node.js. It is a **1:1 mirror** of the original library without any further simplifications or optimizations.
|
262 |
|
263 | * All classes available from `libphonenumber` are exported as-is. No magic methods.
|
264 | * Always based on the latest `google-closure` library version available from Google with performance and bug fixes.
|
265 | * Relies on a simplified and [well-documented update process](https://github.com/ruimarinho/google-libphonenumber/blob/master/bin/update.sh) to keep the underlying `libphonenumber` library always up-to-date.
|
266 |
|
267 | If you're looking for a slightly simpler API, you should try [awesome-phonenumber](https://www.npmjs.com/package/awesome-phonenumber). It is based on the same concepts of this package but changes the API in order to make it more user friendly. You run the risk of bumping into [other](https://github.com/grantila/awesome-phonenumber/issues/14) [bugs](https://github.com/grantila/awesome-phonenumber/issues/17) and you'll have to [learn new API types](https://github.com/grantila/awesome-phonenumber#api-types), but that's the necessary trade-off that the author made for achieving a generally better looking API.
|
268 |
|
269 | [libphonenumber-js](https://www.npmjs.com/package/libphonenumber-js) is a much more radical approach to Google's libphonenumber. It is a rewrite of the original library based on its source phone metadata but implemented without depending on the Google Closure library. It also offers a tool to reduce the metadata to a set of countries which might be useful for frontend projects. It has several [caveats](https://github.com/catamphetamine/libphonenumber-js#difference-from-googles-libphonenumber), many of which make a lot of sense depending on the project, but you will have to ascertain those yourself.
|
270 |
|
271 | ## Webpack
|
272 |
|
273 | There have been some users reporting successful but also unsuccessful usage with Webpack. While I don't personally use it, I'm 100% supportive of pull requests adding modifications that allow this package to better interact with it.
|
274 |
|
275 | ## Tests
|
276 |
|
277 | A small subset of tests guarantees that the main library functions are working as expected and are correctly exported. The actual heavy lifting is done by `libphonenumber`'s extensive test suite.
|
278 |
|
279 | ```sh
|
280 | npm test
|
281 | ```
|
282 |
|
283 | ## Release
|
284 |
|
285 | ```sh
|
286 | npm version [<newversion> | major | minor | patch] -m "Release %s"
|
287 | ```
|
288 |
|
289 | ## Acknowledgments
|
290 |
|
291 | The exceptional work on `libphonenumber` was made possible by these [committers and contributors](https://github.com/googlei18n/libphonenumber/graphs/contributors).
|
292 |
|
293 | ## Licenses
|
294 |
|
295 | This package is licensed under MIT. The bundled [libphonenumber](https://github.com/googlei18n/libphonenumber/blob/master/LICENSE) library is licensed under Apache 2.0.
|
296 |
|
297 | [npm-image]: https://flat.badgen.net/npm/v/google-libphonenumber
|
298 | [npm-url]: https://npmjs.org/package/google-libphonenumber
|
299 | [travis-image]: https://flat.badgen.net/travis/ruimarinho/google-libphonenumber
|
300 | [travis-url]: https://travis-ci.org/ruimarinho/google-libphonenumber
|
301 | [packagephobia-image]: https://flat.badgen.net/packagephobia/install/google-libphonenumber
|
302 | [packagephobia-url]: https://packagephobia.now.sh/result?p=google-libphonenumber
|