Giter Site home page Giter Site logo

aftership / phone Goto Github PK

View Code? Open in Web Editor NEW
812.0 42.0 260.0 1.73 MB

With a given country and phone number, validate and reformat the mobile phone number to the E.164 standard. The purpose of this is to allow us to send SMS to mobile phones only.

Home Page: https://www.aftership.com

License: MIT License

JavaScript 40.16% HTML 1.62% TypeScript 58.22%
sms phone-number mobile phone e164

phone's Introduction

Phone · PRs Welcome FOSSA Status

What is phone?

phone is used to normalize mobile phone numbers into E.164 format.

A common problem is that users normally input phone numbers in this way:

`(817) 569-8900` or
`817569-8900` or
`1(817) 569-8900` or
`+1(817) 569-8900` or ...

We always want:

+18175698900

Install

npm install phone

// or

yarn add phone

Usage

const {phone} = require('phone');

// or

import {phone} from 'phone';

1. Simple usage

phone('+852 6569-8900');
// { isValid: true, phoneNumber: '+85265698900',  countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

2. With Country

phone('+1(817) 569-8900', {country: ''}); 
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1'}

phone('(817) 569-8900', {country: 'USA'});
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1'}

phone('(817) 569-8900', {country: 'HKG'});
// { isValid: false }
// not a valid HKG mobile phone number

phone('+1(817) 569-8900', {country: 'HKG'});
// { isValid: false }
// not a valid HKG mobile phone number

phone('6123-6123', {country: 'HKG'});
// { isValid: true, phoneNumber: '+85261236123', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

3. Without country code and no phone prefix

If both country code and country phone prefix are not provided, the phone number will be treated as USA or Canada by default.

phone('(817) 569-8900');
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1' }

phone('(817) 569-8900', {country: ''});
// { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1' }

phone('780-569-8900', {country: null});
// { isValid: true, phoneNumber: '+17805698900', countryIso2: 'CA', countryIso3: 'CAN', countryCode: '+1' }
// 780 is a Canada phone prefix

phone('6123-6123', {country: null});
// { isValid: false }
// as default country is USA / CAN and the phone number does not fit such countries' rules

4. With country code / phone prefix, but no + sign

Even you input a valid phone number with a valid prefix, if there is no plus sign, it will not work as expected:

phone('85291234567');
// or
phone('85291234567', {country: null});

// { isValid: false }

852 is a valid Hong Kong phone prefix, and 91234567 is a valid Hong Kong mobile phone number. However, there is no plus sign provided, the module will assume the phone number is a USA or Canada phone number, hence no result will be found.

If you know you have provided country phone prefix, make sure you also provide a plus sign:

phone('+85291234567');
// or
phone('+85291234567', {country: null});

// { isValid: true, phoneNumber: '+85291234567', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

or, if you know the country, and only want to reformat the phone number to E.164 format:

phone('91234567',  {country: 'HKG'})
// { isValid: true, phoneNumber: '+85291234567', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }

5. Skipping phone number initial digit checking

If you want to skip phone number initial digit checking, set validateMobilePrefix to false:

phone('+(852) 2356-4902');
// { isValid: false }
// '2' is a Hong Kong landline phone number prefix, not a valid mobile phone number prefix

phone('+(852) 2356-4902', {validateMobilePrefix: true});
// { isValid: false }
// same as above, default value of validateMobilePrefix = true

phone('+(852) 2356-4902', {validateMobilePrefix: false});
// { isValid: true, phoneNumber: '+85223564902', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
// skipping mobile prefix checking

With validateMobilePrefix set to false, the initial digit checking logic will be disabled completely, even you enter a phone number start with a non-exist digit:

phone('+(852) 0356-4902', {validateMobilePrefix: false});
// { isValid: true, phoneNumber: '+85203564902', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
// even the phone number start with `0` is not a valid landline phone number

Note that the module does not have the capability to determine if the prefix is a valid landline prefix number.

6. Trunk Code Detection Logic

For some phone numbers, such as this sample UK phone number:

+44 07911 123456

There is a trunk code 0 after the country code +44 so that it is unable to match any correct country.

Hence the module will try to remove 1 digit after the country code,

and try to detect:

+44 7911 123456

and it would become a valid UK phone number now.

phone('+4407911 123456')
// { isValid: true, phoneNumber: '+447911123456', countryIso2: 'GB', countryIso3: 'GBR', countryCode: '+44' }

If you want to disable this behavior, please set strictDetection to true:

phone('+4407911 123456', {strictDetection: true})
// { isValid: false }

API

const {phone} = require('phone');

// or

import {phone} from 'phone';

phone(phoneNumber: string, { country, validateMobilePrefix, strictDetection }?: {
    country?: string;
    validateMobilePrefix?: boolean;
    strictDetection?: boolean;
})

Input

Parameter Type Required Default Description
phoneNumber String Yes - The phone number text you want to process
country String No null Provided country code in iso-3166 alpha 2 or 3 format
validateMobilePrefix Boolean No true Set to false if you want to skip phone number initial digit checking
strictDetection Boolean No false Set to true if you want to disable trunk code detection logic.

Returns

type PhoneResult = PhoneInvalidResult | PhoneValidResult;

interface PhoneValidResult {
	isValid: true;
	phoneNumber: string;
	countryIso2: string;
	countryIso3: string;
	countryCode: string;
}

interface PhoneInvalidResult {
	isValid: false;
	phoneNumber: null;
	countryIso2: null;
	countryIso3: null;
	countryCode: null;
}
Parameter Type Description
isValid Boolean To indicate if the result valid
phoneNumber String or null Normalized phone number in E.164 format
countryIso2 String or null Detected phone number country code in iso-3166 alpha 2 format
countryIso3 String or null Detected phone number country code in iso-3166 alpha 3 format
countryCode String or null Detected phone number country calling code with + sign

Test

yarn test

Interactive Web Example

yarn start:example

or

yarn dev

And then visit http://localhost:8080

Build

yarn build

FAQ

  1. Does phone do any logical validation?

    Yes. If you provide country, and the phone number does not start with + sign,

    the module will validate phone_number_lengths and mobile_begin_with

  2. Why is phone returning an invalid result for a valid phone number?

    By default, the function will validate a mobile phone number only, to validate a landline phone number, please set validateMobilePrefix to false.

    If you find the result is still incorrect, please submit a ticket to improve our validation rules.

  3. Why is phone returning an object with isValid = false instead of returning a null directly?

    It reserves the flexibility to extend the response interface for invalid result in future.

Migrate from v2

The interface of v3 has been changed for better usability, maintainability and flexibility, this shows all the changes from v2:

Function Interface

Version Interface
v2 phone(phoneNumber, country, allowLandline)
v3 phone(phoneNumber,{country: String, validateMobilePrefix: Boolean, strictDetection: Boolean})

Function Response

Version Result Interface
v2 - [phoneNumber, country]
v3 Valid {isValid: true, phoneNumber: string, countryIso2: string, countryIso3: string, countryCode: string}
v3 Invalid {isValid: false, phoneNumber: null, countryIso2: null, countryIso3: null, countryCode: null}

allowLandline vs validateMobilePrefix

allowLandline in v2 is essentially equals to validateMobilePrefix in v3, however, the value is opposite.

Because allowLandline = true in v2 means "Skip the mobile phone number prefix validation", and there is NO capability to verify if the input phone number is a valid landline phone number.

To avoid the misleading information, the parameter name has been changed to validateMobilePrefix, and the input value is opposite, while validateMobilePrefix = false means "Skip the mobile phone number prefix validation".

Help

We've tried to make sure that this package works for as many cases as possible, if you notice that we have an incorrect rule for a country or other case, please open an issue to let us know.

For creating new pull requests regarding add or modify phone number formats, please include the reference information such as PDFs, websites, etc. Thank you very much.

The library supports mobile phone number format only. We are unable to provide landline phone number support as we do not have landline phone number format data, hence we do not accept PRs for landline phone numbers.

License

This project is licensed under the MIT license.

FOSSA Status

phone's People

Contributors

adam0x01 avatar adityabansod avatar aftership-admin avatar anhtuank7c avatar boomfly avatar bossa573 avatar coldshower avatar dependabot[bot] avatar ebaynaud avatar fyko avatar gongbaodd avatar hans-lizihan avatar hiukwok avatar kode4food avatar lykmapipo avatar maximization avatar neekey avatar pgl avatar quaidbartolomei avatar rbudiharso avatar rssnorbertkeri avatar secretbase avatar serega3000 avatar soutoukakka avatar teddychan avatar tom-crypto avatar victorberestian avatar williamli avatar youthcity avatar zontik2012 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phone's Issues

UK phone numbers that aren’t for mobiles are returned as invalid

If you use a UK land line phone number like “02380 123456” then an empty array is returned as if the phone number is invalid. This is a valid phone number format but for a non mobile number.

Can an additional parameter be added to phone() or by another means a flag be set as to whether a mobile phone check should be performed?

Regards

Doesn't work with custom array prototype extensions.

If 'Array' type is extended like below, enumeration using for (var i in ...) doesn't work as expected.

Array.prototype.foo = function() { console.log("hi"); }
a = [1,2,3,4,5];
for (var i in a) {
  console.log(i); //foo will be enumerated
}

This causes invalid regular expression error in validate_phone_iso3166 function.

Eliminate leading 0

Sometimes users are used to type in their phone with a leading 0, after the country code. Can we identify this?

ReferenceError: Can't find variable: iso3166_data

v1.0.11 causes an error on mobile safari. It seems that in this commit the data switched from being a variable to being required.

Due to the scoping of const, the variable that is holding the iso3166_data becomes undefined. Did not happen before since data was stored within file (instead of being required). A simple fix is to replace const with var.

ukrainian mobile phone numbers

from #119 and #98

Here is the table combining both source:

code prefix wiki maanimo.com Current phone module support?
39
50 Vodafone Vodafone
63 lifecell lifecell
66 Vodafone Vodafone
67 Kyivstar Kyivstar
68 Kyivstar
73 lifecell lifecell
891 Datagroup
892 Ukrtelecom
893 Global
894 O3 / mixnet
895 Link-3000
896 Vodafone
897 Kyivstar
899 Velton.Telecom
91 ThreeMob ThreeMob / PeopleNet / Intertelecom
92 PeopleNet ThreeMob / PeopleNet / Intertelecom
93 lifecell lifecell
94 Intertelecom ThreeMob / PeopleNet / Intertelecom
95 Vodafone Vodafone
96 Kyivstar Kyivstar
97 Kyivstar Kyivstar
98 Kyivstar Kyivstar
99 Vodafone Vodafone

68

Only exists on wiki, unable to verify the correctness

89x

Only exists on wiki, unable to verify the correctness

91, 92, 94

From https://maanimo.com/helpful/142623-kody-operatorov

(translated)
91 - belongs to the operator Trimob from the company Ukrtelecom and sent to use high-quality 3G-Internet;

92 - is PeopleNet, which is also used mainly for the Internet;

94 - owned by Intertelecom, which has long been trying to create competition to the three main Ukrainian operators, but so far unsuccessfully. 94 is new and almost unknown at the moment;

91 is seems to be valid, but 92 and 94 is doubtful

@DanielMazurkiewicz @Kamikadze4GAME please help to review and resolving 68, 89x, 91, 92, 94 before I merge the codes, thanks

New release?

Do you mind bumping the version and releasing the latest changes. It's been a while since last release 😁

Thank you!

Error with source-map while building

AfterShip/phone is a dependency of my project and I recently meet some build issues due to source-map, probably due to: webpack-contrib/babel-minify-webpack-plugin#68

I will PR in a few minute a workaround to disable source-map.

Issue details:

93% after chunk asset optimization SourceMapDevToolPlugin index.js generate SourceMap/myprojectpath/node_modules/phone/node_modules/babel-minify-webpack-plugin/node_modules/source-map/lib/source-map-generator.js:276
        throw new Error(
        ^

Error: original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.

Toll Free returning blank results

It appears USA toll free returns blanks. I'm not sure if this is the desired return or not, but we certainly need those straightened out also.

Croatia Mobile and SMS

Looks like some older Croatian cell phones have six digit numbers instead of seven, e.g. +385 98 xxx xxx. Currently node-phone requires seven. It should allow six or seven.

Tests not running

Tests aren't running. The output of npm test is:

iMacValerio:node-phone tanis$ npm test

> [email protected] test /Users/tanis/Documents/node-phone
> mocha --recursive -R spec


module.js:340
    throw err;
          ^
Error: Cannot find module 'should'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/Users/tanis/Documents/node-phone/test/index.js:1:76)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at /usr/local/lib/node_modules/mocha/lib/mocha.js:157:27
    at Array.forEach (native)
    at Mocha.loadFiles (/usr/local/lib/node_modules/mocha/lib/mocha.js:154:14)
    at Mocha.run (/usr/local/lib/node_modules/mocha/lib/mocha.js:326:31)
    at Object.<anonymous> (/usr/local/lib/node_modules/mocha/bin/_mocha:350:7)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3
npm ERR! weird error 8
npm ERR! not ok code 0
iMacValerio:node-phone tanis$ 

Argentina Mobile and SMS

We're using the library to validate SMS phone numbers, and Argentinian SMS has a wrinkle - it doesn't support the leading 9, per http://en.wikipedia.org/wiki/Telephone_numbers_in_Argentina#Inbound_SMS

Also, it looks like Argentinian numbers can be 6, 7 or 8 digits long. I'm curious about the 10 in the code:

country_code: "54", country_name: "Argentina", mobile_begin_with: ["9"], phone_number_lengths: [10]

Would you entertain a pull request that removes the mobile_begin_with 9 requirement and replaces the 10 with 6, 7, 8, 9 (to cover whether or not the leading 9 is present). Or is there a better approach to fix this?

Bad Length Comparison

On line 417 of node-phone / lib / index.js there is a bad phone number length comparison.

if (phone.length === iso3166.phone_number_lengths) {
should be
if (iso3166.phone_number_lengths.indexOf(phone.length)>-1) {

iso3166.phone_number_lengths is an array, and you should be looking for the presence of the phone.length in that array, rather than a strict comparison. This always returns false as is, being that 10 !== [10]

Netherlands phone number returning empty array

Validation for NL phone:+31623638101‬ without country code returning an empty array, although it is a valid NL phone.

Phone('+31623638101‬', 'NL') => return ['+31623638101', 'NLD'] // this works
Phone('+31623638101‬') => returns [] // expected to be the same as above

+86 21 5206 6273 is a valid number

I live in China and I can dial this number +86 21 5206 6273 but when I pass in either of the below I get undefined returned.

+86 21 5206 6273
+86 021 5206 6273

Politically incorrect region name "Taiwan, Province of China"

(This issue is forwarded from Politically incorrect region name "Taiwan, Province of China" · Issue #626 · GitbookIO/feedback)

The region name "Taiwan, Province of China" is politically incorrect and offending to Taiwanese users, please use the neutral name "Taiwan" instead.

If the application relies on the iso-codes package, please use the "common name" field when available instead as with this patch did with the Ubuntu LoCo Team Portal site.

REF:

Thanks in advance!

Update some +1 areas

by no means exhaustive, but some "mobile_begin_with" rules I found in numbers already in my database for numbers with the country code +1 and 10 digit numbers

  • 340 -- virgin islands
  • 787, 939 -- puerto rico
  • 876 -- jamaica
  • 242 -- bahamas

Bug in Finnish numbers

Just found out a bug in your package:

  var phone = require('phone')
   phone('+358 (0) 10 44 88 000') // []
   phone('+358104488000')    // []

This is Nokia's office number in Helsinki, Finland and it's a valid number. It surprisingly returns an empty array.

Update Prefixes for Denmark

Valid phone numbers from Denmark are being called invalid. The library currently requires the phone number to begin with one of these: ["20", "31", "40", "42", "50", "53", "60", "61", "71", "81", "91", "93"]

But there are now valid mobile phone numbers in Denmark that start with more numbers. According to https://erhvervsstyrelsen.dk/nummerplan numbers that start with the following digits: 2, 30, 31, 40, 41, 42, 50, 51, 52, 53, 60, 61, 71, 81, 91, 92 and 93 are primarily designated mobile communication.

The library should add 2, 30, 41, 51, 52 and 92 to the "starts with" array for Denmark. (And remove 20 since 2 will cover it.)

Phone number validation error with prefixed plus sign

test case as following:

phone('+5345-4564','HKG');
[ '+53454564', 'HKG' ] // Actual response @1.0.9
// expect: [] or ['+85253454564', 'HKG']

phone('+53454564', 'HKG');
[ '+53454564', 'HKG' ] // Actual response @1.0.9
// expect: [] or ['+85253454564', 'HKG'].

Undocumented feature

Seems that forcing the first character of the phone argument to be a '+' sign will disable the default country feature. I do need this feature disabled, but I haven't seen any note about this behavior in the documentation.

Example:

847-555-5555 results in prefixed number with USA country code
+847-555-5555 fails validation and results in []

Fail to parse Israel non-mobile phone numbers

The module failed to parse Israel non-mobile phone numbers.

Example:

phone('+972-3-111-1111') will returns []

Israel non-mobile phone numbers have local prefix that starts with zero and consist of 2 digits (e.g. 03, 02, 08, ...).

Detecting Israel mobile phone number works. they have local prefix that starts with zero and consists of 3 digits (e.g. 052, 050, 054, ...).

Possible solution:

{
alpha2: "IL",
alpha3: "ISR",
country_code: "972",
country_name: "Israel",
mobile_begin_with: ["1", "2", "3", "4", "5", "7", "8", "9"],
phone_number_lengths: [8, 9, 11]
}

Will validate successfully these phone numbers:

  • ‎+972-50-111-1111
  • +972-73-111-1111
  • +972-2-111-1111
  • +972-3-111-1111
  • +972-4-111-1111
  • +972-8-111-1111
  • +972-9-111-1111
  • +972-1599-111-1111
  • +972-1700-111-1111
  • +972-1800-111-1111

https://he.wikipedia.org/wiki/%D7%A7%D7%99%D7%93%D7%95%D7%9E%D7%AA_%D7%98%D7%9C%D7%A4%D7%95%D7%9F_%D7%91%D7%99%D7%A9%D7%A8%D7%90%D7%9C

US 800 #s

I have the same problem as #146 but I'm using '+1 (800) 555 1212', which is standard for testing. I get an empty array. this should be acceptable and should format properly

Potential issue with +

I there!

If you put: 643123123 & FR
It output: ["+33643123123", "FRA"] All right!

But if you try this combinaison: +643123123 & FR
It output : ["+643123123", "FRA"], that is not the same number (or wrong number, I don't know).

Did i missed something ?

Countries without mobile-begin-with values may fail to validate

If you call the module with a phone number but not a country, and the phone number includes a country code (e.g. +54 for Argentina) and the country doesn't have any mobile_begin_with values, then the internal function get_iso3166_by_phone will fail to return an iso3166 entry and valid phone numbers for that country will fail to validate.

New numbers in China.

Ministry of Industry and Information Technology of China disclosed a number of new numbers in 2017 tenth "telecommunications network code resource use certificate"

China Telecom: 199
China Mobile: 198
China Unicom: 166

Valid phone number (USA/Canada) not working

Input value: 905-555-1234

Output value: []

Expected: [ '+19055431234', 'USA' ]

If I have time, I'll try and look into your code and issue a PR, but it probably won't be anytime soon.

Edit: 905 is a Canadian area code, but the formatting is the same...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.