├── .nvmrc
├── .eslintignore
├── example
├── client
│ ├── .eslintrc
│ └── index.js
├── webpack.config.js
├── README.md
└── index.html
├── .eslintrc
├── __tests__
├── .eslintrc
├── index.spec.ts
├── test_match.ts
└── data.csv
├── .babelrc
├── .github
└── ISSUE_TEMPLATE
│ ├── 2--all-other-issues.md
│ └── 1_phone_number_format_issue.yml
├── scripts
└── add-new-rules
│ ├── tsconfig.json
│ ├── interface.ts
│ └── index.ts
├── jest.config.js
├── .gitignore
├── tsconfig.json
├── webpack.config.js
├── LICENSE
├── package.json
├── .npmignore
├── src
├── index.ts
├── lib
│ └── utility.ts
└── data
│ └── country_phone_data.ts
├── README.md
└── test_generate.js
/.nvmrc:
--------------------------------------------------------------------------------
1 | v12.22.0
2 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | coverage
3 | lib
4 |
--------------------------------------------------------------------------------
/example/client/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "aftership/frontend",
3 | "rules": {
4 | "max-lines": 0
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "aftership",
3 | "rules": {
4 | "max-lines": 0,
5 | "comma-dangle": "off"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/__tests__/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "aftership",
3 | "env": {
4 | "jest": true,
5 | "comma-dangle": "off"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", {
4 | "targets": {
5 | "node": "6.11"
6 | }
7 | }]
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2--all-other-issues.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 2. All other issues
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/scripts/add-new-rules/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2015",
4 | "module": "commonjs",
5 | "lib": ["es2015"],
6 | "esModuleInterop": true,
7 | "allowJs": true
8 | }
9 | }
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | preset: 'ts-jest',
5 | testEnvironment: 'node',
6 | coverageDirectory: './coverage/',
7 | collectCoverage: true,
8 | transform: {
9 | '^.+\\.(ts|tsx)?$': 'ts-jest',
10 | '^.+\\.(js|jsx)$': 'babel-jest',
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/scripts/add-new-rules/interface.ts:
--------------------------------------------------------------------------------
1 | export interface IStackDriverError {
2 | jsonPayload: {
3 | data: string;
4 | message: "The phone number is not valid.";
5 | };
6 | }
7 |
8 | export interface ITwilioPhoneNumberInstance {
9 | countryCode: string;
10 | phoneNumber: string;
11 | }
12 |
13 | export interface Iiso3166 {
14 | alpha2: string;
15 | country_code: string;
16 | mobile_begin_with: string[];
17 | phone_number_lengths: number[];
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # =============== log ignore
2 | node_modules/
3 |
4 | # =========================== DO NOT touch below v1.0.0 ===============================
5 |
6 | # =============== RubyMine.gitignore
7 | # =============== PhPStorm.gitignore
8 | .idea
9 |
10 |
11 | # =============== OSX.gitignore
12 | .DS_Store
13 | .AppleDouble
14 | .LSOverride
15 |
16 | npm-debug.log
17 |
18 | .publishrc
19 |
20 | # ==== build output
21 | dist
22 | web
23 |
24 | coverage
25 |
26 | # ==== .env
27 | .env
28 |
29 | # ==== stackdriver
30 | stackdriver
31 |
32 | # === logs
33 | logs
34 |
35 | # === vscode
36 | .vscode
37 |
38 | test.js
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "lib": [
6 | "es6",
7 | "dom"
8 | ],
9 | "esModuleInterop": true,
10 | "allowJs": true,
11 | "declaration": true, /* Generates corresponding '.d.ts' file. */
12 | "outDir": "./dist", /* Redirect output structure to the directory. */
13 | "strict": true, /* Enable all strict type-checking options. */
14 | "noUnusedLocals": true, /* Report errors on unused locals. */
15 | "noUnusedParameters": true, /* Report errors on unused parameters. */
16 | "noImplicitReturns": false, /* Report error when not all code paths in function return a value. */
17 | },
18 | "include": ["src"],
19 | "exclude": ["node_modules", "**/__tests__/*"]
20 | }
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const webpack = require('webpack');
5 | const MinifyPlugin = require('babel-minify-webpack-plugin');
6 |
7 | module.exports = {
8 | mode: 'production',
9 | entry: './example/client/index.js',
10 | output: {
11 | path: path.resolve(__dirname),
12 | filename: 'app.js'
13 | },
14 | devServer: {
15 | static: {
16 | directory: path.join(__dirname)
17 | }
18 | },
19 | stats: {
20 | colors: true,
21 | modules: false
22 | },
23 | plugins: [
24 | new webpack.optimize.ModuleConcatenationPlugin(),
25 | new MinifyPlugin()
26 | ],
27 | module: {
28 | rules: [
29 | {
30 | test: /\.js$/,
31 | exclude: '/node_modules/',
32 | use: {
33 | loader: 'babel-loader',
34 | options: {
35 | presets: [['@babel/preset-env']]
36 | }
37 | }
38 | },
39 | ]
40 | },
41 | performance: {
42 | maxAssetSize: 500000,
43 | maxEntrypointSize: 500000
44 | }
45 | };
46 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const MinifyPlugin = require('babel-minify-webpack-plugin');
5 | const webpack = require('webpack');
6 |
7 | module.exports = {
8 | // devtool: 'source-map',
9 | entry: './lib/index.js',
10 | mode: 'production',
11 | output: {
12 | path: path.resolve(__dirname, 'dist'),
13 | filename: 'index.js',
14 | libraryTarget: 'umd',
15 | library: 'phone',
16 | globalObject: 'this'
17 | },
18 | plugins: [
19 | new webpack.optimize.ModuleConcatenationPlugin(),
20 | new MinifyPlugin()
21 | ],
22 | module: {
23 | rules: [
24 | {
25 | test: /\.js$/,
26 | include: [
27 | path.resolve(__dirname, 'lib')
28 | ],
29 | loader: 'babel-loader',
30 | options: {
31 | babelrc: false,
32 | presets: [
33 | ['env', {
34 | targets: {
35 | browsers: '>1%',
36 | node: '6.10'
37 | },
38 | modules: false,
39 | debug: true
40 | }]
41 | ]
42 | }
43 | }
44 | ]
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2020 AfterShip
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/__tests__/index.spec.ts:
--------------------------------------------------------------------------------
1 | import phone from '../src/index';
2 |
3 | describe('Parameter types', () => {
4 | test('using default parameter if not provided', () => {
5 | const result = phone('+1 (817) 569-8900', {});
6 |
7 | expect(result).toEqual({
8 | isValid: true,
9 | phoneNumber: '+18175698900',
10 | countryIso2: 'US',
11 | countryIso3: 'USA',
12 | countryCode: '+1'
13 | });
14 | });
15 |
16 | test('2nd parameter is undefined', () => {
17 | const result = phone('+1 (817) 569-8900');
18 |
19 | expect(result).toEqual({
20 | isValid: true,
21 | phoneNumber: '+18175698900',
22 | countryIso2: 'US',
23 | countryIso3: 'USA',
24 | countryCode: '+1'
25 | });
26 | });
27 |
28 | test('phone is not a string', () => {
29 | const result = phone(18175698900 as unknown as string);
30 |
31 | expect(result).toEqual({
32 | isValid: false,
33 | phoneNumber: null,
34 | countryIso2: null,
35 | countryIso3: null,
36 | countryCode: null
37 | });
38 | });
39 |
40 | test('country is not a string', () => {
41 | const result = phone('+18175698900', {
42 | country: 123 as unknown as string
43 | });
44 |
45 | expect(result).toEqual({
46 | isValid: true,
47 | phoneNumber: '+18175698900',
48 | countryIso2: 'US',
49 | countryIso3: 'USA',
50 | countryCode: '+1'
51 | });
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | ## AfterShip Phone browser usage
2 |
3 | We use the new `Array.prototype.find` function to simplify the coding. To support for older browser. You need to include the `polyfill` yourself. Here is live example to use `phone` browser. In this example we use `webpack`, `babel-polyfill` and `babel-preset-env` to simplify and optimize the build for target browser env. of cause you can using other services or package like `https://polyfill.io/`, `core-js`, etc.
4 |
5 | You can running this example by
6 |
7 | 1. git clone git@github.com:AfterShip/phone.git
8 | 2. yarn install
9 | 3. yarn run start:example
10 | 4. navigate to `localhost:8080`
11 |
12 | ```javascript
13 | // client/index.js
14 | import 'babel-polyfill';
15 | ```
16 |
17 | ```javascript
18 | // webpack.config.js
19 | 'use strict';
20 |
21 | const path = require('path');
22 |
23 | module.exports = {
24 | entry: './example/client/index.js',
25 | output: {
26 | path: path.resolve(__dirname),
27 | filename: 'app.js'
28 | },
29 | devServer: {
30 | contentBase: path.join(__dirname),
31 | stats: {
32 | colors: true,
33 | modules: false
34 | }
35 | },
36 | module: {
37 | rules: [
38 | {
39 | test: /\.js$/,
40 | loader: 'babel-loader',
41 | options: {
42 | babelrc: false,
43 | presets: [
44 | ['env', {
45 | targets: {
46 | browsers: '>1%'
47 | },
48 | useBuiltIns: true, // optimize build for the babel-polyfill
49 | debug: true,
50 | modules: false
51 | }]
52 | ]
53 | }
54 | }
55 | ]
56 | }
57 | };
58 |
59 | ```
60 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1_phone_number_format_issue.yml:
--------------------------------------------------------------------------------
1 | name: 1. Phone number format issue
2 | description: For any issues related to phone number format (such as not detecting a certain phone number).
3 | title: "[phone number format] "
4 | labels: ["phone-number-format"]
5 | assignees:
6 | - bossa573
7 | body:
8 | - type: markdown
9 | attributes:
10 | value: "## Creating a PR directly is much appreciated, thank you very much."
11 | - type: input
12 | id: country_region
13 | attributes:
14 | label: Country/Region
15 | description: in ISO 3166 alpha-3
16 | placeholder: e.g. USA, GBR, FRA, etc
17 | validations:
18 | required: true
19 | - type: input
20 | id: sample_phone_number
21 | attributes:
22 | label: Sample input with real phone format
23 | description: A dummy phone number is fine, do not leave personal info.
24 | placeholder: e.g. +13805553750, separated with comma for multiple phone numbers
25 | validations:
26 | required: true
27 | - type: textarea
28 | id: reference
29 | attributes:
30 | label: Reference docs/website
31 | description: Reference docs/website showing that the phone number format should be valid, government websites, 3rd party websites, or even Wikipedia pages are fine.
32 | placeholder:
33 | validations:
34 | required: true
35 | - type: checkboxes
36 | id: mobile_phone_number
37 | attributes:
38 | label: Mobile phone number
39 | description: Make sure your reported phone number is a mobile phone number. Landline, VoIP, or any other phone number formats are not supported and will not be accepted. If this checkbox is unchecked, the ticket will be closed.
40 | options:
41 | - label: I confirmed that the provided sample is a mobile phone number.
42 | validations:
43 | required: true
44 |
45 |
--------------------------------------------------------------------------------
/__tests__/test_match.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import { parse } from 'papaparse';
3 | import phone from '../src/index';
4 |
5 | interface TestCaseItem {
6 | input_phone: string;
7 | input_country: string;
8 | not_validate_prefix: string;
9 | output_phone: string;
10 | output_country_alpha2: string;
11 | output_country_alpha3: string;
12 | output_country_code: string;
13 | output_is_valid: string;
14 | desc1: string;
15 | desc2: string;
16 | test_desc: string;
17 | strict_detection: string;
18 | }
19 |
20 | const testCases = (parse(fs.readFileSync(`${__dirname}/data.csv`).toString(), {
21 | header: true
22 | })).data as TestCaseItem[];
23 |
24 | for (const testCase of testCases) {
25 | test(`${testCase.input_phone} / ${testCase.input_country} / ${testCase.not_validate_prefix}`, function() {
26 | const {input_phone: phoneNumber, input_country: country, not_validate_prefix: notValidatePrefix, strict_detection: strictDetectionString} = testCase;
27 | const validateMobilePrefix = !notValidatePrefix;
28 |
29 | let strictDetection = undefined;
30 |
31 | if (strictDetectionString === 'true') {
32 | strictDetection = true;
33 | } else if (strictDetectionString === 'false') {
34 | strictDetection = false;
35 | }
36 |
37 | const result = phone(phoneNumber, {
38 | country,
39 | validateMobilePrefix,
40 | strictDetection
41 | });
42 |
43 | if (testCase.output_is_valid === 'true') {
44 | expect(result).toEqual({
45 | isValid: true,
46 | phoneNumber: testCase.output_phone,
47 | countryIso2: testCase.output_country_alpha2,
48 | countryIso3: testCase.output_country_alpha3,
49 | countryCode: testCase.output_country_code
50 | });
51 | } else {
52 | expect(result).toEqual({
53 | isValid: false,
54 | phoneNumber: null,
55 | countryIso2: null,
56 | countryIso3: null,
57 | countryCode: null
58 | });
59 | }
60 | });
61 | }
62 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | AfterShip - phone
9 |
10 |
11 |
12 |
phone example
13 |
23 |
24 |
This username is available
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
42 |
43 |
44 |
45 |
46 |
47 |
Result
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/example/client/index.js:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill';
2 | import { phone } from '../../dist/';
3 |
4 | const input = document.getElementById('phone');
5 | const code = document.getElementById('code');
6 | const help = document.querySelector('.help');
7 | const country = document.getElementById('country');
8 | const validateMobilePrefix = document.getElementById('validateMobilePrefix');
9 | const strictDetection = document.getElementById('strictDetection');
10 |
11 | const formatPhone = (e) => {
12 | const inputPhoneNumber = input.value;
13 | const options = {
14 | validateMobilePrefix: validateMobilePrefix.checked,
15 | strictDetection: strictDetection.checked,
16 | };
17 |
18 | const countryValue = country.value.trim();
19 | if (countryValue) {
20 | options.country = countryValue;
21 | }
22 |
23 | const { phoneNumber, countryIso2, countryIso3, countryCode, isValid } = phone(inputPhoneNumber, options);
24 |
25 | if (!isValid) {
26 | [
27 | help,
28 | input,
29 | ].forEach(node => {
30 | node.classList.remove('is-success');
31 | node.classList.add('is-danger');
32 | });
33 | code.classList.add('is-hidden');
34 | code.textContent = '';
35 | help.textContent = 'This phone number is invalid';
36 | return;
37 | }
38 | [
39 | help,
40 | input,
41 | ].forEach(node => {
42 | node.classList.add('is-success');
43 | node.classList.remove('is-danger');
44 | });
45 |
46 | help.textContent = 'This phone number is valid';
47 | code.classList.remove('is-hidden');
48 | code.textContent = `
49 | isValid: ${isValid}
50 | Formatted Phone number: ${phoneNumber}
51 | Country code alpha 2: ${countryIso2}
52 | Country code alpha 3: ${countryIso3}
53 | Country calling code: ${countryCode}`;
54 | };
55 |
56 | input.addEventListener('input', formatPhone);
57 | country.addEventListener('input', formatPhone);
58 | validateMobilePrefix.addEventListener('click', formatPhone);
59 | strictDetection.addEventListener('click', formatPhone);
60 |
61 |
62 | input.dispatchEvent(new Event('input'));
63 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "phone",
3 | "version": "3.1.68",
4 | "description": "With a given country and phone number, validate and format the phone number to E.164 standard",
5 | "main": "./dist/index.js",
6 | "types": "./dist/index.d.ts",
7 | "engines": {
8 | "node": ">=12"
9 | },
10 | "directories": {
11 | "lib": "./src/lib"
12 | },
13 | "scripts": {
14 | "test": "jest",
15 | "test:watch": "jest --watch",
16 | "test:update": "jest --updateSnapshot",
17 | "lint": "eslint .",
18 | "build": "rimraf ./dist && tsc",
19 | "start:example": "yarn build && webpack serve --config ./example/webpack.config.js --progress",
20 | "dev": "yarn start:example",
21 | "prepublishOnly": "yarn build",
22 | "fix:numbers": "ts-node -P scripts/add-new-rules/tsconfig.json scripts/add-new-rules"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "https://github.com/aftership/phone"
27 | },
28 | "bugs": {
29 | "url": "https://github.com/aftership/phone/issues"
30 | },
31 | "devDependencies": {
32 | "@babel/preset-env": "^7.26.9",
33 | "@types/jest": "^29.5.14",
34 | "@types/node": "^22.14.1",
35 | "@types/papaparse": "^5.3.15",
36 | "babel-cli": "^6.26.0",
37 | "babel-loader": "^10.0.0",
38 | "babel-minify-webpack-plugin": "^0.3.1",
39 | "babel-polyfill": "^6.26.0",
40 | "babel-preset-env": "^1.7.0",
41 | "dotenv": "^16.5.0",
42 | "eslint": "^9.24.0",
43 | "eslint-config-aftership": "^7.0.0",
44 | "eslint-plugin-import": "^2.31.0",
45 | "idempotent-babel-polyfill": "^7.4.4",
46 | "jest": "^29.7.0",
47 | "lodash": "^4.17.21",
48 | "papaparse": "^5.5.2",
49 | "rimraf": "^6.0.1",
50 | "ts-jest": "^29.3.2",
51 | "ts-node": "^10.9.2",
52 | "twilio": "^5.5.2",
53 | "typescript": "^5.8.3",
54 | "webpack": "^5.99.5",
55 | "webpack-cli": "^6.0.1",
56 | "webpack-dev-server": "^5.2.1"
57 | },
58 | "keywords": [
59 | "phone",
60 | "e.164"
61 | ],
62 | "author": "AfterShip",
63 | "license": "MIT",
64 | "dependencies": {}
65 | }
66 |
--------------------------------------------------------------------------------
/scripts/add-new-rules/index.ts:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 |
3 | const accountSid = process.env.TWILIO_SID;
4 | const authToken = process.env.TWILIO_TOKEN;
5 |
6 | ~function() {
7 | if (!accountSid || !authToken) {
8 | throw new Error('Please set environment TWILIO_SID & TWILIO_TOKEN first!');
9 | }
10 | }();
11 |
12 | import { IStackDriverError, ITwilioPhoneNumberInstance, Iiso3166 } from './interface';
13 | import * as _find from 'lodash/find';
14 | import * as fs from 'fs';
15 | import * as path from 'path';
16 |
17 | const errors: IStackDriverError[] = require('./stackdriver/errors.json');
18 | const error_phone_array: string[] = require('./stackdriver/error_list.json');
19 | const iso3166s: Iiso3166[] = require('../../lib/iso3166Data');
20 | const client = require('twilio')(accountSid, authToken);
21 |
22 | ~async function() {
23 | const error_numbers = [...new Set(
24 | errors.map(({ jsonPayload: {data} }) => data)
25 | .concat(error_phone_array)
26 | .map(data => {
27 | const formatted_number = data.replace(/[\s|-]+/g, '');
28 | return formatted_number;
29 | }),
30 | )];
31 | const errorStream = fs.createWriteStream(path.resolve(__dirname, './logs/error.log'));
32 | const twilioPromises = error_numbers.map(num => {
33 | return client
34 | .lookups
35 | .phoneNumbers(num)
36 | .fetch()
37 | .catch(err => {
38 | errorStream.write(`${num}:\n ${JSON.stringify(err, null, 4)}\n`);
39 | });
40 | });
41 |
42 | const lookups = await Promise.all(twilioPromises).then(v => {
43 | errorStream.end();
44 | return v;
45 | });
46 | const filteredLookups: ITwilioPhoneNumberInstance[] = lookups.filter(v => v);
47 | const deduplatedLookups = [...new Set(
48 | filteredLookups.map(({ phoneNumber, countryCode }) => `${countryCode}:${phoneNumber}`),
49 | )].map(str => {
50 | const [countryCode, phoneNumber] = str.split(':');
51 | return {countryCode, phoneNumber};
52 | });
53 |
54 | const sumByAlpha2 = deduplatedLookups.reduce((sum, { countryCode, phoneNumber }) => {
55 | const [matched_item] = iso3166s.filter(({ alpha2 }) => alpha2 === countryCode);
56 | const {
57 | alpha2,
58 | country_code,
59 | mobile_begin_with,
60 | phone_number_lengths,
61 | } = matched_item;
62 | const localPhoneNumber = phoneNumber.replace('+' + country_code, '');
63 | const isBeginWithRight = mobile_begin_with.length === 0 || mobile_begin_with.some(num => new RegExp(`^${num}`).test(localPhoneNumber));
64 | const new_mobile_begin_with = isBeginWithRight ? mobile_begin_with: mobile_begin_with.concat(localPhoneNumber.slice(0, mobile_begin_with[0].length));
65 | const new_phone_number_lengths = [...new Set(phone_number_lengths.concat(localPhoneNumber.length))];
66 |
67 | const sum_alpha2 = sum[alpha2];
68 | return {
69 | ...sum,
70 | [alpha2]: {
71 | ...matched_item,
72 | mobile_begin_with: sum_alpha2 ?
73 | [...new Set([
74 | ...new_mobile_begin_with,
75 | ...sum_alpha2.mobile_begin_with
76 | ])] :
77 | new_mobile_begin_with,
78 | phone_number_lengths: sum_alpha2 ?
79 | [...new Set([
80 | ...new_phone_number_lengths,
81 | ...sum_alpha2.phone_number_lengths,
82 | ])] :
83 | new_phone_number_lengths
84 | }
85 | };
86 | }, {});
87 |
88 | const resultStream = fs.createWriteStream(path.resolve(__dirname, './logs/result.log'));
89 | resultStream.write(JSON.stringify(sumByAlpha2, null, 4));
90 | resultStream.end();
91 | }();
92 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # v1.0.4 2015-05-06
2 |
3 |
4 | # ------------------------------------------------------------------------------
5 | # Add your custom excludes below
6 | # ------------------------------------------------------------------------------
7 | .nyc_output/
8 | .npmrc
9 | .vscode/
10 | .tern-project
11 | lib/
12 | src/
13 | script/
14 | example/
15 | .babelrc
16 | .eslintignore
17 | .flowconfig
18 | .gitignore
19 | .publishrc
20 | .stylelintrc
21 | example.config.json
22 | gulfile.babel.js
23 | jest.config.json
24 | litmus-support-clients.js
25 | flow-typed
26 | __tests__/
27 | webpack.config.js
28 | .eslintrc
29 |
30 |
31 | # =============== log ignore builtAssets
32 |
33 | /tmp/*
34 | /builtAssets/*
35 | *.log
36 | .nyc_output/
37 | coverage/
38 |
39 | # =========================== DO NOT touch below v1.0.3 ===============================
40 |
41 |
42 | node_modules
43 |
44 | # =============== RubyMine.gitignore
45 | # =============== PhPStorm.gitignore
46 | .idea
47 |
48 |
49 | # =============== OSX.gitignore
50 | .DS_Store
51 | .AppleDouble
52 | .LSOverride
53 |
54 | # Thumbnails
55 | ._*
56 |
57 | # =============== # Windows image file caches
58 | Thumbs.db
59 | ehthumbs.db
60 |
61 | # Folder config file
62 | Desktop.ini
63 |
64 | # Recycle Bin used on file shares
65 | $RECYCLE.BIN/
66 |
67 | # Except the .htpassed
68 | !.htpasswd
69 | !.nodemonignore
70 |
71 | npm-debug.log
72 |
73 | dump.rdb
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | # FROM https://github.com/niftylettuce/node-email-templates/blob/master/.gitignore
83 |
84 | # ------------------------------------------------------------------------------
85 | # Common Node files and folders
86 | # https://github.com/github/gitignore/blob/master/Node.gitignore
87 | # ------------------------------------------------------------------------------
88 |
89 | lib-cov
90 | *.seed
91 | *.log
92 | *.csv
93 | *.dat
94 | *.out
95 | *.pid
96 | *.gz
97 |
98 | pids
99 | log
100 | results
101 |
102 | node_modules
103 | npm-debug.log
104 |
105 |
106 | # ------------------------------------------------------------------------------
107 | # Nodemon
108 | # ------------------------------------------------------------------------------
109 |
110 | .monitor
111 |
112 |
113 | # ------------------------------------------------------------------------------
114 | # JSHint
115 | # ------------------------------------------------------------------------------
116 |
117 | jshint
118 |
119 |
120 | # ------------------------------------------------------------------------------
121 | # Numerous always-ignore extensions
122 | # ------------------------------------------------------------------------------
123 |
124 | *.diff
125 | *.err
126 | *.orig
127 | *.rej
128 | *.swo
129 | *.swp
130 | *.vi
131 | *~
132 | *.sass-cache
133 |
134 |
135 | # ------------------------------------------------------------------------------
136 | # Files from other repository control systems
137 | # ------------------------------------------------------------------------------
138 |
139 | .hg
140 | .svn
141 | .CVS
142 |
143 |
144 | # ------------------------------------------------------------------------------
145 | # PHPStorm, RubyMine
146 | # ------------------------------------------------------------------------------
147 |
148 | .idea
149 |
150 |
151 | # ------------------------------------------------------------------------------
152 | # OS X and other IDE's folder attributes
153 | # ------------------------------------------------------------------------------
154 |
155 | .DS_Store
156 | Thumbs.db
157 | .cache
158 | .project
159 | .settings
160 | .tmproj
161 | *.esproj
162 | nbproject
163 | *.sublime-project
164 | *.sublime-workspace
165 |
166 |
167 | # ------------------------------------------------------------------------------
168 | # Dreamweaver added files
169 | # ------------------------------------------------------------------------------
170 |
171 | _notes
172 | dwsync.xml
173 |
174 |
175 | # ------------------------------------------------------------------------------
176 | # Komodo
177 | # ------------------------------------------------------------------------------
178 |
179 | *.komodoproject
180 | .komodotools
181 | bower_components
182 |
183 | config/examples.json
184 | config.json
185 |
186 | # ------------------------------------------------------------------------------
187 | # customized scripts
188 | # ------------------------------------------------------------------------------
189 | scripts
190 |
191 | test.js
192 | test_generate.js
193 | .github
194 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import countryPhoneData from './data/country_phone_data';
2 | import {
3 | findCountryPhoneDataByCountry,
4 | findCountryPhoneDataByPhoneNumber,
5 | validatePhoneISO3166,
6 | CountryPhoneDataItem,
7 | } from './lib/utility';
8 |
9 | export interface PhoneInvalidResult {
10 | isValid: false;
11 | phoneNumber: null;
12 | countryIso2: null;
13 | countryIso3: null;
14 | countryCode: null;
15 | }
16 |
17 | export interface PhoneValidResult {
18 | isValid: true;
19 | phoneNumber: string;
20 | countryIso2: string;
21 | countryIso3: string;
22 | countryCode: string;
23 | }
24 |
25 | export type PhoneResult = PhoneInvalidResult | PhoneValidResult;
26 |
27 | /**
28 | * @typedef {Object} Option
29 | * @property {string=} country - country code in ISO3166 alpha 2 or 3
30 | * @property {boolean=} validateMobilePrefix - true to validate phone number prefix
31 | * @property {boolean=} strictDetection - true to disable remove truck code and detection logic
32 | *
33 | * @param {string} phoneNumber - phone number
34 | * @param {Option} option
35 | * @returns {{phoneNumber: string|null, countryIso2: string|null, countryIso3: string|null}}
36 | */
37 | export default function phone(phoneNumber: string, {
38 | country = '',
39 | validateMobilePrefix = true,
40 | strictDetection = false
41 | }: {
42 | country?: string;
43 | validateMobilePrefix?: boolean;
44 | strictDetection?: boolean;
45 | } = {}): PhoneResult {
46 | const invalidResult = {
47 | isValid: false as const,
48 | phoneNumber: null,
49 | countryIso2: null,
50 | countryIso3: null,
51 | countryCode: null
52 | };
53 |
54 | let processedPhoneNumber = (typeof phoneNumber !== 'string') ? '' : phoneNumber.trim();
55 | const processedCountry = (typeof country !== 'string') ? '' : country.trim();
56 | const hasPlusSign = Boolean(processedPhoneNumber.match(/^\+/));
57 |
58 | // remove any non-digit character, included the +
59 | processedPhoneNumber = processedPhoneNumber.replace(/\D/g, '');
60 |
61 | let foundCountryPhoneData = findCountryPhoneDataByCountry(processedCountry);
62 |
63 | if (!foundCountryPhoneData) {
64 | return invalidResult;
65 | }
66 |
67 | let defaultCountry = false;
68 |
69 | // if country provided, only reformat the phone number
70 | if (processedCountry) {
71 | // remove leading 0s for all countries except 'CIV', 'COG'
72 | if (!['CIV', 'COG'].includes(foundCountryPhoneData.alpha3)) {
73 | processedPhoneNumber = processedPhoneNumber.replace(/^0+/, '');
74 | }
75 |
76 | // if input 89234567890, RUS, remove the 8
77 | if (foundCountryPhoneData.alpha3 === 'RUS' && processedPhoneNumber.length === 11 && processedPhoneNumber.match(/^89/) !== null) {
78 | processedPhoneNumber = processedPhoneNumber.replace(/^8+/, '');
79 | }
80 |
81 | // if there's no plus sign and the phone number length is one of the valid length under country phone data
82 | // then assume there's no country code, hence add back the country code
83 | if (!hasPlusSign && foundCountryPhoneData.phone_number_lengths.includes(processedPhoneNumber.length)) {
84 | processedPhoneNumber = `${foundCountryPhoneData.country_code}${processedPhoneNumber}`;
85 | }
86 | } else if (hasPlusSign) {
87 | // if there is a plus sign but no country provided
88 | // try to find the country phone data by the phone number
89 | const { exactCountryPhoneData, possibleCountryPhoneData } = findCountryPhoneDataByPhoneNumber(processedPhoneNumber, validateMobilePrefix);
90 |
91 | if (exactCountryPhoneData) {
92 | foundCountryPhoneData = exactCountryPhoneData;
93 | } else if (possibleCountryPhoneData && !strictDetection) {
94 | // for some countries, the phone number usually includes one trunk prefix for local use
95 | // The UK mobile phone number ‘07911 123456’ in international format is ‘+44 7911 123456’, so without the first zero.
96 | // 8 (AAA) BBB-BB-BB, 0AA-BBBBBBB
97 | // the numbers should be omitted in international calls
98 |
99 | foundCountryPhoneData = possibleCountryPhoneData;
100 | processedPhoneNumber = foundCountryPhoneData.country_code + processedPhoneNumber.replace(new RegExp(`^${foundCountryPhoneData.country_code}\\d`), '');
101 | } else {
102 | foundCountryPhoneData = null;
103 | }
104 | } else if (foundCountryPhoneData.phone_number_lengths.indexOf(processedPhoneNumber.length) !== -1) {
105 | // B: no country, no plus sign --> treat it as USA
106 | // 1. check length if == 11, or 10, if 10, add +1, then go go D
107 | // no plus sign, no country is given. then it must be USA
108 | // iso3166 = iso3166_data[0]; already assign by the default value
109 | processedPhoneNumber = `1${processedPhoneNumber}`;
110 | defaultCountry = true;
111 | }
112 |
113 | if (!foundCountryPhoneData) {
114 | return invalidResult;
115 | }
116 |
117 | let validateResult = validatePhoneISO3166(processedPhoneNumber, foundCountryPhoneData, validateMobilePrefix, hasPlusSign);
118 |
119 | if (validateResult) {
120 | return {
121 | isValid: true as const,
122 | phoneNumber: `+${processedPhoneNumber}`,
123 | countryIso2: foundCountryPhoneData.alpha2,
124 | countryIso3: foundCountryPhoneData.alpha3,
125 | countryCode: `+${foundCountryPhoneData.country_code}`
126 | };
127 | }
128 |
129 | if (defaultCountry) {
130 | // also try to validate against CAN for default country, as CAN is also start with +1
131 | foundCountryPhoneData = findCountryPhoneDataByCountry('CAN') as CountryPhoneDataItem;
132 | validateResult = validatePhoneISO3166(processedPhoneNumber, foundCountryPhoneData, validateMobilePrefix, hasPlusSign);
133 | if (validateResult) {
134 | return {
135 | isValid: true as const,
136 | phoneNumber: `+${processedPhoneNumber}`,
137 | countryIso2: foundCountryPhoneData.alpha2,
138 | countryIso3: foundCountryPhoneData.alpha3,
139 | countryCode: `+${foundCountryPhoneData.country_code}`
140 | };
141 | }
142 | }
143 |
144 | return invalidResult;
145 | };
146 |
147 | export {
148 | phone,
149 | countryPhoneData,
150 | };
151 |
--------------------------------------------------------------------------------
/src/lib/utility.ts:
--------------------------------------------------------------------------------
1 | import countryPhoneData from '../data/country_phone_data';
2 |
3 | type GetArrayElementType = T extends readonly (infer U)[] ? U : never;
4 | export type CountryPhoneDataItem = GetArrayElementType;
5 |
6 | /**
7 | * @param {string=} country - country code alpha 2 or 3
8 | * @returns {{country_code: string, alpha2: string, country_name: string, alpha3: string, mobile_begin_with, phone_number_lengths: [number]}|{country_code: string, alpha2: string, country_name: string, alpha3: string, mobile_begin_with: [string, string, string, string], phone_number_lengths: [number]}|{country_code: string, alpha2: string, country_name: string, alpha3: string, mobile_begin_with: [string], phone_number_lengths: [number]}|{country_code: string, alpha2: string, country_name: string, alpha3: string, mobile_begin_with: [string], phone_number_lengths: [number]}|{country_code: string, alpha2: string, country_name: string, alpha3: string, mobile_begin_with: [string, string], phone_number_lengths: [number]}|null}
9 | */
10 | export function findCountryPhoneDataByCountry(country: string) {
11 | // if no country provided, assume it's USA
12 | if (!country) {
13 | return countryPhoneData.find(countryPhoneDatum => countryPhoneDatum.alpha3 === 'USA') || null;
14 | }
15 |
16 | if (country.length === 2) {
17 | return countryPhoneData.find(countryPhoneDatum => country.toUpperCase() === countryPhoneDatum.alpha2) || null;
18 | }
19 |
20 | if (country.length === 3) {
21 | return countryPhoneData.find(countryPhoneDatum => country.toUpperCase() === countryPhoneDatum.alpha3) || null;
22 | }
23 |
24 | return countryPhoneData.find(countryPhoneDatum => country.toUpperCase() === countryPhoneDatum.country_name.toUpperCase()) || null;
25 | }
26 |
27 | export function findExactCountryPhoneData(phoneNumber: string, validateMobilePrefix: boolean, countryPhoneDatum: CountryPhoneDataItem) {
28 | // check if the phone number length match any one of the length config
29 | const phoneNumberLengthMatched = countryPhoneDatum.phone_number_lengths.some(length => {
30 | // as the phone number must include the country code,
31 | // but countryPhoneDatum.phone_number_lengths is the length without country code
32 | // therefore need to add back countryPhoneDatum.country_code.length to length
33 | return (countryPhoneDatum.country_code.length + length === phoneNumber.length);
34 | });
35 |
36 | if (!phoneNumberLengthMatched) {
37 | return null;
38 | }
39 |
40 | // if no need to validate mobile prefix or the country data does not have mobile begin with
41 | // pick the current one as the answer directly
42 | if (!countryPhoneDatum.mobile_begin_with.length || !validateMobilePrefix) {
43 | return countryPhoneDatum;
44 | }
45 |
46 | // if the mobile begin with is correct, pick as the correct answer
47 | if (countryPhoneDatum.mobile_begin_with.some(beginWith => {
48 | return phoneNumber.match(new RegExp('^' + countryPhoneDatum.country_code + beginWith));
49 | })) {
50 | return countryPhoneDatum;
51 | }
52 |
53 | return null;
54 | }
55 |
56 | export function findPossibleCountryPhoneData(phoneNumber: string, validateMobilePrefix: boolean, countryPhoneDatum: CountryPhoneDataItem) {
57 | // check if the phone number length match any one of the length config
58 | const phoneNumberLengthMatched = countryPhoneDatum.phone_number_lengths.some(length => {
59 | // the phone number must include the country code
60 | // countryPhoneDatum.phone_number_lengths is the length without country code
61 | // + 1 is assuming there is an unwanted trunk code prepended to the phone number
62 | return (countryPhoneDatum.country_code.length + length + 1 === phoneNumber.length);
63 | });
64 |
65 | if (!phoneNumberLengthMatched) {
66 | return null;
67 | }
68 |
69 | // if no need to validate mobile prefix or the country data does not have mobile begin with
70 | // pick the current one as the answer directly
71 | if (!countryPhoneDatum.mobile_begin_with.length || !validateMobilePrefix) {
72 | return countryPhoneDatum;
73 | }
74 |
75 | // if the mobile begin with is correct, pick as the correct answer
76 | // match another \d for the unwanted trunk code prepended to the phone number
77 | if (countryPhoneDatum.mobile_begin_with.some(beginWith => {
78 | return phoneNumber.match(new RegExp('^' + countryPhoneDatum.country_code + '\\d?' + beginWith));
79 | })) {
80 | return countryPhoneDatum;
81 | }
82 | }
83 |
84 | /**
85 | * get country phone data by phone number
86 | * the phone number must include country code as the complete phone number includes the plus sign
87 | * @param phoneNumber
88 | * @param validateMobilePrefix
89 | * @returns {{exactCountryPhoneData: (*), possibleCountryPhoneData: (*)}}
90 | */
91 | export function findCountryPhoneDataByPhoneNumber(phoneNumber: string, validateMobilePrefix: boolean) {
92 | let exactCountryPhoneData;
93 | let possibleCountryPhoneData;
94 |
95 | for (const countryPhoneDatum of countryPhoneData) {
96 | // if the country code is wrong, skip directly
97 | if (!phoneNumber.match(new RegExp('^' + countryPhoneDatum.country_code))) {
98 | continue;
99 | }
100 |
101 | // process only if exact match not found yet
102 | if (!exactCountryPhoneData) {
103 | exactCountryPhoneData = findExactCountryPhoneData(phoneNumber, validateMobilePrefix, countryPhoneDatum);
104 | }
105 |
106 | if (!possibleCountryPhoneData) {
107 | possibleCountryPhoneData = findPossibleCountryPhoneData(phoneNumber, validateMobilePrefix, countryPhoneDatum);
108 | }
109 | }
110 |
111 | return {
112 | exactCountryPhoneData,
113 | possibleCountryPhoneData
114 | }
115 | }
116 |
117 |
118 | /**
119 | *
120 | * @param {string} phone - phone number without plus sign, with or without country calling code
121 | * @param {Object} countryPhoneDatum - iso 3166 data
122 | * @param {String} countryPhoneDatum.country_code - country calling codes
123 | * @param {Array} countryPhoneDatum.phone_number_lengths - all available phone number lengths for this country
124 | * @param {Array} countryPhoneDatum.mobile_begin_with - mobile begin with number
125 | * @param {boolean} validateMobilePrefix - true if we skip mobile begin with checking
126 | * @param {boolean} plusSign - true if the input contains a plus sign
127 | * @returns {*|boolean}
128 | */
129 | export function validatePhoneISO3166(phone: string, countryPhoneDatum: CountryPhoneDataItem, validateMobilePrefix: boolean, plusSign: boolean) {
130 | if (!countryPhoneDatum.phone_number_lengths) {
131 | return false;
132 | }
133 |
134 | // remove country calling code from the phone number
135 | const phoneWithoutCountry = phone.replace(new RegExp('^' + countryPhoneDatum.country_code), '');
136 |
137 | // if the phone number have +, countryPhoneDatum detected,
138 | // but the phone number does not have country calling code
139 | // then should consider the phone number as invalid
140 | if (plusSign && countryPhoneDatum && phoneWithoutCountry.length === phone.length) {
141 | return false;
142 | }
143 |
144 | const phone_number_lengths = countryPhoneDatum.phone_number_lengths;
145 | const mobile_begin_with = countryPhoneDatum.mobile_begin_with;
146 |
147 | const isLengthValid = phone_number_lengths.some(length => phoneWithoutCountry.length === length);
148 | // some country doesn't have mobile_begin_with
149 | const isBeginWithValid = mobile_begin_with.length ?
150 | mobile_begin_with.some(beginWith => phoneWithoutCountry.match(new RegExp('^' + beginWith))):
151 | true;
152 |
153 | return isLengthValid && (!validateMobilePrefix || isBeginWithValid);
154 | }
155 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Phone · [](http://makeapullrequest.com) [](https://app.fossa.com/projects/git%2Bgithub.com%2FAfterShip%2Fphone?ref=badge_shield)
2 |
3 | ## What is phone?
4 | `phone` is used to normalize mobile phone numbers into E.164 format.
5 |
6 | A common problem is that users normally input phone numbers in this way:
7 |
8 | ```
9 | `(817) 569-8900` or
10 | `817569-8900` or
11 | `1(817) 569-8900` or
12 | `+1(817) 569-8900` or ...
13 | ```
14 |
15 | We always want:
16 |
17 | ```
18 | +18175698900
19 | ```
20 |
21 | ## Install
22 | ```
23 | npm install phone
24 |
25 | // or
26 |
27 | yarn add phone
28 | ```
29 |
30 | ## Usage
31 |
32 | ```javascript
33 | const {phone} = require('phone');
34 |
35 | // or
36 |
37 | import {phone} from 'phone';
38 | ```
39 |
40 | ### 1. Simple usage
41 |
42 | ```javascript
43 | phone('+852 6569-8900');
44 | // { isValid: true, phoneNumber: '+85265698900', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
45 | ```
46 |
47 | ### 2. With Country
48 |
49 | ```javascript
50 | phone('+1(817) 569-8900', {country: ''});
51 | // { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1'}
52 |
53 | phone('(817) 569-8900', {country: 'USA'});
54 | // { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1'}
55 |
56 | phone('(817) 569-8900', {country: 'HKG'});
57 | // { isValid: false }
58 | // not a valid HKG mobile phone number
59 |
60 | phone('+1(817) 569-8900', {country: 'HKG'});
61 | // { isValid: false }
62 | // not a valid HKG mobile phone number
63 |
64 | phone('6123-6123', {country: 'HKG'});
65 | // { isValid: true, phoneNumber: '+85261236123', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
66 | ```
67 |
68 | ### 3. Without country code and no phone prefix
69 |
70 | If both country code and country phone prefix are not provided, the phone number will be treated as USA or Canada by default.
71 |
72 | ```javascript
73 | phone('(817) 569-8900');
74 | // { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1' }
75 |
76 | phone('(817) 569-8900', {country: ''});
77 | // { isValid: true, phoneNumber: '+18175698900', countryIso2: 'US', countryIso3: 'USA', countryCode: '+1' }
78 |
79 | phone('780-569-8900', {country: null});
80 | // { isValid: true, phoneNumber: '+17805698900', countryIso2: 'CA', countryIso3: 'CAN', countryCode: '+1' }
81 | // 780 is a Canada phone prefix
82 |
83 | phone('6123-6123', {country: null});
84 | // { isValid: false }
85 | // as default country is USA / CAN and the phone number does not fit such countries' rules
86 | ```
87 |
88 | ### 4. With country code / phone prefix, but no `+` sign
89 |
90 | Even you input a valid phone number with a valid prefix, if there is no plus sign, it will not work as expected:
91 |
92 | ```javascript
93 | phone('85291234567');
94 | // or
95 | phone('85291234567', {country: null});
96 |
97 | // { isValid: false }
98 | ```
99 |
100 | `852` is a valid Hong Kong phone prefix, and `91234567` is a valid Hong Kong mobile phone number.
101 | However, there is no plus sign provided, the module will assume the phone number is a USA or Canada phone number,
102 | hence no result will be found.
103 |
104 | If you know you have provided country phone prefix, make sure you also provide a plus sign:
105 |
106 | ```javascript
107 | phone('+85291234567');
108 | // or
109 | phone('+85291234567', {country: null});
110 |
111 | // { isValid: true, phoneNumber: '+85291234567', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
112 | ```
113 |
114 | or, if you know the country, and only want to reformat the phone number to E.164 format:
115 |
116 | ```javascript
117 | phone('91234567', {country: 'HKG'})
118 | // { isValid: true, phoneNumber: '+85291234567', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
119 | ```
120 |
121 | ### 5. Skipping phone number initial digit checking
122 |
123 | If you want to skip phone number initial digit checking, set `validateMobilePrefix` to false:
124 |
125 | ```javascript
126 | phone('+(852) 2356-4902');
127 | // { isValid: false }
128 | // '2' is a Hong Kong landline phone number prefix, not a valid mobile phone number prefix
129 |
130 | phone('+(852) 2356-4902', {validateMobilePrefix: true});
131 | // { isValid: false }
132 | // same as above, default value of validateMobilePrefix = true
133 |
134 | phone('+(852) 2356-4902', {validateMobilePrefix: false});
135 | // { isValid: true, phoneNumber: '+85223564902', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
136 | // skipping mobile prefix checking
137 | ```
138 |
139 | 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:
140 |
141 | ```javascript
142 | phone('+(852) 0356-4902', {validateMobilePrefix: false});
143 | // { isValid: true, phoneNumber: '+85203564902', countryIso2: 'HK', countryIso3: 'HKG', countryCode: '+852' }
144 | // even the phone number start with `0` is not a valid landline phone number
145 | ```
146 | Note that the module does not have the capability to determine if the prefix is a valid `landline` prefix number.
147 |
148 | ### 6. Trunk Code Detection Logic
149 |
150 | For some phone numbers, such as this sample UK phone number:
151 |
152 | ```
153 | +44 07911 123456
154 | ```
155 |
156 | There is a trunk code `0` after the country code `+44` so that it is unable to match any correct country.
157 |
158 | Hence the module will try to remove 1 digit after the country code,
159 |
160 | and try to detect:
161 |
162 | ```
163 | +44 7911 123456
164 | ```
165 |
166 | and it would become a valid UK phone number now.
167 |
168 | ```javascript
169 | phone('+4407911 123456')
170 | // { isValid: true, phoneNumber: '+447911123456', countryIso2: 'GB', countryIso3: 'GBR', countryCode: '+44' }
171 | ```
172 |
173 | If you want to disable this behavior,
174 | please set `strictDetection` to `true`:
175 |
176 | ```javascript
177 | phone('+4407911 123456', {strictDetection: true})
178 | // { isValid: false }
179 | ```
180 |
181 | ## API
182 |
183 | ```typescript
184 | const {phone} = require('phone');
185 |
186 | // or
187 |
188 | import {phone} from 'phone';
189 |
190 | phone(phoneNumber: string, { country, validateMobilePrefix, strictDetection }?: {
191 | country?: string;
192 | validateMobilePrefix?: boolean;
193 | strictDetection?: boolean;
194 | })
195 | ```
196 |
197 | #### Input
198 |
199 | Parameter | Type | Required | Default | Description
200 | --- | --- | --- | --- | ---
201 | phoneNumber | String | Yes | - | The phone number text you want to process
202 | country | String | No | null | Provided country code in iso-3166 alpha 2 or 3 format
203 | validateMobilePrefix | Boolean | No | true | Set to false if you want to skip phone number initial digit checking
204 | strictDetection | Boolean | No | false | Set to true if you want to disable trunk code detection logic.
205 |
206 | #### Returns
207 |
208 | ```typescript
209 | type PhoneResult = PhoneInvalidResult | PhoneValidResult;
210 |
211 | interface PhoneValidResult {
212 | isValid: true;
213 | phoneNumber: string;
214 | countryIso2: string;
215 | countryIso3: string;
216 | countryCode: string;
217 | }
218 |
219 | interface PhoneInvalidResult {
220 | isValid: false;
221 | phoneNumber: null;
222 | countryIso2: null;
223 | countryIso3: null;
224 | countryCode: null;
225 | }
226 | ```
227 |
228 | Parameter | Type | Description
229 | --- | --- | ---
230 | isValid | Boolean | To indicate if the result valid
231 | phoneNumber | String or null | Normalized phone number in E.164 format
232 | countryIso2 | String or null | Detected phone number country code in iso-3166 alpha 2 format
233 | countryIso3 | String or null | Detected phone number country code in iso-3166 alpha 3 format
234 | countryCode | String or null | Detected phone number country calling code with `+` sign
235 |
236 | [comment]: <> (## Demo)
237 |
238 | [comment]: <> ([Try it on CodeSandbox](https://codesandbox.io/s/phone-browser-example-react-o5vt5?file=/src/App.js))
239 |
240 | ## Test
241 |
242 | ```
243 | yarn test
244 | ```
245 |
246 | ## Interactive Web Example
247 |
248 | ```
249 | yarn start:example
250 | ```
251 |
252 | or
253 |
254 | ```
255 | yarn dev
256 | ```
257 |
258 | And then visit http://localhost:8080
259 |
260 | ## Build
261 |
262 | ```
263 | yarn build
264 | ```
265 |
266 | [comment]: <> (## Supported Environment)
267 |
268 | [comment]: <> (We currently transpile script to work on target environments for which the browser's global usage is >1%, and Node.js 6.10+.)
269 |
270 | [comment]: <> (You can check browser usage statistics on the [browserlist](http://browserl.ist/?q=%3E1%25).)
271 |
272 | [comment]: <> (You may need polyfills for some older browsers; for more details, please read the `example/README` file.)
273 |
274 |
275 | ## FAQ
276 |
277 | 1. Does `phone` do any logical validation?
278 |
279 | Yes. If you provide `country`, and the phone number does not start with a `+` sign, the module will validate both `phone_number_lengths` and `mobile_begin_with`
280 |
281 | 2. Why is `phone` returning an invalid result for a valid phone number?
282 |
283 | By default, the function validates **mobile phone numbers only**. It checks the phone number prefix and length to determine validity. If you want to skip the mobile prefix validation (for example, when checking landline numbers), you can set `validateMobilePrefix` to `false`.
284 |
285 | > **Note:** Disabling this check does **not** enable "landline mode". The library does **not** support landline number validation, as it only contains validation rules for mobile numbers. If a landline number has a different length or format than a mobile number, the library may not process it correctly.
286 |
287 | If you believe the result is incorrect, please submit a ticket to improve our validation rules.
288 |
289 | 3. Why is `phone` returning an object with `isValid = false` instead of returning a null directly?
290 |
291 | Returning an object (with `isValid = false`) allows us to extend the response format in the future, making it more flexible for adding additional information about invalid results.
292 |
293 | ## Migrate from v2
294 |
295 | The interface of v3 has been changed for better usability, maintainability, and flexibility, this shows all the changes from v2:
296 |
297 | #### Function Interface
298 |
299 | Version | Interface
300 | --- | ---
301 | v2 | phone(phoneNumber, country, allowLandline)
302 | v3 | phone(phoneNumber,{country: String, validateMobilePrefix: Boolean, strictDetection: Boolean})
303 |
304 | #### Function Response
305 |
306 | Version | Result | Interface
307 | --- | --- | ---
308 | v2 | - | [phoneNumber, country]
309 | v3 | Valid | {isValid: true, phoneNumber: string, countryIso2: string, countryIso3: string, countryCode: string}
310 | v3 | Invalid | {isValid: false, phoneNumber: null, countryIso2: null, countryIso3: null, countryCode: null}
311 |
312 | #### allowLandline vs validateMobilePrefix
313 |
314 | `allowLandline` in v2 is essentially equal to `validateMobilePrefix` in v3, however, the value is the opposite.
315 |
316 | 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.
317 |
318 | To avoid misleading information, the parameter name has been changed to `validateMobilePrefix`, and the input value is the opposite, while `validateMobilePrefix = false` means "Skip the mobile phone number prefix validation".
319 |
320 |
321 | ## Phone Number Format Improvement
322 |
323 | We strive to ensure this package functions well across diverse scenarios. However, please note that the phone number formats may not be updated proactively or regularly, as this is a manual task and we lack a dedicated incentive for continuous updates. If you find any incorrect rules for a country or other specific case, please create a pull request to inform us.
324 |
325 | When submitting pull requests to add or modify phone number formats, it is essential to include reference information such as PDFs, websites, etc. **PRs submitted without references will not be accepted.** Thank you for your understanding and cooperation.
326 |
327 | **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.
328 |
329 | ## License
330 |
331 | This project is licensed under the [MIT license](https://github.com/AfterShip/phone/blob/master/LICENSE).
332 |
333 |
334 | [](https://app.fossa.com/projects/git%2Bgithub.com%2FAfterShip%2Fphone?ref=badge_large)
335 |
--------------------------------------------------------------------------------
/__tests__/data.csv:
--------------------------------------------------------------------------------
1 | input_phone,input_country,not_validate_prefix,output_phone,output_country_alpha2,output_country_alpha3,output_country_code,output_is_valid,desc1,desc2,test_desc,strict_detection
2 | (852) 569-8900,,,,,,,false,Testing input parameter Phone,Test 1,"returns ",
3 | +1 (817) 569-8900,,,+18175698900,US,USA,+1,true,,Test 2,"returns +18175698900,USA",
4 | +852 6569-8900,,,+85265698900,HK,HKG,+852,true,,Test 3,"returns +85265698900,HKG",
5 | +852 6569-8900,HKG,,+85265698900,HK,HKG,+852,true,,Test 4,"returns +85265698900,HKG",
6 | ,HKG,,,,,,false,,Test 5,"returns ",
7 | +225 0534567888,CIV,,+2250534567888,CI,CIV,+225,true,,Test 6,should remove the leadings zero when country is CIV,
8 | +242 012345678,COG,,+242012345678,CG,COG,+242,true,,,should remove the leadings zero when country is COG,
9 | (852) 569-8900,,,,,,,false,Testing USA Phone,Test 1,"returns ",
10 | +1 (817) 569-8900,,,+18175698900,US,USA,+1,true,,Test 2,"returns +18175698900,USA",
11 | +1 (817) 569-8900,,,+18175698900,US,USA,+1,true,,Test 3,"returns +18175698900,USA",
12 | 2121234567,,,+12121234567,US,USA,+1,true,,Test 4,"returns +12121234567,USA",
13 | 22-6569-8900,,,+12265698900,CA,CAN,+1,true,,"Test 5, does not provide country, should match canada phone number","returns +12265698900,CAN",
14 | 22-5569-8900,,,+12255698900,US,USA,+1,true,,Test 6,"returns +12255698900,USA",
15 | +1 (817) 569-8900,United States,,+18175698900,US,USA,+1,true,,Test 7,"returns +18175698900,USA",
16 | +1 (817) 569-8900,"United States ",,+18175698900,US,USA,+1,true,,Test 8,"returns +18175698900,USA",
17 | +1 (817) 569-8900,USA,,+18175698900,US,USA,+1,true,,Test 9,"returns +18175698900,USA",
18 | +1 (817) 569-8900,"USA ",,+18175698900,US,USA,+1,true,,Test 10,"returns +18175698900,USA",
19 | +1 (817) 569-8900,US,,+18175698900,US,USA,+1,true,,Test 11,"returns +18175698900,USA",
20 | +1 (817) 569-8900," US",,+18175698900,US,USA,+1,true,,Test 12,"returns +18175698900,USA",
21 | +1 (817) 569-8900,HKG,,,,,,false,,Test 13,"returns ",
22 | +1 (888) 569-8900,,,+18885698900,US,USA,+1,true,,Test 14,"returns +18885698900,USA",
23 | +1905-555-1234,,,+19055551234,CA,CAN,+1,true,Testing default Canada phone number,"Test 1, does not provide country, should match canada phone number","returns +19055551234,CAN",
24 | 519-555-1234,,,+15195551234,CA,CAN,+1,true,,"Test 2, does not provide country and plus sign, should match canada phone number","returns +15195551234,CAN",
25 | 1519-555-1234,,,,,,,false,,"Test 3, does not provide country and plus sign but with ""1"", should match nothing","returns ",
26 | +1 340 1234 567,VIR,,+13401234567,VI,VIR,+1,true,Testing +1 but NOT in USA,+1 340 United States Virgin Islands,"returns +13401234567,VIR",
27 | +1 670 1234 567,MNP,,+16701234567,MP,MNP,+1,true,,+1 670 Northern Mariana Islands,"returns +16701234567,MNP",
28 | +1 671 1234 567,GUM,,+16711234567,GU,GUM,+1,true,,+1 671 Guam,"returns +16711234567,GUM",
29 | +1 684 1234 567,ASM,,,,,,false,,+1 684 American Samoa,"returns ",
30 | +1 684 2584 567,ASM,,+16842584567,AS,ASM,+1,true,,+1 684 American Samoa,"returns +16842584567,ASM",
31 | +1 684 7334 567,ASM,,+16847334567,AS,ASM,+1,true,,+1 684 American Samoa,"returns +16847334567,ASM",
32 | +1 787 1234 567,PRI,,+17871234567,PR,PRI,+1,true,,+1 787 / 939 Puerto Rico,"returns +17871234567,PRI",
33 | +1 939 1234 567,PRI,,+19391234567,PR,PRI,+1,true,,+1 787 / 939 Puerto Rico,"returns +19391234567,PRI",
34 | +1 242 1234 567,BHS,,+12421234567,BS,BHS,+1,true,,+1 242 Bahamas,"returns +12421234567,BHS",
35 | +1 246 1234 567,BRB,,+12461234567,BB,BRB,+1,true,,+1 246 Barbados,"returns +12461234567,BRB",
36 | +1 264 1234 567,AIA,,,,,,false,,+1 264 Anguilla,"returns ",
37 | +1 264 5234 567,AIA,,+12645234567,AI,AIA,+1,true,,+1 264 Anguilla,"returns +12645234567,AIA",
38 | +1 264 7234 567,AIA,,+12647234567,AI,AIA,+1,true,,+1 264 Anguilla,"returns +12647234567,AIA",
39 | +1 268 1234 567,ATG,,,,,,false,,+1 268 Antigua and Barbuda,"returns ",
40 | +1 268 7234 567,ATG,,+12687234567,AG,ATG,+1,true,,+1 268 Antigua and Barbuda,"returns +12687234567,ATG",
41 | +1 284 1234 567,VGB,,+12841234567,VG,VGB,+1,true,,+1 284 British Virgin Islands,"returns +12841234567,VGB",
42 | +1 345 1234 567,CYM,,+13451234567,KY,CYM,+1,true,,+1 345 Cayman Islands,"returns +13451234567,CYM",
43 | +1 441 1234 567,BMU,,,,,,false,,+1 441 Bermuda,"returns ",
44 | +1 441 3234 567,BMU,,+14413234567,BM,BMU,+1,true,,+1 441 Bermuda,"returns +14413234567,BMU",
45 | +1 441 5234 567,BMU,,+14415234567,BM,BMU,+1,true,,+1 441 Bermuda,"returns +14415234567,BMU",
46 | +1 441 7234 567,BMU,,+14417234567,BM,BMU,+1,true,,+1 441 Bermuda,"returns +14417234567,BMU",
47 | +1 473 1234 567,GRD,,+14731234567,GD,GRD,+1,true,,+1 473 Grenada,"returns +14731234567,GRD",
48 | +1 649 1234 567,TCA,,,,,,false,,+1 649 Turks and Caicos Islands,"returns ",
49 | +1 649 2234 567,TCA,,+16492234567,TC,TCA,+1,true,,+1 649 Turks and Caicos Islands,"returns +16492234567,TCA",
50 | +1 664 1234 567,MSR,,+16641234567,MS,MSR,+1,true,,+1 664 Montserrat,"returns +16641234567,MSR",
51 | +1 721 1234 567,SXM,,+17211234567,SX,SXM,+1,true,,+1 721 Sint Maarten,"returns +17211234567,SXM",
52 | +1 758 1234 567,LCA,,+17581234567,LC,LCA,+1,true,,+1 758 Saint Lucia,"returns +17581234567,LCA",
53 | +1 767 1234 567,DMA,,+17671234567,DM,DMA,+1,true,,+1 767 Dominica,"returns +17671234567,DMA",
54 | +1 784 1234 567,VCT,,+17841234567,VC,VCT,+1,true,,+1 784 Saint Vincent and the Grenadines,"returns +17841234567,VCT",
55 | +1 809 1234 567,DOM,,+18091234567,DO,DOM,+1,true,,+1 809 / 829 / 849 Dominican Republic,"returns +18091234567,DOM",
56 | +1 829 1234 567,DOM,,+18291234567,DO,DOM,+1,true,,+1 809 / 829 / 849 Dominican Republic,"returns +18291234567,DOM",
57 | +1 849 1234 567,DOM,,+18491234567,DO,DOM,+1,true,,+1 809 / 829 / 849 Dominican Republic,"returns +18491234567,DOM",
58 | +1 868 1234 567,TTO,,+18681234567,TT,TTO,+1,true,,+1 868 Trinidad and Tobago,"returns +18681234567,TTO",
59 | +1 869 1234 567,KNA,,+18691234567,KN,KNA,+1,true,,+1 869 Saint Kitts and Nevis,"returns +18691234567,KNA",
60 | +1 876 1234 567,JAM,,+18761234567,JM,JAM,+1,true,,+1 876 Jamaica,"returns +18761234567,JAM",
61 | +52 1 762 100 9517,,,+5217621009517,MX,MEX,+52,true,Testing MEX Phone,Test 1,"returns +5217621009517,MEX",
62 | +52 1 762 100 9517,MEX,,+5217621009517,MX,MEX,+52,true,,Test 2,"returns +5217621009517,MEX",
63 | +52 1 762 100 9517,USA,,,,,,false,,Test 3,"returns ",
64 | +52 1 762 100 9517,Mexico,,+5217621009517,MX,MEX,+52,true,,Test 4,"returns +5217621009517,MEX",
65 | +52 1 762 100 9517,United States,,,,,,false,,Test 5,"returns ",
66 | +52 62 100 9517,,,,,,,false,,Test 6,"returns ",
67 | +52 62 100 9517,MEX,,,,,,false,,Test 7,"returns ",
68 | +52 62 100 9517,USA,,,,,,false,,Test 8,"returns ",
69 | +52 62 100 9517,Mexico,,,,,,false,,Test 9,"returns ",
70 | +52 62 100 9517,United States,,,,,,false,,Test 10,"returns ",
71 | 52762 100 9517,,,,,,,false,,Test 11,"returns ",
72 | 762 100 9517,MEX,,+527621009517,MX,MEX,+52,true,,Test 12,"returns +527621009517,MEX",
73 | 762 100 9517,MEXINVALID,,,,,,false,,Test 13,"returns ",
74 | 762 100 9517,Mexico,,+527621009517,MX,MEX,+52,true,,Test 14,"returns +527621009517,MEX",
75 | 762 100 9517,Mexico Invalid,,,,,,false,,Test 15,"returns ",
76 | 6123-6123,HKG,,+85261236123,HK,HKG,+852,true,Testing HKG Phone Quick Test,Test 1,"returns +85261236123,HKG",
77 | +55 11 9 6123 1234,BRA,,+5511961231234,BR,BRA,+55,true,Testing BRA Phone Quick Test,Test 1,"returns +5511961231234,BRA",
78 | +55 69 8 6123 1234,BRA,,+5569861231234,BR,BRA,+55,false,,Test 4,"returns +5569861231234,BRA",
79 | +55 65 9 9123 4567,BRA,,+5565991234567,BR,BRA,+55,true,,Test 5,"returns +5565991234567,BRA",
80 | +5599988311895,BRA,,+5599988311895,BR,BRA,+55,true,,Test 6,"returns +5599988311895,BRA",
81 | +1-787-672-9999,PRI,,+17876729999,PR,PRI,+1,true,Testing PRI Phone Quick Test,Test 1,"returns +17876729999,PRI",
82 | 17876729999,PRI,,+17876729999,PR,PRI,+1,true,,Test 2,"returns +17876729999,PRI",
83 | 7876729999,PRI,,+17876729999,PR,PRI,+1,true,,Test 3,"returns +17876729999,PRI",
84 | 89234567890,RUS,,+79234567890,RU,RUS,+7,true,Testing RUS Phone Quick Test,Test 1,"returns +79234567890,RUS",
85 | +79234567890,RUS,,+79234567890,RU,RUS,+7,true,,Test 2,"returns +79234567890,RUS",
86 | +79234567890,,,+79234567890,RU,RUS,+7,true,,Test 3,"returns +79234567890,RUS",
87 | +70234567890,RUS,,,,,,false,,Test 4,"returns ",
88 | +79234567890,USA,,,,,,false,,Test 5,"returns ",
89 | 0812345678,THA,,+66812345678,TH,THA,+66,true,Testing THA Phone Quick Test,Test 1,"returns +66812345678,THA",
90 | 0912345678,THA,,+66912345678,TH,THA,+66,true,,Test 2,"returns +66912345678,THA",
91 | 812345678,THA,,+66812345678,TH,THA,+66,true,,Test 3,"returns +66812345678,THA",
92 | 0714795861,TZA,,+255714795861,TZ,TZA,+255,true,Testing TZA Phone Quick Test,Test 1,"returns +255714795861,TZA",
93 | 0684795861,TZA,,+255684795861,TZ,TZA,+255,true,,Test 2,"returns +255684795861,TZA",
94 | 714795861,TZA,,+255714795861,TZ,TZA,+255,true,,Test 3,"returns +255714795861,TZA",
95 | +77012345678,KAZ,,+77012345678,KZ,KAZ,+7,true,Testing KAZ Phone Quick Test,Test 1,"returns +77012345678,KAZ",
96 | +77412345678,KAZ,,+77412345678,KZ,KAZ,+7,true,,Test 2,"returns +77412345678,KAZ",
97 | +77712345678,KAZ,,+77712345678,KZ,KAZ,+7,true,,Test 3,"returns +77712345678,KAZ",
98 | +507 61234567,PAN,,+50761234567,PA,PAN,+507,true,Testing PAN Phone Quick Test,Test 1,"returns +50761234567,PAN",
99 | +507 51234567,PAN,,,,,,false,,Test 2,"returns ",
100 | +230 51234567,,,+23051234567,MU,MUS,+230,true,Testing MUS Phone Quick Test,Test 1,"returns +23051234567,MUS",
101 | +230 5123-4567,,,+23051234567,MU,MUS,+230,true,,Test 2,"returns +23051234567,MUS",
102 | +230 6123-4567,,,,,,,false,,Test 3,"returns ",
103 | +230 6123-4567,HKG,,,,,,false,,Test 4,"returns ",
104 | +86 199 51343779,,,+8619951343779,CN,CHN,+86,true,Testing CHN Phone Quick Test,Test for pattern 199,"returns +8619951343779,CHN",
105 | +86 198 51343779,,,+8619851343779,CN,CHN,+86,true,,Test for pattern 198,"returns +8619851343779,CHN",
106 | +86 166 51343779,,,+8616651343779,CN,CHN,+86,true,,Test for pattern 166,"returns +8616651343779,CHN",
107 | +54 233 123 4567,,,+542331234567,AR,ARG,+54,true,Testing ARG numbers,Test for number without 9 prefix,"returns +542331234567,ARG",
108 | +54 9 233 123 4567,,,+542331234567,AR,ARG,+54,true,,Test for number with 9 prefix,"returns +542331234567,ARG",
109 | +54 13 123 456,,,+5413123456,AR,ARG,+54,true,,Test for number with 2 + 6 digit,"returns +5413123456,ARG",
110 | +54 13 123 4567,,,+54131234567,AR,ARG,+54,true,,Test for number with 2 + 7 digit,"returns +54131234567,ARG",
111 | +54 13 123 45678,,,+541312345678,AR,ARG,+54,true,,Test for number with 2 + 8 digit,"returns +541312345678,ARG",
112 | +54 133 123 45678,,,+5413312345678,AR,ARG,+54,true,,Test for number with 3 + 8 digit,"returns +5413312345678,ARG",
113 | +54 1334 123 45678,,,+54133412345678,AR,ARG,+54,true,,Test for number with 4 + 8 digit,"returns +54133412345678,ARG",
114 | +299 555299,,,+299555299,GL,GRL,+299,true,Testing GRL numbers,Test for numbers starting with 5,"returns +299555299,GRL",
115 | +299 233299,,,+299233299,GL,GRL,+299,true,,Test for numbers starting with 2,"returns +299233299,GRL",
116 | +299 321000,,,,,,,false,,Test for landlines,"returns ",
117 | +95 9 55 00000,,,+9595500000,MM,MMR,+95,true,Testing MMR Phone,"Test for 8 digits mobile numbers ","returns +9595500000,MMR",
118 | +95 9 30 000 000,,,+95930000000,MM,MMR,+95,true,,"Test for 9 digits mobile numbers ","returns +95930000000,MMR",
119 | +95 9 426 00 0000,,,+959426000000,MM,MMR,+95,true,,Test 10 digits mobile numbers,"returns +959426000000,MMR",
120 | +95 1 1234567,,,,,,,false,,Test land lines,"returns ",
121 | +1 367 1234567,,,+13671234567,CA,CAN,+1,true,Testing Canada Phone,Should return result when it matches mobile_begin_with,"returns +13671234567,CAN",
122 | +1 111 1234567,,,,,,,false,,Should not return result when it does not match mobile_begin_with,"returns ",
123 | +237 612345678,,,+237612345678,CM,CMR,+237,true,Testing Cameroon Phone,Should return result when it matches mobile_begin_with,"returns +237612345678,CMR",
124 | +237 112345678,,,,,,,false,,Should not return result when it does not match mobile_begin_with,"returns ",
125 | +687 812345,,,+687812345,NC,NCL,+687,true,Testing New Caledonia Phone,Should return result when it matches mobile_begin_with,"returns +687812345,NCL",
126 | +687 512345,,,+687512345,NC,NCL,+687,true,Testing New Caledonia Phone,Should return result when NCL number starts with 5,"returns +687512345,NCL",
127 | +687 112345,,,,,,,false,,Should not return result when it does not match mobile_begin_with,"returns ",
128 | +380 73 123 45 67,,,+380731234567,UA,UKR,+380,true,Testing Ukraine Phone,Should return result when it matches mobile_begin_with,"returns +380731234567,UKR",
129 | +380 11 123 45 67,,,,,,,false,,Should not return result when it does not match mobile_begin_with,"returns ",
130 | +61(0)488888888,,,+61488888888,AU,AUS,+61,true,,test phone with trunk prefix,Austrilia phone with trunk prefix (0),
131 | +7(8)9234567890,,,+79234567890,RU,RUS,+7,true,,,Russian Federation phone with trunk prefix (8),
132 | +691(0)1234567,,,+6911234567,FM,FSM,+691,true,,,Micronesia with trunk prefix (0),
133 | +298 212345,,,+298212345,FO,FRO,+298,true,,test phone with no mobile_begin_with,Test 1,
134 | +17215201993,,,+17215201993,SX,SXM,+1,true,,[CORE-1562] add new phone number rules for `+17215201993、+5164518135、+6062311120、+16782069397`,Test +17215201993,
135 | +5164518135,,,+5164518135,,,,false,,,Test +5164518135,
136 | +6062311120,,,+6062311120,MY,MYS,+60,true,,,Test +6062311120,
137 | +16782069397,,,+16782069397,US,USA,+1,true,,,Test +16782069397,
138 | +85293785433,,,+85293785433,HK,HKG,+852,true,,Landline phone number test,"Test mobile phone number, should success",
139 | +85223785433,,,,,,,false,,,"Test landline phone number without 3rd parameter, should fail",
140 | +85223785433,,true,+85223785433,HK,HKG,+852,true,,,"Test landline phone number with 3rd parameter, should success",
141 | 85293785433,HKG,,+85293785433,HK,HKG,+852,true,,,"Test mobile phone number without plus sign, should success",
142 | 85223785433,HKG,,,,,,false,,,"Test landline phone number without plus sign without 3rd parameter, should fail",
143 | 85223785433,HKG,true,+85223785433,HK,HKG,+852,true,,,"Test landline phone number without plus sign with 3rd parameter, should success",
144 | 93785433,HKG,,+85293785433,HK,HKG,+852,true,,,"Test mobile phone number without plus sign nor country code, should success",
145 | 23785433,HKG,,,,,,false,,,"Test landline phone number without plus sign nor country code without 3rd parameter, should fail",
146 | 23785433,HKG,true,+85223785433,HK,HKG,+852,true,,,"Test landline phone number without plus sign nor country code with 3rd parameter, should success",
147 | +85293785433,HKG,,+85293785433,HK,HKG,+852,true,,#190 phone number with plus sign BUT without country code (intentionally wrong input),"1. with +, country code, and country, should get the result",
148 | 85293785433,HKG,,+85293785433,HK,HKG,+852,true,,,"2. without +, with country code, with country, should get the result",
149 | +93785433,HKG,,,,,,false,,,"3a. with +, without country code, with country, should get empty array",
150 | +41414141,NO,,,,,,false,,,"3b. with +, without country code, with country, should get empty array",
151 | +2011231234,USA,,,,,,false,,,"3c. with +, without country code, with country, should get empty array",
152 | 93785433,HKG,,+85293785433,HK,HKG,+852,true,,,"4a. without +, without country code, with country, should get the result",
153 | 2014125632,USA,,+12014125632,US,USA,+1,true,,,"4b. without +, without country code, with country, should get the result",
154 | 41414141,NO,,+4741414141,NO,NOR,+47,true,,,"4c. without +, without country code, with country, should get the result",
155 | +4741414141,,,+4741414141,NO,NOR,+47,true,,,"5a. with +, with country code, without country, should get the result",
156 | +85296587452,,,+85296587452,HK,HKG,+852,true,,,"5b. with +, with country code, without country, should get the result",
157 | +13612145896,,,+13612145896,US,USA,+1,true,,,"5c. with +, with country code, without country, should get the result",
158 | 13612145896,,,+13612145896,US,USA,+1,true,,,"6a. without +, with country code, without country, should get the result",
159 | 4741414141,,,+14741414141,CA,CAN,+1,true,,,"6b. without +, with country code, without country, will get canada",
160 | 4761414141,,,,,,,false,,,"6b. without +, with country code, without country, default USA and should get empty result",
161 | 96587452,,,,,,,false,,,"6c. without +, with country code, without country, default USA and should get empty result",
162 | +96587452,,,,,,,false,,,"7a. with +, without country code, without country, should get empty result",
163 | +3612145896,,,,,,,false,,,"7b. with +, without country code, without country, should get empty result",
164 | +41414141,,,,,,,false,,,"7c. with +, without country code, without country, should get empty result",
165 | 96587452,,,,,,,false,,,"8a. without +, without country code, without country, should get empty result",
166 | 3612145896,,,+13612145896,US,USA,+1,true,,,"8b. without +, without country code, without country, default USA, should get result",
167 | 41414141,,,,,,,false,,,"8c. without +, without country code, without country, should get empty result",
168 | +44 079111 23456,,,+447911123456,GB,GBR,+44,true,,Test strict detect switch,"returns +447911123456,GBR",
169 | +44 079111 23456,,,,,,,false,,,returns empty result for strict detect,true
170 | +44 079111 23456,,,+447911123456,GB,GBR,+44,true,,"returns +447911123456,GBR for explicitly false",false,
171 | +4710000000,,,,,,,false,Testing NO / SJ numbers,Should not be valid NO or SJ,returns,
172 | +4779000000,,,+4779000000,SJ,SJM,+47,true,,Should be SJ (Svalbard / Jan Mayen),"returns +4779000000,SJM",
173 | +36 50 1234567,,,+36501234567,HU,HUN,+36,true,,Hungary phone number 50 prefix,"returns +36501234567,HUN",
174 | +996 226123123,,,+996226123123,KG,KGZ,+996,true,,,Kyrgyzstan test 1,
175 | +996 206123123,,,+996206123123,KG,KGZ,+996,true,,,Kyrgyzstan test 2,
176 | +996 312583123,,,+996312583123,KG,KGZ,+996,true,,,Kyrgyzstan test 4,
177 | +996 312973123,,,+996312973123,KG,KGZ,+996,true,,,Kyrgyzstan test 5,
178 | +996 912973123,,,+996912973123,KG,KGZ,+996,true,,,Kyrgyzstan test 6,
179 | +996 312573123,,,,,,,false,,,Kyrgyzstan test 7,
180 | 048 999 999,XK,,+38348999999,XK,XKX,+383,true,Testing Kosovo number,,,
181 | +1 3292021234,,,+13292021234,US,USA,+1,true,,#389 (1),"returns +13292021234,USA",
182 | +1 4722021234,,,+14722021234,US,USA,+1,true,,#389 (2),"returns +14722021234,USA",
183 | +599 4161234,,,+5994161234,BQ,BES,+599,true,,,"returns BES 1",
184 | +599 7001234,,,+5997001234,BQ,BES,+599,true,,,"returns BES 2",
185 | +599 9583 1517,,,+59995831517,CW,CUW,+599,true,,,"returns ANT 1",
186 | +599 9683 1517,,,+59996831517,CW,CUW,+599,true,,,"returns ANT 2",
187 | +1 (353) 555-8900,,,+13535558900,US,USA,+1,true,,353 area code,"returns +13535558900,USA",
188 | +1 (645) 555-1234,,,+16455551234,US,USA,+1,true,,645 area code,"returns +16455551234,USA",
189 | +387 620 12345,,,+38762012345,BA,BIH,+387,true,,Bosnia and Herzegovina 8 digit number,"returns +38762012345,BIH",
190 | +387 6031 12345,,,+387603112345,BA,BIH,+387,true,,Bosnia and Herzegovina 9 digit number,"returns +387603112345,BIH",
191 |
--------------------------------------------------------------------------------
/test_generate.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | let allOutput = [
4 | [
5 | 'input_phone',
6 | 'input_country',
7 | 'validate_prefix',
8 | 'output_phone',
9 | 'output_country_alpha2',
10 | 'output_country_alpha3',
11 | 'desc1',
12 | 'desc2',
13 | 'test_desc'
14 | ]
15 | ];
16 | let outputLine = [];
17 | let description = [];
18 |
19 | const countryPhoneData = require('../data/country_phone_data');
20 |
21 | function describe(desc, func) {
22 | description.push(desc);
23 | func();
24 | }
25 |
26 | function test(desc, func) {
27 | func();
28 | if (description.length === 0) {
29 | description = ['', ''].concat(description);
30 | }
31 | if (description.length === 1) {
32 | description = [''].concat(description);
33 | }
34 | outputLine = outputLine.concat(description);
35 | outputLine.push(desc);
36 | allOutput.push(outputLine);
37 | outputLine = [];
38 | description = [];
39 | }
40 |
41 | function expect(output) {
42 | return {
43 | toEqual: function(result) {
44 | if (!result || result.length === 0) {
45 | outputLine.push('');
46 | outputLine.push('');
47 | outputLine.push('');
48 | } else {
49 | const countryIso3 = result[1];
50 | const countryIso2 = countryPhoneData.find((d) => d.alpha3 === countryIso3).alpha2;
51 | outputLine.push(result[0]);
52 | outputLine.push(countryIso2);
53 | outputLine.push(result[1]);
54 | }
55 | }
56 | };
57 | }
58 |
59 | function phone(arg1, arg2, arg3) {
60 | outputLine.push(arg1 || '');
61 | outputLine.push(arg2 || '');
62 | outputLine.push(arg3 || '');
63 | }
64 |
65 | describe('Testing input parameter Phone', () => {
66 | describe('Test 1', () => {
67 | const number = '(852) 569-8900';
68 | const result = [];
69 | test('returns ' + result, () => {
70 | expect(phone(number)).toEqual(result);
71 | });
72 | });
73 |
74 | describe('Test 2', () => {
75 | const number = '+1 (817) 569-8900';
76 | const result = ['+18175698900', 'USA'];
77 | test('returns ' + result, () => {
78 | expect(phone(number)).toEqual(result);
79 | });
80 | });
81 |
82 |
83 | describe('Test 3', () => {
84 | const number = '+852 6569-8900';
85 | const result = ['+85265698900', 'HKG'];
86 | test('returns ' + result, () => {
87 | expect(phone(number)).toEqual(result);
88 | });
89 | });
90 |
91 | describe('Test 4', () => {
92 | const number = '+852 6569-8900';
93 | const country = 'HKG';
94 | const result = ['+85265698900', 'HKG'];
95 | test('returns ' + result, () => {
96 | expect(phone(number, country)).toEqual(result);
97 | });
98 | });
99 |
100 | describe('Test 5', () => {
101 | const number = null;
102 | const country = 'HKG';
103 | const result = [];
104 | test('returns ' + result, () => {
105 | expect(phone(number, country)).toEqual(result);
106 | });
107 | });
108 |
109 | describe('Test 6', () => {
110 | test('should remove the leadings zero when country is CIV', () => {
111 | expect(phone('+225 05345678', 'CIV')).toEqual(['+22505345678', 'CIV']);
112 | });
113 |
114 | test('should remove the leadings zero when country is COG', () => {
115 | expect(phone('+242 012345678', 'COG')).toEqual(['+242012345678', 'COG']);
116 | });
117 | });
118 | });
119 |
120 | describe('Testing USA Phone', () => {
121 | describe('Test 1', () => {
122 | const number = '(852) 569-8900';
123 | const country = '';
124 | const result = [];
125 | test('returns ' + result, () => {
126 | expect(phone(number, country)).toEqual(result);
127 | });
128 | });
129 |
130 | describe('Test 2', () => {
131 | const number = '+1 (817) 569-8900';
132 | const country = '';
133 | const result = ['+18175698900', 'USA'];
134 |
135 | test('returns ' + result, () => {
136 | expect(phone(number, country)).toEqual(result);
137 | });
138 | });
139 |
140 | describe('Test 3', () => {
141 | const number = '+1 (817) 569-8900';
142 | const country = null;
143 | const result = ['+18175698900', 'USA'];
144 | test('returns ' + result, () => {
145 | expect(phone(number, country)).toEqual(result);
146 | });
147 | });
148 |
149 |
150 | describe('Test 4', () => {
151 | const number = '2121234567';
152 | const country = '';
153 | const result = ['+12121234567', 'USA'];
154 | test('returns ' + result, () => {
155 | expect(phone(number, country)).toEqual(result);
156 | });
157 | });
158 |
159 | describe('Test 5, does not provide country, should match canada phone number', () => {
160 | const number = '22-6569-8900';
161 | const country = '';
162 | const result = ['+12265698900', 'CAN'];
163 | test('returns ' + result, () => {
164 | expect(phone(number, country)).toEqual(result);
165 | });
166 | });
167 |
168 | describe('Test 6', () => {
169 | const number = '22-5569-8900';
170 | const country = '';
171 | const result = ['+12255698900', 'USA'];
172 | test('returns ' + result, () => {
173 | expect(phone(number, country)).toEqual(result);
174 | });
175 | });
176 |
177 | describe('Test 7', () => {
178 | const number = '+1 (817) 569-8900';
179 | const country = 'United States';
180 | const result = ['+18175698900', 'USA'];
181 | test('returns ' + result, () => {
182 | expect(phone(number, country)).toEqual(result);
183 | });
184 | });
185 |
186 | describe('Test 8', () => {
187 | const number = '+1 (817) 569-8900';
188 | const country = 'United States ';
189 | const result = ['+18175698900', 'USA'];
190 | test('returns ' + result, () => {
191 | expect(phone(number, country)).toEqual(result);
192 | });
193 | });
194 |
195 | describe('Test 9', () => {
196 | const number = '+1 (817) 569-8900';
197 | const country = 'USA';
198 | const result = ['+18175698900', 'USA'];
199 |
200 | test('returns ' + result, () => {
201 | expect(phone(number, country)).toEqual(result);
202 | });
203 | });
204 |
205 | describe('Test 10', () => {
206 | const number = '+1 (817) 569-8900';
207 | const country = 'USA ';
208 | const result = ['+18175698900', 'USA'];
209 | test('returns ' + result, () => {
210 | expect(phone(number, country)).toEqual(result);
211 | });
212 | });
213 |
214 | describe('Test 11', () => {
215 | const number = '+1 (817) 569-8900';
216 | const country = 'US';
217 | const result = ['+18175698900', 'USA'];
218 | test('returns ' + result, () => {
219 | expect(phone(number, country)).toEqual(result);
220 | });
221 | });
222 |
223 | describe('Test 12', () => {
224 | const number = '+1 (817) 569-8900';
225 | const country = ' US';
226 | const result = ['+18175698900', 'USA'];
227 | test('returns ' + result, () => {
228 | expect(phone(number, country)).toEqual(result);
229 | });
230 | });
231 |
232 |
233 | describe('Test 13', () => {
234 | const number = '+1 (817) 569-8900';
235 | const country = 'HKG';
236 | const result = [];
237 | test('returns ' + result, () => {
238 | expect(phone(number, country)).toEqual(result);
239 | });
240 | });
241 |
242 | describe('Test 14', () => {
243 | const number = '+1 (888) 569-8900';
244 | const result = ['+18885698900', 'USA'];
245 | test('returns ' + result, () => {
246 | expect(phone(number)).toEqual(result);
247 | });
248 | });
249 | });
250 |
251 | describe('Testing default Canada phone number', () => {
252 | describe('Test 1, does not provide country, should match canada phone number', () => {
253 | const number = '+1905-555-1234';
254 | const country = '';
255 | const result = ['+19055551234', 'CAN'];
256 | test('returns ' + result, () => {
257 | expect(phone(number, country)).toEqual(result);
258 | });
259 | });
260 |
261 | describe('Test 2, does not provide country and plus sign, should match canada phone number', () => {
262 | const number = '519-555-1234';
263 | const country = '';
264 | const result = ['+15195551234', 'CAN'];
265 | test('returns ' + result, () => {
266 | expect(phone(number, country)).toEqual(result);
267 | });
268 | });
269 |
270 | describe('Test 3, does not provide country and plus sign but with "1", should match nothing', () => {
271 | const number = '1519-555-1234';
272 | const country = '';
273 | const result = [];
274 | test('returns ' + result, () => {
275 | expect(phone(number, country)).toEqual(result);
276 | });
277 | });
278 | });
279 |
280 | describe('Testing +1 but NOT in USA', () => {
281 | describe('+1 340 United States Virgin Islands', () => {
282 | const number = '+1 340 1234 567';
283 | const country = 'VIR';
284 | const result = ['+13401234567', 'VIR'];
285 | test('returns ' + result, () => {
286 | expect(phone(number, country)).toEqual(result);
287 | });
288 | });
289 |
290 | describe('+1 670 Northern Mariana Islands', () => {
291 | const number = '+1 670 1234 567';
292 | const country = 'MNP';
293 | const result = ['+16701234567', 'MNP'];
294 | test('returns ' + result, () => {
295 | expect(phone(number, country)).toEqual(result);
296 | });
297 | });
298 |
299 |
300 | describe('+1 671 Guam', () => {
301 | const number = '+1 671 1234 567';
302 | const country = 'GUM';
303 | const result = ['+16711234567', 'GUM'];
304 | test('returns ' + result, () => {
305 | expect(phone(number, country)).toEqual(result);
306 | });
307 | });
308 |
309 | describe('+1 684 American Samoa', () => {
310 | const number = '+1 684 1234 567';
311 | const country = 'ASM';
312 | const result = [];
313 | test('returns ' + result, () => {
314 | expect(phone(number, country)).toEqual(result);
315 | });
316 | });
317 |
318 | describe('+1 684 American Samoa', () => {
319 | const number = '+1 684 2584 567';
320 | const country = 'ASM';
321 | const result = ['+16842584567', 'ASM'];
322 | test('returns ' + result, () => {
323 | expect(phone(number, country)).toEqual(result);
324 | });
325 | });
326 |
327 | describe('+1 684 American Samoa', () => {
328 | const number = '+1 684 7334 567';
329 | const country = 'ASM';
330 | const result = ['+16847334567', 'ASM'];
331 | test('returns ' + result, () => {
332 | expect(phone(number, country)).toEqual(result);
333 | });
334 | });
335 |
336 | describe('+1 787 / 939 Puerto Rico', () => {
337 | const number = '+1 787 1234 567';
338 | const country = 'PRI';
339 | const result = ['+17871234567', 'PRI'];
340 | test('returns ' + result, () => {
341 | expect(phone(number, country)).toEqual(result);
342 | });
343 | });
344 |
345 | describe('+1 787 / 939 Puerto Rico', () => {
346 | const number = '+1 939 1234 567';
347 | const country = 'PRI';
348 | const result = ['+19391234567', 'PRI'];
349 | test('returns ' + result, () => {
350 | expect(phone(number, country)).toEqual(result);
351 | });
352 | });
353 |
354 | describe('+1 242 Bahamas', () => {
355 | const number = '+1 242 1234 567';
356 | const country = 'BHS';
357 | const result = ['+12421234567', 'BHS'];
358 | test('returns ' + result, () => {
359 | expect(phone(number, country)).toEqual(result);
360 | });
361 | });
362 | describe('+1 246 Barbados', () => {
363 | const number = '+1 246 1234 567';
364 | const country = 'BRB';
365 | const result = ['+12461234567', 'BRB'];
366 | test('returns ' + result, () => {
367 | expect(phone(number, country)).toEqual(result);
368 | });
369 | });
370 |
371 | describe('+1 264 Anguilla', () => {
372 | const number = '+1 264 1234 567';
373 | const country = 'AIA';
374 | const result = [];
375 | test('returns ' + result, () => {
376 | expect(phone(number, country)).toEqual(result);
377 | });
378 | });
379 |
380 | describe('+1 264 Anguilla', () => {
381 | const number = '+1 264 5234 567';
382 | const country = 'AIA';
383 | const result = ['+12645234567', 'AIA'];
384 | test('returns ' + result, () => {
385 | expect(phone(number, country)).toEqual(result);
386 | });
387 | });
388 |
389 | describe('+1 264 Anguilla', () => {
390 | const number = '+1 264 7234 567';
391 | const country = 'AIA';
392 | const result = ['+12647234567', 'AIA'];
393 | test('returns ' + result, () => {
394 | expect(phone(number, country)).toEqual(result);
395 | });
396 | });
397 |
398 | describe('+1 268 Antigua and Barbuda', () => {
399 | const number = '+1 268 1234 567';
400 | const country = 'ATG';
401 | const result = [];
402 | test('returns ' + result, () => {
403 | expect(phone(number, country)).toEqual(result);
404 | });
405 | });
406 |
407 | describe('+1 268 Antigua and Barbuda', () => {
408 | const number = '+1 268 7234 567';
409 | const country = 'ATG';
410 | const result = ['+12687234567', 'ATG'];
411 | test('returns ' + result, () => {
412 | expect(phone(number, country)).toEqual(result);
413 | });
414 | });
415 |
416 | describe('+1 284 British Virgin Islands', () => {
417 | const number = '+1 284 1234 567';
418 | const country = 'VGB';
419 | const result = ['+12841234567', 'VGB'];
420 | test('returns ' + result, () => {
421 | expect(phone(number, country)).toEqual(result);
422 | });
423 | });
424 |
425 |
426 | describe('+1 345 Cayman Islands', () => {
427 | const number = '+1 345 1234 567';
428 | const country = 'CYM';
429 | const result = ['+13451234567', 'CYM'];
430 | test('returns ' + result, () => {
431 | expect(phone(number, country)).toEqual(result);
432 | });
433 | });
434 |
435 | describe('+1 441 Bermuda', () => {
436 | const number = '+1 441 1234 567';
437 | const country = 'BMU';
438 | const result = [];
439 | test('returns ' + result, () => {
440 | expect(phone(number, country)).toEqual(result);
441 | });
442 | });
443 |
444 |
445 | describe('+1 441 Bermuda', () => {
446 | const number = '+1 441 3234 567';
447 | const country = 'BMU';
448 | const result = ['+14413234567', 'BMU'];
449 | test('returns ' + result, () => {
450 | expect(phone(number, country)).toEqual(result);
451 | });
452 | });
453 |
454 | describe('+1 441 Bermuda', () => {
455 | const number = '+1 441 5234 567';
456 | const country = 'BMU';
457 | const result = ['+14415234567', 'BMU'];
458 | test('returns ' + result, () => {
459 | expect(phone(number, country)).toEqual(result);
460 | });
461 | });
462 |
463 | describe('+1 441 Bermuda', () => {
464 | const number = '+1 441 7234 567';
465 | const country = 'BMU';
466 | const result = ['+14417234567', 'BMU'];
467 | test('returns ' + result, () => {
468 | expect(phone(number, country)).toEqual(result);
469 | });
470 | });
471 |
472 |
473 | describe('+1 473 Grenada', () => {
474 | const number = '+1 473 1234 567';
475 | const country = 'GRD';
476 | const result = ['+14731234567', 'GRD'];
477 | test('returns ' + result, () => {
478 | expect(phone(number, country)).toEqual(result);
479 | });
480 | });
481 |
482 |
483 | describe('+1 649 Turks and Caicos Islands', () => {
484 | const number = '+1 649 1234 567';
485 | const country = 'TCA';
486 | const result = [];
487 | test('returns ' + result, () => {
488 | expect(phone(number, country)).toEqual(result);
489 | });
490 | });
491 |
492 | describe('+1 649 Turks and Caicos Islands', () => {
493 | const number = '+1 649 2234 567';
494 | const country = 'TCA';
495 | const result = ['+16492234567', 'TCA'];
496 | test('returns ' + result, () => {
497 | expect(phone(number, country)).toEqual(result);
498 | });
499 | });
500 |
501 | describe('+1 664 Montserrat', () => {
502 | const number = '+1 664 1234 567';
503 | const country = 'MSR';
504 | const result = ['+16641234567', 'MSR'];
505 | test('returns ' + result, () => {
506 | expect(phone(number, country)).toEqual(result);
507 | });
508 | });
509 |
510 |
511 | describe('+1 721 Sint Maarten', () => {
512 | const number = '+1 721 1234 567';
513 | const country = 'SXM';
514 | const result = ['+17211234567', 'SXM'];
515 | test('returns ' + result, () => {
516 | expect(phone(number, country)).toEqual(result);
517 | });
518 | });
519 |
520 | describe('+1 758 Saint Lucia', () => {
521 | const number = '+1 758 1234 567';
522 | const country = 'LCA';
523 | const result = ['+17581234567', 'LCA'];
524 | test('returns ' + result, () => {
525 | expect(phone(number, country)).toEqual(result);
526 | });
527 | });
528 |
529 | describe('+1 767 Dominica', () => {
530 | const number = '+1 767 1234 567';
531 | const country = 'DMA';
532 | const result = ['+17671234567', 'DMA'];
533 | test('returns ' + result, () => {
534 | expect(phone(number, country)).toEqual(result);
535 | });
536 | });
537 |
538 | describe('+1 784 Saint Vincent and the Grenadines', () => {
539 | const number = '+1 784 1234 567';
540 | const country = 'VCT';
541 | const result = ['+17841234567', 'VCT'];
542 | test('returns ' + result, () => {
543 | expect(phone(number, country)).toEqual(result);
544 | });
545 | });
546 |
547 |
548 | describe('+1 809 / 829 / 849 Dominican Republic', () => {
549 | const number = '+1 809 1234 567';
550 | const country = 'DOM';
551 | const result = ['+18091234567', 'DOM'];
552 | test('returns ' + result, () => {
553 | expect(phone(number, country)).toEqual(result);
554 | });
555 | });
556 |
557 | describe('+1 809 / 829 / 849 Dominican Republic', () => {
558 | const number = '+1 829 1234 567';
559 | const country = 'DOM';
560 | const result = ['+18291234567', 'DOM'];
561 | test('returns ' + result, () => {
562 | expect(phone(number, country)).toEqual(result);
563 | });
564 | });
565 |
566 | describe('+1 809 / 829 / 849 Dominican Republic', () => {
567 | const number = '+1 849 1234 567';
568 | const country = 'DOM';
569 | const result = ['+18491234567', 'DOM'];
570 | test('returns ' + result, () => {
571 | expect(phone(number, country)).toEqual(result);
572 | });
573 | });
574 |
575 |
576 | describe('+1 868 Trinidad and Tobago', () => {
577 | const number = '+1 868 1234 567';
578 | const country = 'TTO';
579 | const result = ['+18681234567', 'TTO'];
580 | test('returns ' + result, () => {
581 | expect(phone(number, country)).toEqual(result);
582 | });
583 | });
584 |
585 |
586 | describe('+1 869 Saint Kitts and Nevis', () => {
587 | const number = '+1 869 1234 567';
588 | const country = 'KNA';
589 | const result = ['+18691234567', 'KNA'];
590 | test('returns ' + result, () => {
591 | expect(phone(number, country)).toEqual(result);
592 | });
593 | });
594 |
595 |
596 | describe('+1 876 Jamaica', () => {
597 | const number = '+1 876 1234 567';
598 | const country = 'JAM';
599 | const result = ['+18761234567', 'JAM'];
600 | test('returns ' + result, () => {
601 | expect(phone(number, country)).toEqual(result);
602 | });
603 | });
604 | });
605 |
606 | describe('Testing MEX Phone', () => {
607 | // valid +phone, null
608 | // valid +phone, valid iso
609 | // valid +phone, invalid iso
610 | // valid +phone, valid name
611 | // valid +phone, invalid name
612 |
613 | describe('Test 1', () => {
614 | const number = '+52 1 762 100 9517';
615 | const country = null;
616 | const result = ['+5217621009517', 'MEX'];
617 | test('returns ' + result, () => {
618 | expect(phone(number, country)).toEqual(result);
619 | });
620 | });
621 |
622 |
623 | describe('Test 2', () => {
624 | const number = '+52 1 762 100 9517';
625 | const country = 'MEX';
626 | const result = ['+5217621009517', 'MEX'];
627 | test('returns ' + result, () => {
628 | expect(phone(number, country)).toEqual(result);
629 | });
630 | });
631 | describe('Test 3', () => {
632 | const number = '+52 1 762 100 9517';
633 | const country = 'USA';
634 | const result = [];
635 | test('returns ' + result, () => {
636 | expect(phone(number, country)).toEqual(result);
637 | });
638 | });
639 | describe('Test 4', () => {
640 | const number = '+52 1 762 100 9517';
641 | const country = 'Mexico';
642 | const result = ['+5217621009517', 'MEX'];
643 | test('returns ' + result, () => {
644 | expect(phone(number, country)).toEqual(result);
645 | });
646 | });
647 | describe('Test 5', () => {
648 | const number = '+52 1 762 100 9517';
649 | const country = 'United States';
650 | const result = [];
651 | test('returns ' + result, () => {
652 | expect(phone(number, country)).toEqual(result);
653 | });
654 | });
655 |
656 | // invalid +phone, null
657 | // invalid +phone, valid iso
658 | // invalid +phone, invalid iso
659 | // invalid +phone, valid name
660 | // invalid +phone, invalid name
661 |
662 |
663 | describe('Test 6', () => {
664 | const number = '+52 62 100 9517';
665 | const country = null;
666 | const result = [];
667 | test('returns ' + result, () => {
668 | expect(phone(number, country)).toEqual(result);
669 | });
670 | });
671 | describe('Test 7', () => {
672 | const number = '+52 62 100 9517';
673 | const country = 'MEX';
674 | const result = [];
675 | test('returns ' + result, () => {
676 | expect(phone(number, country)).toEqual(result);
677 | });
678 | });
679 | describe('Test 8', () => {
680 | const number = '+52 62 100 9517';
681 | const country = 'USA';
682 | const result = [];
683 | test('returns ' + result, () => {
684 | expect(phone(number, country)).toEqual(result);
685 | });
686 | });
687 | describe('Test 9', () => {
688 | const number = '+52 62 100 9517';
689 | const country = 'Mexico';
690 | const result = [];
691 | test('returns ' + result, () => {
692 | expect(phone(number, country)).toEqual(result);
693 | });
694 | });
695 | describe('Test 10', () => {
696 | const number = '+52 62 100 9517';
697 | const country = 'United States';
698 | const result = [];
699 | test('returns ' + result, () => {
700 | expect(phone(number, country)).toEqual(result);
701 | });
702 | });
703 |
704 | // valid phone, null
705 | // valid phone, valid iso
706 | // valid phone, invalid iso
707 | // valid phone, valid name
708 | // valid phone, invalid name
709 |
710 |
711 | describe('Test 11', () => {
712 | const number = '52762 100 9517';
713 | const country = null;
714 | const result = [];
715 | test('returns ' + result, () => {
716 | expect(phone(number, country)).toEqual(result);
717 | });
718 | });
719 | describe('Test 12', () => {
720 | const number = '762 100 9517';
721 | const country = 'MEX';
722 | const result = ['+527621009517', 'MEX'];
723 | test('returns ' + result, () => {
724 | expect(phone(number, country)).toEqual(result);
725 | });
726 | });
727 | describe('Test 13', () => {
728 | const number = '762 100 9517';
729 | const country = 'MEXINVALID';
730 | const result = [];
731 | test('returns ' + result, () => {
732 | expect(phone(number, country)).toEqual(result);
733 | });
734 | });
735 | describe('Test 14', () => {
736 | const number = '762 100 9517';
737 | const country = 'Mexico';
738 | const result = ['+527621009517', 'MEX'];
739 | test('returns ' + result, () => {
740 | expect(phone(number, country)).toEqual(result);
741 | });
742 | });
743 | describe('Test 15', () => {
744 | const number = '762 100 9517';
745 | const country = 'Mexico Invalid';
746 | const result = [];
747 | test('returns ' + result, () => {
748 | expect(phone(number, country)).toEqual(result);
749 | });
750 | });
751 | });
752 |
753 |
754 | describe('Testing HKG Phone Quick Test', () => {
755 | describe('Test 1', () => {
756 | const number = '6123-6123';
757 | const country = 'HKG';
758 | const result = ['+85261236123', 'HKG'];
759 | test('returns ' + result, () => {
760 | expect(phone(number, country)).toEqual(result);
761 | });
762 | });
763 | });
764 |
765 |
766 | describe('Testing BRA Phone Quick Test', () => {
767 | describe('Test 1', () => {
768 | const number = '+55 11 9 6123 1234';
769 | const country = 'BRA';
770 | const result = ['+5511961231234', 'BRA'];
771 | test('returns ' + result, () => {
772 | expect(phone(number, country)).toEqual(result);
773 | });
774 | });
775 |
776 | describe('Test 4', () => {
777 | const number = '+55 69 8 6123 1234';
778 | const country = 'BRA';
779 | const result = ['+5569861231234', 'BRA'];
780 | test('returns ' + result, () => {
781 | expect(phone(number, country)).toEqual(result);
782 | });
783 | });
784 |
785 | describe('Test 5', () => {
786 | const number = '+55 65 9 9123 4567';
787 | const country = 'BRA';
788 | const result = ['+5565991234567', 'BRA'];
789 | test('returns ' + result, () => {
790 | expect(phone(number, country)).toEqual(result);
791 | });
792 | });
793 |
794 | describe('Test 6', () => {
795 | const number = '+5599988311895';
796 | const country = 'BRA';
797 | const result = ['+5599988311895', 'BRA'];
798 | test('returns ' + result, () => {
799 | expect(phone(number, country)).toEqual(result);
800 | });
801 | });
802 | });
803 |
804 | describe('Testing PRI Phone Quick Test', () => {
805 | describe('Test 1', () => {
806 | const number = '+1-787-672-9999';
807 | const country = 'PRI';
808 | const result = ['+17876729999', 'PRI'];
809 | test('returns ' + result, () => {
810 | expect(phone(number, country)).toEqual(result);
811 | });
812 | });
813 |
814 | describe('Test 2', () => {
815 | const number = '17876729999';
816 | const country = 'PRI';
817 | const result = ['+17876729999', 'PRI'];
818 | test('returns ' + result, () => {
819 | expect(phone(number, country)).toEqual(result);
820 | });
821 | });
822 |
823 | describe('Test 3', () => {
824 | const number = '7876729999';
825 | const country = 'PRI';
826 | const result = ['+17876729999', 'PRI'];
827 | test('returns ' + result, () => {
828 | expect(phone(number, country)).toEqual(result);
829 | });
830 | });
831 | });
832 |
833 | // input --> output
834 | // 89234567890, RUS --> +79234567890, RUS
835 | // +79234567890, RUS --> +79234567890, RUS
836 | // +79234567890 ---> +79234567890, RUS
837 | // +70234567890, RUS ---> invalid
838 | // 9234567890, RUS ---> +79234567890, RUS
839 |
840 |
841 | describe('Testing RUS Phone Quick Test', () => {
842 | describe('Test 1', () => {
843 | const number = '89234567890'; // remove the 8, treat it as 923456789;
844 | const country = 'RUS';
845 | const result = ['+79234567890', 'RUS'];
846 | test('returns ' + result, () => {
847 | expect(phone(number, country)).toEqual(result);
848 | });
849 | });
850 |
851 | describe('Test 2', () => {
852 | const number = '+79234567890';
853 | const country = 'RUS';
854 | const result = ['+79234567890', 'RUS'];
855 | test('returns ' + result, () => {
856 | expect(phone(number, country)).toEqual(result);
857 | });
858 | });
859 |
860 | describe('Test 3', () => {
861 | const number = '+79234567890';
862 | const country = '';
863 | const result = ['+79234567890', 'RUS'];
864 | test('returns ' + result, () => {
865 | expect(phone(number, country)).toEqual(result);
866 | });
867 | });
868 |
869 | describe('Test 4', () => {
870 | const number = '+70234567890';
871 | const country = 'RUS';
872 | const result = []; // as 0 is not a valid prefix, must be 9
873 | test('returns ' + result, () => {
874 | expect(phone(number, country)).toEqual(result);
875 | });
876 | });
877 |
878 | describe('Test 5', () => {
879 | const number = '+79234567890';
880 | const country = 'USA';
881 | const result = [];
882 | test('returns ' + result, () => {
883 | expect(phone(number, country)).toEqual(result);
884 | });
885 | });
886 | });
887 |
888 | describe('Testing THA Phone Quick Test', () => {
889 | describe('Test 1', () => {
890 | const number = '0812345678'; // remove the leading ;
891 | const country = 'THA';
892 | const result = ['+66812345678', 'THA'];
893 | test('returns ' + result, () => {
894 | expect(phone(number, country)).toEqual(result);
895 | });
896 | });
897 |
898 | describe('Test 2', () => {
899 | const number = '0912345678'; // remove the leading ;
900 | const country = 'THA';
901 | const result = ['+66912345678', 'THA'];
902 | test('returns ' + result, () => {
903 | expect(phone(number, country)).toEqual(result);
904 | });
905 | });
906 |
907 | describe('Test 3', () => {
908 | const number = '812345678';
909 | const country = 'THA';
910 | const result = ['+66812345678', 'THA'];
911 | test('returns ' + result, () => {
912 | expect(phone(number, country)).toEqual(result);
913 | });
914 | });
915 | });
916 |
917 |
918 | describe('Testing TZA Phone Quick Test', () => {
919 | describe('Test 1', () => {
920 | const number = '0714795861'; // remove the leading ;
921 | const country = 'TZA';
922 | const result = ['+255714795861', 'TZA'];
923 | test('returns ' + result, () => {
924 | expect(phone(number, country)).toEqual(result);
925 | });
926 | });
927 |
928 | describe('Test 2', () => {
929 | const number = '0684795861'; // remove the leading ;
930 | const country = 'TZA';
931 | const result = ['+255684795861', 'TZA'];
932 | test('returns ' + result, () => {
933 | expect(phone(number, country)).toEqual(result);
934 | });
935 | });
936 |
937 | describe('Test 3', () => {
938 | const number = '714795861';
939 | const country = 'TZA';
940 | const result = ['+255714795861', 'TZA'];
941 | test('returns ' + result, () => {
942 | expect(phone(number, country)).toEqual(result);
943 | });
944 | });
945 | });
946 |
947 | describe('Testing KAZ Phone Quick Test', () => {
948 | describe('Test 1', () => {
949 | const number = '+77012345678';
950 | const country = 'KAZ';
951 | const result = ['+77012345678', 'KAZ'];
952 | test('returns ' + result, () => {
953 | expect(phone(number, country)).toEqual(result);
954 | });
955 | });
956 |
957 | describe('Test 2', () => {
958 | const number = '+77412345678';
959 | const country = 'KAZ';
960 | const result = ['+77412345678', 'KAZ'];
961 | test('returns ' + result, () => {
962 | expect(phone(number, country)).toEqual(result);
963 | });
964 | });
965 |
966 | describe('Test 3', () => {
967 | const number = '+77712345678';
968 | const country = 'KAZ';
969 | const result = ['+77712345678', 'KAZ'];
970 | test('returns ' + result, () => {
971 | expect(phone(number, country)).toEqual(result);
972 | });
973 | });
974 | });
975 |
976 |
977 | describe('Testing PAN Phone Quick Test', () => {
978 | describe('Test 1', () => {
979 | const number = '+507 61234567';
980 | const country = 'PAN';
981 | const result = ['+50761234567', 'PAN'];
982 | test('returns ' + result, () => {
983 | expect(phone(number, country)).toEqual(result);
984 | });
985 | });
986 |
987 |
988 | describe('Test 2', () => {
989 | const number = '+507 51234567'; // start from 5 is landlines
990 | const country = 'PAN';
991 | const result = [];
992 | test('returns ' + result, () => {
993 | expect(phone(number, country)).toEqual(result);
994 | });
995 | });
996 | });
997 |
998 | describe('Testing MUS Phone Quick Test', () => {
999 | describe('Test 1', () => {
1000 | const number = '+230 51234567';
1001 | const result = ['+23051234567', 'MUS'];
1002 | test('returns ' + result, () => {
1003 | expect(phone(number)).toEqual(result);
1004 | });
1005 | });
1006 |
1007 |
1008 | describe('Test 2', () => {
1009 | const number = '+230 5123-4567';
1010 | const result = ['+23051234567', 'MUS'];
1011 | test('returns ' + result, () => {
1012 | expect(phone(number)).toEqual(result);
1013 | });
1014 | });
1015 |
1016 | describe('Test 3', () => {
1017 | const number = '+230 6123-4567'; // Landlines
1018 | const result = [];
1019 | test('returns ' + result, () => {
1020 | expect(phone(number)).toEqual(result);
1021 | });
1022 | });
1023 |
1024 | describe('Test 4', () => {
1025 | const number = '+230 6123-4567'; // Country code not match with number
1026 | const country = 'HKG';
1027 | const result = [];
1028 | test('returns ' + result, () => {
1029 | expect(phone(number, country)).toEqual(result);
1030 | });
1031 | });
1032 | });
1033 |
1034 |
1035 | describe('Testing CHN Phone Quick Test', () => {
1036 | // Test for new pattern (199, 198, 166)
1037 | describe('Test for pattern 199', () => {
1038 | const number = '+86 199 51343779';
1039 | const result = ['+8619951343779', 'CHN'];
1040 | test('returns ' + result, () => {
1041 | expect(phone(number)).toEqual(result);
1042 | });
1043 | });
1044 |
1045 | describe('Test for pattern 198', () => {
1046 | const number = '+86 198 51343779';
1047 | const result = ['+8619851343779', 'CHN'];
1048 | test('returns ' + result, () => {
1049 | expect(phone(number)).toEqual(result);
1050 | });
1051 | });
1052 |
1053 | describe('Test for pattern 166', () => {
1054 | const number = '+86 166 51343779';
1055 | const result = ['+8616651343779', 'CHN'];
1056 | test('returns ' + result, () => {
1057 | expect(phone(number)).toEqual(result);
1058 | });
1059 | });
1060 | });
1061 |
1062 |
1063 | describe('Testing ARG numbers', () => {
1064 | describe('Test for number without 9 prefix', () => {
1065 | const number = '+54 233 123 4567';
1066 | const result = ['+542331234567', 'ARG'];
1067 | test('returns ' + result, () => {
1068 | expect(phone(number)).toEqual(result);
1069 | });
1070 | });
1071 |
1072 | describe('Test for number with 9 prefix', () => {
1073 | const number = '+54 9 233 123 4567';
1074 | const result = ['+542331234567', 'ARG'];
1075 | test('returns ' + result, () => {
1076 | expect(phone(number)).toEqual(result);
1077 | });
1078 | });
1079 |
1080 | describe('Test for number with 15 prefix', () => {
1081 | const number = '+54 15 233 123 4567';
1082 | const result = [];
1083 | test('returns ' + result, () => {
1084 | expect(phone(number)).toEqual(result);
1085 | });
1086 | });
1087 | });
1088 |
1089 |
1090 | describe('Testing GRL numbers', () => {
1091 | describe('Test for numbers starting with 5', () => {
1092 | const number = '+299 555299';
1093 | const result = ['+299555299', 'GRL'];
1094 | test('returns ' + result, () => {
1095 | expect(phone(number)).toEqual(result);
1096 | });
1097 | });
1098 | describe('Test for numbers starting with 2', () => {
1099 | const number = '+299 233299';
1100 | const result = ['+299233299', 'GRL'];
1101 | test('returns ' + result, () => {
1102 | expect(phone(number)).toEqual(result);
1103 | });
1104 | });
1105 | describe('Test for landlines', () => {
1106 | const number = '+299 321000';
1107 | const result = [];
1108 | test('returns ' + result, () => {
1109 | expect(phone(number)).toEqual(result);
1110 | });
1111 | });
1112 | });
1113 |
1114 |
1115 | describe( 'Testing MMR Phone', () => {
1116 | describe('Test for 8 digits mobile numbers ', () => {
1117 | const number = '+95 9 55 00000';
1118 | const result = ['+9595500000', 'MMR'];
1119 | test('returns ' + result, () => {
1120 | expect(phone(number)).toEqual(result);
1121 | });
1122 | });
1123 | describe('Test for 9 digits mobile numbers ', () => {
1124 | const number = '+95 9 30 000 000';
1125 | const result = ['+95930000000', 'MMR'];
1126 | test('returns ' + result, () => {
1127 | expect(phone(number)).toEqual(result);
1128 | });
1129 | });
1130 | describe('Test 10 digits mobile numbers', () => {
1131 | const number = '+95 9 426 00 0000';
1132 | const result = ['+959426000000', 'MMR'];
1133 | test('returns ' + result, () => {
1134 | expect(phone(number)).toEqual(result);
1135 | });
1136 | });
1137 | describe('Test land lines', () => {
1138 | const number = '+95 1 1234567'; //Landlines
1139 | const result = [];
1140 | test('returns ' + result, () => {
1141 | expect(phone(number)).toEqual(result);
1142 | });
1143 | });
1144 | });
1145 |
1146 |
1147 | describe( 'Testing Canada Phone', () => {
1148 | describe('Should return result when it matches mobile_begin_with', () => {
1149 | const number = '+1 367 1234567';
1150 | const result = ['+13671234567', 'CAN'];
1151 | test('returns ' + result, () => {
1152 | expect(phone(number)).toEqual(result);
1153 | });
1154 | });
1155 | describe('Should not return result when it does not match mobile_begin_with', () => {
1156 | const number = '+1 111 1234567';
1157 | const result = [];
1158 | test('returns ' + result, () => {
1159 | expect(phone(number)).toEqual(result);
1160 | });
1161 | });
1162 | });
1163 |
1164 |
1165 | describe( 'Testing Cameroon Phone', () => {
1166 | describe('Should return result when it matches mobile_begin_with', () => {
1167 | const number = '+237 612345678';
1168 | const result = ['+237612345678', 'CMR'];
1169 | test('returns ' + result, () => {
1170 | expect(phone(number)).toEqual(result);
1171 | });
1172 | });
1173 | describe('Should not return result when it does not match mobile_begin_with', () => {
1174 | const number = '+237 112345678';
1175 | const result = [];
1176 | test('returns ' + result, () => {
1177 | expect(phone(number)).toEqual(result);
1178 | });
1179 | });
1180 | });
1181 |
1182 |
1183 | describe( 'Testing New Caledonia Phone', () => {
1184 | describe('Should return result when it matches mobile_begin_with', () => {
1185 | const number = '+687 812345';
1186 | const result = ['+687812345', 'NCL'];
1187 | test('returns ' + result, () => {
1188 | expect(phone(number)).toEqual(result);
1189 | });
1190 | });
1191 | describe('Should not return result when it does not match mobile_begin_with', () => {
1192 | const number = '+687 112345';
1193 | const result = [];
1194 | test('returns ' + result, () => {
1195 | expect(phone(number)).toEqual(result);
1196 | });
1197 | });
1198 | });
1199 |
1200 |
1201 | describe( 'Testing Ukraine Phone', () => {
1202 | describe('Should return result when it matches mobile_begin_with', () => {
1203 | const number = '+380 73 123 45 67';
1204 | const result = ['+380731234567', 'UKR'];
1205 | test('returns ' + result, () => {
1206 | expect(phone(number)).toEqual(result);
1207 | });
1208 | });
1209 | describe('Should not return result when it does not match mobile_begin_with', () => {
1210 | const number = '+380 11 123 45 67';
1211 | const result = [];
1212 | test('returns ' + result, () => {
1213 | expect(phone(number)).toEqual(result);
1214 | });
1215 | });
1216 | });
1217 |
1218 |
1219 | describe('test phone with trunk prefix', () => {
1220 | test('Austrilia phone with trunk prefix (0)', () => {
1221 | const number = '+61(0)488888888';
1222 | const result = ['+61488888888', 'AUS'];
1223 | expect(phone(number)).toEqual(result);
1224 | });
1225 |
1226 | test('Russian Federation phone with trunk prefix (8)', () => {
1227 | const number = '+7(8)9234567890';
1228 | const result = ['+79234567890', 'RUS'];
1229 | expect(phone(number)).toEqual(result);
1230 | });
1231 |
1232 | test('Micronesia with trunk prefix (0)', () => {
1233 | const number = '+691(0)1234567';
1234 | const result = ['+6911234567', 'FSM'];
1235 | expect(phone(number)).toEqual(result);
1236 | });
1237 | });
1238 |
1239 | describe('test phone with no mobile_begin_with', () => {
1240 | test('Test 1', () => {
1241 | const number = '+298 212345';
1242 | const result = ['+298212345', 'FRO'];
1243 | expect(phone(number)).toEqual(result);
1244 | });
1245 | });
1246 |
1247 | describe('[CORE-1562] add new phone number rules for `+17215201993、+5164518135、+6062311120、+16782069397`', () => {
1248 | test('Test +17215201993', () => {
1249 | const number = '+17215201993';
1250 | const result = ['+17215201993', 'SXM'];
1251 | expect(phone(number)).toEqual(result);
1252 | });
1253 |
1254 | test('Test +5164518135', () => {
1255 | const number = '+5164518135';
1256 | const result = ['+5164518135', 'PER'];
1257 | expect(phone(number)).toEqual(result);
1258 | });
1259 |
1260 | test('Test +6062311120', () => {
1261 | const number = '+6062311120';
1262 | const result = ['+6062311120', 'MYS'];
1263 | expect(phone(number)).toEqual(result);
1264 | });
1265 |
1266 | test('Test +16782069397', () => {
1267 | const number = '+16782069397';
1268 | const result = ['+16782069397', 'USA'];
1269 | expect(phone(number)).toEqual(result);
1270 | });
1271 | });
1272 |
1273 |
1274 | describe('Landline phone number test', () => {
1275 | test('Test mobile phone number, should success', () => {
1276 | const number = '+85293785433';
1277 | const result = ['+85293785433', 'HKG'];
1278 | expect(phone(number)).toEqual(result);
1279 | });
1280 |
1281 | test('Test landline phone number without 3rd parameter, should fail', () => {
1282 | const number = '+85223785433';
1283 | const result = [];
1284 | expect(phone(number)).toEqual(result);
1285 | });
1286 |
1287 | test('Test landline phone number with 3rd parameter, should success', () => {
1288 | const number = '+85223785433';
1289 | const result = ['+85223785433', 'HKG'];
1290 | expect(phone(number, '', true)).toEqual(result);
1291 | });
1292 |
1293 | test('Test mobile phone number without plus sign, should success', () => {
1294 | const number = '85293785433';
1295 | const result = ['+85293785433', 'HKG'];
1296 | expect(phone(number, 'HKG')).toEqual(result);
1297 | });
1298 |
1299 | test('Test landline phone number without plus sign without 3rd parameter, should fail', () => {
1300 | const number = '85223785433';
1301 | const result = [];
1302 | expect(phone(number, 'HKG')).toEqual(result);
1303 | });
1304 |
1305 | test('Test landline phone number without plus sign with 3rd parameter, should success', () => {
1306 | const number = '85223785433';
1307 | const result = ['+85223785433', 'HKG'];
1308 | expect(phone(number, 'HKG', true)).toEqual(result);
1309 | });
1310 |
1311 | test('Test mobile phone number without plus sign nor country code, should success', () => {
1312 | const number = '93785433';
1313 | const result = ['+85293785433', 'HKG'];
1314 | expect(phone(number, 'HKG')).toEqual(result);
1315 | });
1316 |
1317 | test('Test landline phone number without plus sign nor country code without 3rd parameter, should fail', () => {
1318 | const number = '23785433';
1319 | const result = [];
1320 | expect(phone(number, 'HKG')).toEqual(result);
1321 | });
1322 |
1323 | test('Test landline phone number without plus sign nor country code with 3rd parameter, should success', () => {
1324 | const number = '23785433';
1325 | const result = ['+85223785433', 'HKG'];
1326 | expect(phone(number, 'HKG', true)).toEqual(result);
1327 | });
1328 | });
1329 |
1330 | describe('#190 phone number with plus sign BUT without country code (intentionally wrong input)', () => {
1331 | test('1. with +, country code, and country, should get the result', () => {
1332 | const number = '+85293785433';
1333 | const country = 'HKG';
1334 | const result = ['+85293785433', 'HKG'];
1335 | expect(phone(number, country)).toEqual(result);
1336 | });
1337 |
1338 | test('2. without +, with country code, with country, should get the result', () => {
1339 | const number = '85293785433';
1340 | const country = 'HKG';
1341 | const result = ['+85293785433', 'HKG'];
1342 | expect(phone(number, country)).toEqual(result);
1343 | });
1344 |
1345 | test('3a. with +, without country code, with country, should get empty array', () => {
1346 | const number = '+93785433';
1347 | const country = 'HKG';
1348 | const result = [];
1349 | expect(phone(number, country)).toEqual(result);
1350 | });
1351 |
1352 | test('3b. with +, without country code, with country, should get empty array', () => {
1353 | const number = '+41414141';
1354 | const country = 'NO';
1355 | const result = [];
1356 | expect(phone(number, country)).toEqual(result);
1357 | });
1358 |
1359 | test('3c. with +, without country code, with country, should get empty array', () => {
1360 | const number = '+2011231234';
1361 | const country = 'USA';
1362 | const result = [];
1363 | expect(phone(number, country)).toEqual(result);
1364 | });
1365 |
1366 | test('4a. without +, without country code, with country, should get the result', () => {
1367 | const number = '93785433';
1368 | const country = 'HKG';
1369 | const result = ['+85293785433', 'HKG'];
1370 | expect(phone(number, country)).toEqual(result);
1371 | });
1372 |
1373 | test('4b. without +, without country code, with country, should get the result', () => {
1374 | const number = '2014125632';
1375 | const country = 'USA';
1376 | const result = ['+12014125632', 'USA'];
1377 | expect(phone(number, country)).toEqual(result);
1378 | });
1379 |
1380 | test('4c. without +, without country code, with country, should get the result', () => {
1381 | const number = '41414141';
1382 | const country = 'NO';
1383 | const result = ['+4741414141', 'NOR'];
1384 | expect(phone(number, country)).toEqual(result);
1385 | });
1386 |
1387 | test('5a. with +, with country code, without country, should get the result', () => {
1388 | const number = '+4741414141';
1389 | const result = ['+4741414141', 'NOR'];
1390 | expect(phone(number)).toEqual(result);
1391 | });
1392 |
1393 | test('5b. with +, with country code, without country, should get the result', () => {
1394 | const number = '+85296587452';
1395 | const result = ['+85296587452', 'HKG'];
1396 | expect(phone(number)).toEqual(result);
1397 | });
1398 |
1399 | test('5c. with +, with country code, without country, should get the result', () => {
1400 | const number = '+13612145896';
1401 | const result = ['+13612145896', 'USA'];
1402 | expect(phone(number)).toEqual(result);
1403 | });
1404 |
1405 | test('6a. without +, with country code, without country, should get the result', () => {
1406 | const number = '13612145896';
1407 | const result = ['+13612145896', 'USA'];
1408 | expect(phone(number)).toEqual(result);
1409 | });
1410 |
1411 | test('6b. without +, with country code, without country, default USA and should get empty result', () => {
1412 | const number = '4741414141';
1413 | const result = [];
1414 | expect(phone(number)).toEqual(result);
1415 | });
1416 |
1417 | test('6c. without +, with country code, without country, default USA and should get empty result', () => {
1418 | const number = '96587452';
1419 | const result = [];
1420 | expect(phone(number)).toEqual(result);
1421 | });
1422 |
1423 | test('7a. with +, without country code, without country, should get empty result', () => {
1424 | const number = '+96587452';
1425 | const result = [];
1426 | expect(phone(number)).toEqual(result);
1427 | });
1428 |
1429 | test('7b. with +, without country code, without country, should get empty result', () => {
1430 | const number = '+3612145896';
1431 | const result = [];
1432 | expect(phone(number)).toEqual(result);
1433 | });
1434 |
1435 | test('7c. with +, without country code, without country, should get empty result', () => {
1436 | const number = '+41414141';
1437 | const result = [];
1438 | expect(phone(number)).toEqual(result);
1439 | });
1440 |
1441 | test('8a. without +, without country code, without country, should get empty result', () => {
1442 | const number = '96587452';
1443 | const result = [];
1444 | expect(phone(number)).toEqual(result);
1445 | });
1446 |
1447 | test('8b. without +, without country code, without country, default USA, should get result', () => {
1448 | const number = '3612145896';
1449 | const result = ['+13612145896', 'USA'];
1450 | expect(phone(number)).toEqual(result);
1451 | });
1452 |
1453 | test('8c. without +, without country code, without country, should get empty result', () => {
1454 | const number = '41414141';
1455 | const result = [];
1456 | expect(phone(number)).toEqual(result);
1457 | });
1458 | });
1459 |
1460 | const {unparse} = require('papaparse');
1461 | const fs = require('fs');
1462 |
1463 | const outputCsv = unparse(allOutput, {
1464 | header: true
1465 | });
1466 |
1467 | fs.writeFileSync(`${__dirname}/data.csv`, outputCsv);
--------------------------------------------------------------------------------
/src/data/country_phone_data.ts:
--------------------------------------------------------------------------------
1 | export default [
2 | {
3 | alpha2: 'US',
4 | alpha3: 'USA',
5 | country_code: '1',
6 | country_name: 'United States',
7 | mobile_begin_with: ['201', '202', '203', '205', '206', '207', '208', '209', '210', '212', '213', '214', '215',
8 | '216', '217', '218', '219', '220', '223', '224', '225', '227', '228', '229', '231', '234', '239', '240',
9 | '248', '251', '252', '253', '254', '256', '260', '262', '267', '269', '270', '272', '274', '276', '278',
10 | '281', '283', '301', '302', '303', '304', '305', '307', '308', '309', '310', '312', '313', '314', '315',
11 | '316', '317', '318', '319', '320', '321', '323', '325', '327', '329', '330', '331', '332', '334', '336', '337',
12 | '339', '341', '346', '347', '351', '352', '353', '360', '361', '364', '369', '380', '385', '386', '401', '402',
13 | '404', '405', '406', '407', '408', '409', '410', '412', '413', '414', '415', '417', '419', '423', '424',
14 | '425', '430', '432', '434', '435', '440', '441', '442', '443', '445', '447', '458', '463', '464', '469', '470', '472', '475',
15 | '478', '479', '480', '484', '501', '502', '503', '504', '505', '507', '508', '509', '510', '512', '513',
16 | '515', '516', '517', '518', '520', '530', '531', '534', '539', '540', '541', '551', '557', '559', '561',
17 | '562', '563', '564', '567', '570', '571', '572', '573', '574', '575', '580', '582', '585', '586', '601', '602',
18 | '603', '605', '606', '607', '608', '609', '610', '612', '614', '615', '616', '617', '618', '619', '620',
19 | '623', '626', '627', '628', '629', '630', '631', '636', '640', '641', '645', '646', '650', '651', '656', '657', '659', '660',
20 | '661', '662', '667', '669', '678', '679', '680', '681', '682', '689', '701', '702', '703', '704', '706', '707',
21 | '708', '712', '713', '714', '715', '716', '717', '718', '719', '720', '724', '725', '726', '727', '728', '730', '731',
22 | '732', '734', '737', '740', '743', '747', '752', '754', '757', '760', '762', '763', '764', '765', '769', '770', '771',
23 | '772', '773', '774', '775', '779', '781', '785', '786', '787', '801', '802', '803', '804', '805', '806', '808',
24 | '810', '812', '813', '814', '815', '816', '817', '818', '820', '828', '830', '831', '832', '835', '838', '840', '843', '845',
25 | '847', '848', '850', '854', '856', '857', '858', '859', '860', '862', '863', '864', '865', '870', '872',
26 | '878', '901', '903', '904', '906', '907', '908', '909', '910', '912', '913', '914', '915', '916', '917',
27 | '918', '919', '920', '925', '927', '928', '929', '930', '931', '934', '935', '936', '937', '938', '939', '940', '941', '945',
28 | '947', '949', '951', '952', '954', '956', '957', '959', '970', '971', '972', '973', '975', '978', '979',
29 | '980', '984', '985', '986', '989', '888', '800', '833', '844', '855', '866', '877', '279', '340', '983', '448', '943', '363',
30 | '326', '839', '826', '948', '924', '686'
31 | ],
32 | phone_number_lengths: [10]
33 | },
34 | // https://en.wikipedia.org/wiki/Telephone_numbers_in_Aruba
35 | {
36 | alpha2: 'AW',
37 | alpha3: 'ABW',
38 | country_code: '297',
39 | country_name: 'Aruba',
40 | mobile_begin_with: ['56', '59', '64', '73', '74', '99'],
41 | phone_number_lengths: [7]
42 | },
43 | {
44 | alpha2: 'AF',
45 | alpha3: 'AFG',
46 | country_code: '93',
47 | country_name: 'Afghanistan',
48 | mobile_begin_with: ['7'],
49 | phone_number_lengths: [9]
50 | },
51 | {
52 | alpha2: 'AO',
53 | alpha3: 'AGO',
54 | country_code: '244',
55 | country_name: 'Angola',
56 | mobile_begin_with: ['9'],
57 | phone_number_lengths: [9]
58 | },
59 | {
60 | alpha2: 'AI',
61 | alpha3: 'AIA',
62 | country_code: '1',
63 | country_name: 'Anguilla',
64 | mobile_begin_with: ['2642', '2644', '2645', '2647'],
65 | phone_number_lengths: [10]
66 | },
67 | {
68 | alpha2: 'AX',
69 | alpha3: 'ALA',
70 | country_code: '358',
71 | country_name: 'Åland Islands',
72 | mobile_begin_with: ['18'],
73 | phone_number_lengths: [6, 7, 8]
74 | },
75 | {
76 | alpha2: 'AL',
77 | alpha3: 'ALB',
78 | country_code: '355',
79 | country_name: 'Albania',
80 | mobile_begin_with: ['6'],
81 | phone_number_lengths: [9]
82 | },
83 | {
84 | alpha2: 'AD',
85 | alpha3: 'AND',
86 | country_code: '376',
87 | country_name: 'Andorra',
88 | mobile_begin_with: ['3', '4', '6'],
89 | phone_number_lengths: [6]
90 | },
91 | // https://en.wikipedia.org/wiki/Telephone_numbers_in_Cura%C3%A7ao_and_the_Caribbean_Netherlands
92 | {
93 | alpha2: "BQ",
94 | alpha3: "BES",
95 | country_code: "599",
96 | country_name: "Caribbean Netherlands",
97 | mobile_begin_with: ['3', '416', '700', '701','795'],
98 | phone_number_lengths: [7]
99 | },
100 | {
101 | alpha2: 'AE',
102 | alpha3: 'ARE',
103 | country_code: '971',
104 | country_name: 'United Arab Emirates',
105 | mobile_begin_with: ['5'],
106 | phone_number_lengths: [9]
107 | },
108 | {
109 | alpha2: 'AR',
110 | alpha3: 'ARG',
111 | country_code: '54',
112 | country_name: 'Argentina',
113 | mobile_begin_with: ['1', '2', '3'], // Same for mobile and landlines
114 | phone_number_lengths: [8, 9, 10, 11, 12]
115 | },
116 | {
117 | alpha2: 'AM',
118 | alpha3: 'ARM',
119 | country_code: '374',
120 | country_name: 'Armenia',
121 | mobile_begin_with: ['3', '4', '5', '7', '9'],
122 | phone_number_lengths: [8]
123 | },
124 | // http://www.howtocallabroad.com/results.php?callfrom=united_states&callto=american_samoa
125 | {
126 | alpha2: 'AS',
127 | alpha3: 'ASM',
128 | country_code: '1',
129 | country_name: 'American Samoa',
130 | mobile_begin_with: ['684733', '684258'],
131 | phone_number_lengths: [10]
132 | },
133 | // {alpha2: "AQ", alpha3: "ATA", country_code: "672", country_name: "Antarctica", mobile_begin_with: [], phone_number_lengths: []},
134 | // {alpha2: "TF", alpha3: "ATF", country_code: "", country_name: "French Southern Territories", mobile_begin_with: [], phone_number_lengths: []},
135 | // http://www.howtocallabroad.com/results.php?callfrom=united_states&callto=antigua_barbuda
136 | {
137 | alpha2: 'AG',
138 | alpha3: 'ATG',
139 | country_code: '1',
140 | country_name: 'Antigua and Barbuda',
141 | mobile_begin_with: ['2687'],
142 | phone_number_lengths: [10]
143 | },
144 | {
145 | alpha2: 'AU',
146 | alpha3: 'AUS',
147 | country_code: '61',
148 | country_name: 'Australia',
149 | mobile_begin_with: ['4'],
150 | phone_number_lengths: [9]
151 | },
152 | {
153 | alpha2: 'AT',
154 | alpha3: 'AUT',
155 | country_code: '43',
156 | country_name: 'Austria',
157 | mobile_begin_with: ['6'],
158 | phone_number_lengths: [10, 11, 12, 13, 14]
159 | },
160 | {
161 | alpha2: 'AZ',
162 | alpha3: 'AZE',
163 | country_code: '994',
164 | country_name: 'Azerbaijan',
165 | mobile_begin_with: ['10', '50', '51', '55', '60', '70', '77', '99'],
166 | phone_number_lengths: [9]
167 | },
168 | {
169 | alpha2: 'BI',
170 | alpha3: 'BDI',
171 | country_code: '257',
172 | country_name: 'Burundi',
173 | mobile_begin_with: ['71', '72', '75', '76', '77', '79', '29', '61', '68', '69'],
174 | phone_number_lengths: [8]
175 | },
176 | {
177 | alpha2: 'BE',
178 | alpha3: 'BEL',
179 | country_code: '32',
180 | country_name: 'Belgium',
181 | mobile_begin_with: ['4', '3'],
182 | phone_number_lengths: [9, 8]
183 | },
184 | {
185 | alpha2: 'BJ',
186 | alpha3: 'BEN',
187 | country_code: '229',
188 | country_name: 'Benin',
189 | mobile_begin_with: ['4', '6', '9'],
190 | phone_number_lengths: [8]
191 | },
192 | {
193 | alpha2: 'BF',
194 | alpha3: 'BFA',
195 | country_code: '226',
196 | country_name: 'Burkina Faso',
197 | mobile_begin_with: ['6', '7'],
198 | phone_number_lengths: [8]
199 | },
200 | {
201 | alpha2: 'BD',
202 | alpha3: 'BGD',
203 | country_code: '880',
204 | country_name: 'Bangladesh',
205 | mobile_begin_with: ['1'],
206 | phone_number_lengths: [8, 9, 10]
207 | },
208 | {
209 | alpha2: 'BG',
210 | alpha3: 'BGR',
211 | country_code: '359',
212 | country_name: 'Bulgaria',
213 | mobile_begin_with: ['87', '88', '89', '98', '99', '43'],
214 | phone_number_lengths: [8, 9]
215 | },
216 | {
217 | alpha2: 'BH',
218 | alpha3: 'BHR',
219 | country_code: '973',
220 | country_name: 'Bahrain',
221 | mobile_begin_with: ['3'],
222 | phone_number_lengths: [8]
223 | },
224 | {
225 | alpha2: 'BS',
226 | alpha3: 'BHS',
227 | country_code: '1',
228 | country_name: 'Bahamas',
229 | mobile_begin_with: ['242'],
230 | phone_number_lengths: [10]
231 | },
232 | {
233 | alpha2: 'BA',
234 | alpha3: 'BIH',
235 | country_code: '387',
236 | country_name: 'Bosnia and Herzegovina',
237 | mobile_begin_with: ['6'],
238 | phone_number_lengths: [8, 9]
239 | },
240 | // {alpha2: "BL", alpha3: "BLM", country_code: "590", country_name: "Saint Barthélemy", mobile_begin_with: [], phone_number_lengths: []},
241 | {
242 | alpha2: 'BY',
243 | alpha3: 'BLR',
244 | country_code: '375',
245 | country_name: 'Belarus',
246 | mobile_begin_with: ['25', '29', '33', '44'],
247 | phone_number_lengths: [9]
248 | },
249 | {
250 | alpha2: 'BZ',
251 | alpha3: 'BLZ',
252 | country_code: '501',
253 | country_name: 'Belize',
254 | mobile_begin_with: ['6'],
255 | phone_number_lengths: [7]
256 | },
257 | // http://www.howtocallabroad.com/results.php?callfrom=united_states&callto=bermuda
258 | {
259 | alpha2: 'BM',
260 | alpha3: 'BMU',
261 | country_code: '1',
262 | country_name: 'Bermuda',
263 | mobile_begin_with: ['4413', '4415', '4417'],
264 | phone_number_lengths: [10]
265 | },
266 | {
267 | alpha2: 'BO',
268 | alpha3: 'BOL',
269 | country_code: '591',
270 | country_name: 'Bolivia',
271 | mobile_begin_with: ['6', '7'],
272 | phone_number_lengths: [8]
273 | },
274 | {
275 | alpha2: 'BR',
276 | alpha3: 'BRA',
277 | country_code: '55',
278 | country_name: 'Brazil',
279 | mobile_begin_with: [
280 | '119', '129', '139', '149', '159', '169', '179', '189', '199', '219', '229', '249', '279', '289',
281 | '319', '329', '339', '349', '359', '379', '389',
282 | '419', '429', '439', '449', '459', '469', '479', '489', '499',
283 | '519', '539', '549', '559',
284 | '619', '629', '639', '649', '659', '669', '679', '689', '699',
285 | '719', '739', '749', '759', '779', '799',
286 | '819', '829', '839', '849', '859', '869', '879', '889', '899',
287 | '919', '929', '939', '949', '959', '969', '979', '989', '999',
288 | ],
289 | phone_number_lengths: [10, 11]
290 | },
291 | {
292 | alpha2: 'BB',
293 | alpha3: 'BRB',
294 | country_code: '1',
295 | country_name: 'Barbados',
296 | mobile_begin_with: ['246'],
297 | phone_number_lengths: [10]
298 | },
299 | {
300 | alpha2: 'BN',
301 | alpha3: 'BRN',
302 | country_code: '673',
303 | country_name: 'Brunei Darussalam',
304 | mobile_begin_with: ['7', '8'],
305 | phone_number_lengths: [7]
306 | },
307 | {
308 | alpha2: 'BT',
309 | alpha3: 'BTN',
310 | country_code: '975',
311 | country_name: 'Bhutan',
312 | mobile_begin_with: ['17'],
313 | phone_number_lengths: [8]
314 | },
315 | // {alpha2: "BV", alpha3: "BVT", country_code: "", country_name: "Bouvet Island", mobile_begin_with: [], phone_number_lengths: []},
316 | {
317 | alpha2: 'BW',
318 | alpha3: 'BWA',
319 | country_code: '267',
320 | country_name: 'Botswana',
321 | mobile_begin_with: ['71', '72', '73', '74', '75', '76', '77', '78', '79'],
322 | phone_number_lengths: [8]
323 | },
324 | {
325 | alpha2: 'CF',
326 | alpha3: 'CAF',
327 | country_code: '236',
328 | country_name: 'Central African Republic',
329 | mobile_begin_with: ['7'],
330 | phone_number_lengths: [8]
331 | },
332 |
333 | // http://www.howtocallabroad.com/canada/
334 | // http://areacode.org/
335 | // http://countrycode.org/canada
336 | {
337 | alpha2: 'CA',
338 | alpha3: 'CAN',
339 | country_code: '1',
340 | country_name: 'Canada',
341 | mobile_begin_with: [
342 | '204', '226', '236', '249', '250', '263', '289', '306', '343', '354',
343 | '365', '367', '368', '403', '416', '418', '431', '437', '438', '450',
344 | '468', '474', '506', '514', '519', '548', '579', '581', '584', '587',
345 | '600', '604', '613', '639', '647', '672', '683', '705', '709', '742',
346 | '753', '778', '780', '782', '807', '819', '825', '867', '873', '902',
347 | '905', '428', '382', '942'],
348 | phone_number_lengths: [10]
349 | },
350 | // {alpha2: "CC", alpha3: "CCK", country_code: "61", country_name: "Cocos (Keeling) Islands", mobile_begin_with: [], phone_number_lengths: []},
351 | {
352 | alpha2: 'CH',
353 | alpha3: 'CHE',
354 | country_code: '41',
355 | country_name: 'Switzerland',
356 | mobile_begin_with: ['74', '75', '76', '77', '78', '79'],
357 | phone_number_lengths: [9]
358 | },
359 | {
360 | alpha2: 'CL',
361 | alpha3: 'CHL',
362 | country_code: '56',
363 | country_name: 'Chile',
364 | mobile_begin_with: ['9'],
365 | phone_number_lengths: [9]
366 | },
367 | {
368 | alpha2: 'CN',
369 | alpha3: 'CHN',
370 | country_code: '86',
371 | country_name: 'China',
372 | mobile_begin_with: ['13', '14', '15', '17', '18', '19', '16'],
373 | phone_number_lengths: [11]
374 | },
375 | {
376 | alpha2: 'CI',
377 | alpha3: 'CIV',
378 | country_code: '225',
379 | country_name: "Côte D'Ivoire",
380 | mobile_begin_with: ['0', '4', '5', '6', '7', '8'],
381 | phone_number_lengths: [10]
382 | },
383 | {
384 | alpha2: 'CM',
385 | alpha3: 'CMR',
386 | country_code: '237',
387 | country_name: 'Cameroon',
388 | mobile_begin_with: ['6'],
389 | phone_number_lengths: [9]
390 | },
391 | {
392 | alpha2: 'CD',
393 | alpha3: 'COD',
394 | country_code: '243',
395 | country_name: 'Congo, The Democratic Republic Of The',
396 | mobile_begin_with: ['8', '9'],
397 | phone_number_lengths: [9]
398 | },
399 | {
400 | alpha2: 'CG',
401 | alpha3: 'COG',
402 | country_code: '242',
403 | country_name: 'Congo',
404 | mobile_begin_with: ['0'],
405 | phone_number_lengths: [9]
406 | },
407 | {
408 | alpha2: 'CK',
409 | alpha3: 'COK',
410 | country_code: '682',
411 | country_name: 'Cook Islands',
412 | mobile_begin_with: ['5', '7'],
413 | phone_number_lengths: [5]
414 | },
415 | {
416 | alpha2: 'CO',
417 | alpha3: 'COL',
418 | country_code: '57',
419 | country_name: 'Colombia',
420 | mobile_begin_with: ['3'],
421 | phone_number_lengths: [10]
422 | },
423 | {
424 | alpha2: 'CW',
425 | alpha3: 'CUW',
426 | country_code: '599',
427 | country_name: 'Curaçao',
428 | mobile_begin_with: ['95', '96'],
429 | phone_number_lengths: [8]
430 | },
431 | {
432 | alpha2: 'KM',
433 | alpha3: 'COM',
434 | country_code: '269',
435 | country_name: 'Comoros',
436 | mobile_begin_with: ['3', '76'],
437 | phone_number_lengths: [7]
438 | },
439 | {
440 | alpha2: 'CV',
441 | alpha3: 'CPV',
442 | country_code: '238',
443 | country_name: 'Cape Verde',
444 | mobile_begin_with: ['5', '9'],
445 | phone_number_lengths: [7]
446 | },
447 | {
448 | alpha2: 'CR',
449 | alpha3: 'CRI',
450 | country_code: '506',
451 | country_name: 'Costa Rica',
452 | mobile_begin_with: ['5', '6', '7', '8'],
453 | phone_number_lengths: [8]
454 | },
455 | {
456 | alpha2: 'CU',
457 | alpha3: 'CUB',
458 | country_code: '53',
459 | country_name: 'Cuba',
460 | mobile_begin_with: ['5', '6'],
461 | phone_number_lengths: [8]
462 | },
463 | // {alpha2: "CX", alpha3: "CXR", country_code: "61", country_name: "Christmas Island", mobile_begin_with: [], phone_number_lengths: []},
464 | {
465 | alpha2: 'KY',
466 | alpha3: 'CYM',
467 | country_code: '1',
468 | country_name: 'Cayman Islands',
469 | mobile_begin_with: ['345'],
470 | phone_number_lengths: [10]
471 | },
472 | {
473 | alpha2: 'CY',
474 | alpha3: 'CYP',
475 | country_code: '357',
476 | country_name: 'Cyprus',
477 | mobile_begin_with: ['9'],
478 | phone_number_lengths: [8]
479 | },
480 | {
481 | alpha2: 'CZ',
482 | alpha3: 'CZE',
483 | country_code: '420',
484 | country_name: 'Czech Republic',
485 | mobile_begin_with: ['6', '7'],
486 | phone_number_lengths: [9]
487 | },
488 | {
489 | alpha2: 'DE',
490 | alpha3: 'DEU',
491 | country_code: '49',
492 | country_name: 'Germany',
493 | mobile_begin_with: ['15', '16', '17'],
494 | phone_number_lengths: [10, 11]
495 | },
496 | {
497 | alpha2: 'DJ',
498 | alpha3: 'DJI',
499 | country_code: '253',
500 | country_name: 'Djibouti',
501 | mobile_begin_with: ['77'],
502 | phone_number_lengths: [8]
503 | },
504 | {
505 | alpha2: 'DM',
506 | alpha3: 'DMA',
507 | country_code: '1',
508 | country_name: 'Dominica',
509 | mobile_begin_with: ['767'],
510 | phone_number_lengths: [10]
511 | },
512 | {
513 | alpha2: 'DK',
514 | alpha3: 'DNK',
515 | country_code: '45',
516 | country_name: 'Denmark',
517 | mobile_begin_with: [
518 | '2', '30', '31', '40', '41', '42', '50', '51', '52', '53', '60', '61', '71', '81', '91', '92', '93',
519 | '342', '344', '345', '346', '347', '348', '349', '356', '357', '359', '362',
520 | '365', '366', '389', '398', '431', '441', '462', '466', '468', '472', '474',
521 | '476', '478', '485', '486', '488', '489', '493', '494', '495', '496', '498',
522 | '499', '542', '543', '545', '551', '552', '556', '571', '572', '573', '574',
523 | '577', '579', '584', '586', '587', '589', '597', '598', '627', '629', '641',
524 | '649', '658', '662', '663', '664', '665', '667', '692', '693', '694', '697',
525 | '771', '772', '782', '783', '785', '786', '788', '789', '826', '827', '829'
526 | ],
527 | phone_number_lengths: [8]
528 | },
529 | {
530 | alpha2: 'DO',
531 | alpha3: 'DOM',
532 | country_code: '1',
533 | country_name: 'Dominican Republic',
534 | mobile_begin_with: ['809', '829', '849'],
535 | phone_number_lengths: [10]
536 | },
537 | {
538 | alpha2: 'DZ',
539 | alpha3: 'DZA',
540 | country_code: '213',
541 | country_name: 'Algeria',
542 | mobile_begin_with: ['5', '6', '7'],
543 | phone_number_lengths: [9]
544 | },
545 | {
546 | alpha2: 'EC',
547 | alpha3: 'ECU',
548 | country_code: '593',
549 | country_name: 'Ecuador',
550 | mobile_begin_with: ['9'],
551 | phone_number_lengths: [9]
552 | },
553 | {
554 | alpha2: 'EG',
555 | alpha3: 'EGY',
556 | country_code: '20',
557 | country_name: 'Egypt',
558 | mobile_begin_with: ['1'],
559 | phone_number_lengths: [10, 8]
560 | },
561 | {
562 | alpha2: 'ER',
563 | alpha3: 'ERI',
564 | country_code: '291',
565 | country_name: 'Eritrea',
566 | mobile_begin_with: ['1', '7', '8'],
567 | phone_number_lengths: [7]
568 | },
569 | // {alpha2: "EH", alpha3: "ESH", country_code: "212", country_name: "Western Sahara", mobile_begin_with: [], phone_number_lengths: []},
570 | {
571 | alpha2: 'ES',
572 | alpha3: 'ESP',
573 | country_code: '34',
574 | country_name: 'Spain',
575 | mobile_begin_with: ['6', '7'],
576 | phone_number_lengths: [9]
577 | },
578 | {
579 | alpha2: 'EE',
580 | alpha3: 'EST',
581 | country_code: '372',
582 | country_name: 'Estonia',
583 | mobile_begin_with: ['5', '81', '82', '83'],
584 | phone_number_lengths: [7, 8]
585 | },
586 | {
587 | alpha2: 'ET',
588 | alpha3: 'ETH',
589 | country_code: '251',
590 | country_name: 'Ethiopia',
591 | mobile_begin_with: ['7','9'],
592 | phone_number_lengths: [9]
593 | },
594 | {
595 | alpha2: 'FI',
596 | alpha3: 'FIN',
597 | country_code: '358',
598 | country_name: 'Finland',
599 | mobile_begin_with: ['4', '5'],
600 | phone_number_lengths: [6, 7, 9, 10]
601 | },
602 | {
603 | alpha2: 'FJ',
604 | alpha3: 'FJI',
605 | country_code: '679',
606 | country_name: 'Fiji',
607 | mobile_begin_with: ['2', '7', '8', '9'],
608 | phone_number_lengths: [7]
609 | },
610 | {
611 | alpha2: 'FK',
612 | alpha3: 'FLK',
613 | country_code: '500',
614 | country_name: 'Falkland Islands (Malvinas)',
615 | mobile_begin_with: ['5', '6'],
616 | phone_number_lengths: [5]
617 | },
618 | {
619 | alpha2: 'FR',
620 | alpha3: 'FRA',
621 | country_code: '33',
622 | country_name: 'France',
623 | mobile_begin_with: ['6', '7'],
624 | phone_number_lengths: [9]
625 | },
626 | {
627 | alpha2: 'FO',
628 | alpha3: 'FRO',
629 | country_code: '298',
630 | country_name: 'Faroe Islands',
631 | mobile_begin_with: [],
632 | phone_number_lengths: [6]
633 | },
634 | {
635 | alpha2: 'FM',
636 | alpha3: 'FSM',
637 | country_code: '691',
638 | country_name: 'Micronesia, Federated States Of',
639 | mobile_begin_with: [],
640 | phone_number_lengths: [7]
641 | },
642 | {
643 | alpha2: 'GA',
644 | alpha3: 'GAB',
645 | country_code: '241',
646 | country_name: 'Gabon',
647 | mobile_begin_with: ['2', '3', '4', '5', '6', '7'],
648 | phone_number_lengths: [7]
649 | },
650 | {
651 | alpha2: 'GB',
652 | alpha3: 'GBR',
653 | country_code: '44',
654 | country_name: 'United Kingdom',
655 | mobile_begin_with: ['7'],
656 | phone_number_lengths: [10]
657 | },
658 | {
659 | alpha2: 'GE',
660 | alpha3: 'GEO',
661 | country_code: '995',
662 | country_name: 'Georgia',
663 | mobile_begin_with: ['5', '7'],
664 | phone_number_lengths: [9]
665 | },
666 | // {alpha2: "GG", alpha3: "GGY", country_code: "44", country_name: "Guernsey", mobile_begin_with: [], phone_number_lengths: []},
667 | {
668 | alpha2: 'GH',
669 | alpha3: 'GHA',
670 | country_code: '233',
671 | country_name: 'Ghana',
672 | mobile_begin_with: ['2', '5'],
673 | phone_number_lengths: [9]
674 | },
675 | {
676 | alpha2: 'GI',
677 | alpha3: 'GIB',
678 | country_code: '350',
679 | country_name: 'Gibraltar',
680 | mobile_begin_with: ['5'],
681 | phone_number_lengths: [8]
682 | },
683 | {
684 | alpha2: 'GN',
685 | alpha3: 'GIN',
686 | country_code: '224',
687 | country_name: 'Guinea',
688 | mobile_begin_with: ['6'],
689 | phone_number_lengths: [9]
690 | },
691 | {
692 | alpha2: 'GP',
693 | alpha3: 'GLP',
694 | country_code: '590',
695 | country_name: 'Guadeloupe',
696 | mobile_begin_with: ['690', '691'],
697 | phone_number_lengths: [9]
698 | },
699 | {
700 | alpha2: 'GM',
701 | alpha3: 'GMB',
702 | country_code: '220',
703 | country_name: 'Gambia',
704 | mobile_begin_with: ['7', '9'],
705 | phone_number_lengths: [7]
706 | },
707 | {
708 | alpha2: 'GW',
709 | alpha3: 'GNB',
710 | country_code: '245',
711 | country_name: 'Guinea-Bissau',
712 | mobile_begin_with: ['5', '6', '7'],
713 | phone_number_lengths: [7]
714 | },
715 | {
716 | alpha2: 'GQ',
717 | alpha3: 'GNQ',
718 | country_code: '240',
719 | country_name: 'Equatorial Guinea',
720 | mobile_begin_with: ['222', '551'],
721 | phone_number_lengths: [9]
722 | },
723 | {
724 | alpha2: 'GR',
725 | alpha3: 'GRC',
726 | country_code: '30',
727 | country_name: 'Greece',
728 | mobile_begin_with: ['6'],
729 | phone_number_lengths: [10]
730 | },
731 | {
732 | alpha2: 'GD',
733 | alpha3: 'GRD',
734 | country_code: '1',
735 | country_name: 'Grenada',
736 | mobile_begin_with: ['473'],
737 | phone_number_lengths: [10]
738 | },
739 | {
740 | alpha2: 'GL',
741 | alpha3: 'GRL',
742 | country_code: '299',
743 | country_name: 'Greenland',
744 | mobile_begin_with: ['2', '4', '5'],
745 | phone_number_lengths: [6]
746 | },
747 | {
748 | alpha2: 'GT',
749 | alpha3: 'GTM',
750 | country_code: '502',
751 | country_name: 'Guatemala',
752 | mobile_begin_with: ['3', '4', '5'],
753 | phone_number_lengths: [8]
754 | },
755 | {
756 | alpha2: 'GF',
757 | alpha3: 'GUF',
758 | country_code: '594',
759 | country_name: 'French Guiana',
760 | mobile_begin_with: ['694'],
761 | phone_number_lengths: [9]
762 | },
763 | {
764 | alpha2: 'GU',
765 | alpha3: 'GUM',
766 | country_code: '1',
767 | country_name: 'Guam',
768 | mobile_begin_with: ['671'],
769 | phone_number_lengths: [10]
770 | },
771 | {
772 | alpha2: 'GY',
773 | alpha3: 'GUY',
774 | country_code: '592',
775 | country_name: 'Guyana',
776 | mobile_begin_with: ['6'],
777 | phone_number_lengths: [7]
778 | },
779 | {
780 | alpha2: 'HK',
781 | alpha3: 'HKG',
782 | country_code: '852',
783 | country_name: 'Hong Kong',
784 | mobile_begin_with: ['4', '5', '6', '70', '71', '72', '73', '81', '82', '83', '84', '85', '86', '87', '88', '89', '9'],
785 | phone_number_lengths: [8]
786 | },
787 | // {alpha2: "HM", alpha3: "HMD", country_code: "", country_name: "Heard and McDonald Islands", mobile_begin_with: [], phone_number_lengths: []},
788 | {
789 | alpha2: 'HN',
790 | alpha3: 'HND',
791 | country_code: '504',
792 | country_name: 'Honduras',
793 | mobile_begin_with: ['3', '7', '8', '9'],
794 | phone_number_lengths: [8]
795 | },
796 | {
797 | alpha2: 'HR',
798 | alpha3: 'HRV',
799 | country_code: '385',
800 | country_name: 'Croatia',
801 | mobile_begin_with: ['9'],
802 | phone_number_lengths: [8, 9]
803 | },
804 | {
805 | alpha2: 'HT',
806 | alpha3: 'HTI',
807 | country_code: '509',
808 | country_name: 'Haiti',
809 | mobile_begin_with: ['3', '4'],
810 | phone_number_lengths: [8]
811 | },
812 | {
813 | alpha2: 'HU',
814 | alpha3: 'HUN',
815 | country_code: '36',
816 | country_name: 'Hungary',
817 | mobile_begin_with: ['20', '30', '31', '50', '70'],
818 | phone_number_lengths: [9]
819 | },
820 | {
821 | alpha2: 'ID',
822 | alpha3: 'IDN',
823 | country_code: '62',
824 | country_name: 'Indonesia',
825 | mobile_begin_with: ['8'],
826 | phone_number_lengths: [9, 10, 11, 12]
827 | },
828 | // {alpha2: "IM", alpha3: "IMN", country_code: "44", country_name: "Isle of Man", mobile_begin_with: [], phone_number_lengths: []},
829 | {
830 | alpha2: 'IN',
831 | alpha3: 'IND',
832 | country_code: '91',
833 | country_name: 'India',
834 | mobile_begin_with: ['6', '7', '8', '9'],
835 | phone_number_lengths: [10]
836 | },
837 | // {alpha2: "IO", alpha3: "IOT", country_code: "246", country_name: "British Indian Ocean Territory", mobile_begin_with: [], phone_number_lengths: []},
838 | {
839 | alpha2: 'IE',
840 | alpha3: 'IRL',
841 | country_code: '353',
842 | country_name: 'Ireland',
843 | mobile_begin_with: ['82', '83', '84', '85', '86', '87', '88', '89'],
844 | phone_number_lengths: [9]
845 | },
846 | {
847 | alpha2: 'IR',
848 | alpha3: 'IRN',
849 | country_code: '98',
850 | country_name: 'Iran, Islamic Republic Of',
851 | mobile_begin_with: ['9'],
852 | phone_number_lengths: [10]
853 | },
854 | {
855 | alpha2: 'IQ',
856 | alpha3: 'IRQ',
857 | country_code: '964',
858 | country_name: 'Iraq',
859 | mobile_begin_with: ['7'],
860 | phone_number_lengths: [10]
861 | },
862 | {
863 | alpha2: 'IS',
864 | alpha3: 'ISL',
865 | country_code: '354',
866 | country_name: 'Iceland',
867 | mobile_begin_with: ['6', '7', '8'],
868 | phone_number_lengths: [7]
869 | },
870 | {
871 | alpha2: 'IL',
872 | alpha3: 'ISR',
873 | country_code: '972',
874 | country_name: 'Israel',
875 | mobile_begin_with: ['5'],
876 | phone_number_lengths: [9]
877 | },
878 | {
879 | alpha2: 'IT',
880 | alpha3: 'ITA',
881 | country_code: '39',
882 | country_name: 'Italy',
883 | mobile_begin_with: ['3'],
884 | phone_number_lengths: [9, 10]
885 | },
886 | {
887 | alpha2: 'JM',
888 | alpha3: 'JAM',
889 | country_code: '1',
890 | country_name: 'Jamaica',
891 | mobile_begin_with: ['876'],
892 | phone_number_lengths: [10]
893 | },
894 | // {alpha2: "JE", alpha3: "JEY", country_code: "44", country_name: "Jersey", mobile_begin_with: [], phone_number_lengths: []},
895 | {
896 | alpha2: 'JO',
897 | alpha3: 'JOR',
898 | country_code: '962',
899 | country_name: 'Jordan',
900 | mobile_begin_with: ['7'],
901 | phone_number_lengths: [9]
902 | },
903 | {
904 | alpha2: 'JP',
905 | alpha3: 'JPN',
906 | country_code: '81',
907 | country_name: 'Japan',
908 | mobile_begin_with: ['70', '80', '90'],
909 | phone_number_lengths: [10]
910 | },
911 | {
912 | alpha2: 'KZ',
913 | alpha3: 'KAZ',
914 | country_code: '7',
915 | country_name: 'Kazakhstan',
916 | mobile_begin_with: ['70', '74', '77'],
917 | phone_number_lengths: [10]
918 | },
919 | {
920 | alpha2: 'KE',
921 | alpha3: 'KEN',
922 | country_code: '254',
923 | country_name: 'Kenya',
924 | mobile_begin_with: ['7', '1'],
925 | phone_number_lengths: [9]
926 | },
927 | {
928 | alpha2: 'KG',
929 | alpha3: 'KGZ',
930 | country_code: '996',
931 | country_name: 'Kyrgyzstan',
932 | mobile_begin_with: ['20', '22', '31258', '312973', '5', '600', '7', '88', '912', '99'],
933 | phone_number_lengths: [9]
934 | },
935 | {
936 | alpha2: 'KH',
937 | alpha3: 'KHM',
938 | country_code: '855',
939 | country_name: 'Cambodia',
940 | mobile_begin_with: ['1', '6', '7', '8', '9'],
941 | phone_number_lengths: [8, 9]
942 | },
943 | {
944 | alpha2: 'KI',
945 | alpha3: 'KIR',
946 | country_code: '686',
947 | country_name: 'Kiribati',
948 | mobile_begin_with: ['9', '30'],
949 | phone_number_lengths: [5]
950 | },
951 | {
952 | alpha2: 'KN',
953 | alpha3: 'KNA',
954 | country_code: '1',
955 | country_name: 'Saint Kitts And Nevis',
956 | mobile_begin_with: ['869'],
957 | phone_number_lengths: [10]
958 | },
959 | {
960 | alpha2: 'KR',
961 | alpha3: 'KOR',
962 | country_code: '82',
963 | country_name: 'Korea, Republic of',
964 | mobile_begin_with: ['1'],
965 | phone_number_lengths: [9, 10]
966 | },
967 | // https://www.howtocallabroad.com/kosovo/
968 | // https://en.wikipedia.org/wiki/Telephone_numbers_in_Kosovo
969 | {
970 | alpha2: "XK",
971 | alpha3: "XKX",
972 | country_code: "383",
973 | country_name: "Kosovo, Republic of",
974 | mobile_begin_with: ["43", "44", "45", "46", "47", "48", "49"],
975 | phone_number_lengths: [8],
976 | },
977 | {
978 | alpha2: 'KW',
979 | alpha3: 'KWT',
980 | country_code: '965',
981 | country_name: 'Kuwait',
982 | mobile_begin_with: ['5', '6', '9'],
983 | phone_number_lengths: [8]
984 | },
985 | {
986 | alpha2: 'LA',
987 | alpha3: 'LAO',
988 | country_code: '856',
989 | country_name: "Lao People's Democratic Republic",
990 | mobile_begin_with: ['20'],
991 | phone_number_lengths: [10]
992 | },
993 | {
994 | alpha2: 'LB',
995 | alpha3: 'LBN',
996 | country_code: '961',
997 | country_name: 'Lebanon',
998 | mobile_begin_with: ['3', '7', '8'],
999 | phone_number_lengths: [7, 8]
1000 | },
1001 | {
1002 | alpha2: 'LR',
1003 | alpha3: 'LBR',
1004 | country_code: '231',
1005 | country_name: 'Liberia',
1006 | mobile_begin_with: ['4', '5', '6', '7'],
1007 | phone_number_lengths: [7, 8]
1008 | },
1009 | {
1010 | alpha2: 'LY',
1011 | alpha3: 'LBY',
1012 | country_code: '218',
1013 | country_name: 'Libyan Arab Jamahiriya',
1014 | mobile_begin_with: ['9'],
1015 | phone_number_lengths: [9]
1016 | },
1017 | {
1018 | alpha2: 'LC',
1019 | alpha3: 'LCA',
1020 | country_code: '1',
1021 | country_name: 'Saint Lucia',
1022 | mobile_begin_with: ['758'],
1023 | phone_number_lengths: [10]
1024 | },
1025 | {
1026 | alpha2: 'LI',
1027 | alpha3: 'LIE',
1028 | country_code: '423',
1029 | country_name: 'Liechtenstein',
1030 | mobile_begin_with: ['7'],
1031 | phone_number_lengths: [7]
1032 | },
1033 | {
1034 | alpha2: 'LK',
1035 | alpha3: 'LKA',
1036 | country_code: '94',
1037 | country_name: 'Sri Lanka',
1038 | mobile_begin_with: ['7'],
1039 | phone_number_lengths: [9]
1040 | },
1041 | {
1042 | alpha2: 'LS',
1043 | alpha3: 'LSO',
1044 | country_code: '266',
1045 | country_name: 'Lesotho',
1046 | mobile_begin_with: ['5', '6'],
1047 | phone_number_lengths: [8]
1048 | },
1049 | {
1050 | alpha2: 'LT',
1051 | alpha3: 'LTU',
1052 | country_code: '370',
1053 | country_name: 'Lithuania',
1054 | mobile_begin_with: ['6'],
1055 | phone_number_lengths: [8]
1056 | },
1057 | {
1058 | alpha2: 'LU',
1059 | alpha3: 'LUX',
1060 | country_code: '352',
1061 | country_name: 'Luxembourg',
1062 | mobile_begin_with: ['6'],
1063 | phone_number_lengths: [9]
1064 | },
1065 | {
1066 | alpha2: 'LV',
1067 | alpha3: 'LVA',
1068 | country_code: '371',
1069 | country_name: 'Latvia',
1070 | mobile_begin_with: ['2'],
1071 | phone_number_lengths: [8]
1072 | },
1073 | {
1074 | alpha2: 'MO',
1075 | alpha3: 'MAC',
1076 | country_code: '853',
1077 | country_name: 'Macao',
1078 | mobile_begin_with: ['6'],
1079 | phone_number_lengths: [8]
1080 | },
1081 | // {alpha2: "MF", alpha3: "MAF", country_code: "590", country_name: "Saint Martin", mobile_begin_with: [], phone_number_lengths: []},
1082 | {
1083 | alpha2: 'MA',
1084 | alpha3: 'MAR',
1085 | country_code: '212',
1086 | country_name: 'Morocco',
1087 | mobile_begin_with: ['6', '7'],
1088 | phone_number_lengths: [9]
1089 | },
1090 | {
1091 | alpha2: 'MC',
1092 | alpha3: 'MCO',
1093 | country_code: '377',
1094 | country_name: 'Monaco',
1095 | mobile_begin_with: ['4', '6'],
1096 | phone_number_lengths: [8, 9]
1097 | },
1098 | {
1099 | alpha2: 'MD',
1100 | alpha3: 'MDA',
1101 | country_code: '373',
1102 | country_name: 'Moldova, Republic of',
1103 | mobile_begin_with: ['6', '7'],
1104 | phone_number_lengths: [8]
1105 | },
1106 | {
1107 | alpha2: 'MG',
1108 | alpha3: 'MDG',
1109 | country_code: '261',
1110 | country_name: 'Madagascar',
1111 | mobile_begin_with: ['3'],
1112 | phone_number_lengths: [9]
1113 | },
1114 | {
1115 | alpha2: 'MV',
1116 | alpha3: 'MDV',
1117 | country_code: '960',
1118 | country_name: 'Maldives',
1119 | mobile_begin_with: ['7', '9'],
1120 | phone_number_lengths: [7]
1121 | },
1122 | {
1123 | alpha2: 'MX',
1124 | alpha3: 'MEX',
1125 | country_code: '52',
1126 | country_name: 'Mexico',
1127 | mobile_begin_with: [''],
1128 | phone_number_lengths: [10, 11]
1129 | },
1130 | {
1131 | alpha2: 'MH',
1132 | alpha3: 'MHL',
1133 | country_code: '692',
1134 | country_name: 'Marshall Islands',
1135 | mobile_begin_with: [],
1136 | phone_number_lengths: [7]
1137 | },
1138 | {
1139 | alpha2: 'MK',
1140 | alpha3: 'MKD',
1141 | country_code: '389',
1142 | country_name: 'Macedonia, the Former Yugoslav Republic Of',
1143 | mobile_begin_with: ['7'],
1144 | phone_number_lengths: [8]
1145 | },
1146 | {
1147 | alpha2: 'ML',
1148 | alpha3: 'MLI',
1149 | country_code: '223',
1150 | country_name: 'Mali',
1151 | mobile_begin_with: ['6', '7'],
1152 | phone_number_lengths: [8]
1153 | },
1154 | {
1155 | alpha2: 'MT',
1156 | alpha3: 'MLT',
1157 | country_code: '356',
1158 | country_name: 'Malta',
1159 | mobile_begin_with: ['7', '9'],
1160 | phone_number_lengths: [8]
1161 | },
1162 | {
1163 | alpha2: 'MM',
1164 | alpha3: 'MMR',
1165 | country_code: '95',
1166 | country_name: 'Myanmar',
1167 | mobile_begin_with: ['9'],
1168 | phone_number_lengths: [8, 9, 10]
1169 | },
1170 | {
1171 | alpha2: 'ME',
1172 | alpha3: 'MNE',
1173 | country_code: '382',
1174 | country_name: 'Montenegro',
1175 | mobile_begin_with: ['6'],
1176 | phone_number_lengths: [8]
1177 | },
1178 | {
1179 | alpha2: 'MN',
1180 | alpha3: 'MNG',
1181 | country_code: '976',
1182 | country_name: 'Mongolia',
1183 | mobile_begin_with: ['5', '8', '9'],
1184 | phone_number_lengths: [8]
1185 | },
1186 | {
1187 | alpha2: 'MP',
1188 | alpha3: 'MNP',
1189 | country_code: '1',
1190 | country_name: 'Northern Mariana Islands',
1191 | mobile_begin_with: ['670'],
1192 | phone_number_lengths: [10]
1193 | },
1194 | {
1195 | alpha2: 'MZ',
1196 | alpha3: 'MOZ',
1197 | country_code: '258',
1198 | country_name: 'Mozambique',
1199 | mobile_begin_with: ['8'],
1200 | phone_number_lengths: [9]
1201 | },
1202 | {
1203 | alpha2: 'MR',
1204 | alpha3: 'MRT',
1205 | country_code: '222',
1206 | country_name: 'Mauritania',
1207 | mobile_begin_with: [],
1208 | phone_number_lengths: [8]
1209 | },
1210 | {
1211 | alpha2: 'MS',
1212 | alpha3: 'MSR',
1213 | country_code: '1',
1214 | country_name: 'Montserrat',
1215 | mobile_begin_with: ['664'],
1216 | phone_number_lengths: [10]
1217 | },
1218 | {
1219 | alpha2: 'MQ',
1220 | alpha3: 'MTQ',
1221 | country_code: '596',
1222 | country_name: 'Martinique',
1223 | mobile_begin_with: ['696', '697'],
1224 | phone_number_lengths: [9]
1225 | },
1226 | {
1227 | alpha2: 'MU',
1228 | alpha3: 'MUS',
1229 | country_code: '230',
1230 | country_name: 'Mauritius',
1231 | mobile_begin_with: ['5'],
1232 | phone_number_lengths: [8]
1233 | },
1234 | {
1235 | alpha2: 'MW',
1236 | alpha3: 'MWI',
1237 | country_code: '265',
1238 | country_name: 'Malawi',
1239 | mobile_begin_with: ['77', '88', '99'],
1240 | phone_number_lengths: [9]
1241 | },
1242 | {
1243 | alpha2: 'MY',
1244 | alpha3: 'MYS',
1245 | country_code: '60',
1246 | country_name: 'Malaysia',
1247 | mobile_begin_with: ['1', '6'],
1248 | phone_number_lengths: [9, 10, 8]
1249 | },
1250 | {
1251 | alpha2: 'YT',
1252 | alpha3: 'MYT',
1253 | country_code: '262',
1254 | country_name: 'Mayotte',
1255 | mobile_begin_with: ['639'],
1256 | phone_number_lengths: [9]
1257 | },
1258 | {
1259 | alpha2: 'NA',
1260 | alpha3: 'NAM',
1261 | country_code: '264',
1262 | country_name: 'Namibia',
1263 | mobile_begin_with: ['60', '81', '82', '85'],
1264 | phone_number_lengths: [9]
1265 | },
1266 | {
1267 | alpha2: 'NC',
1268 | alpha3: 'NCL',
1269 | country_code: '687',
1270 | country_name: 'New Caledonia',
1271 | mobile_begin_with: ['5', '7', '8', '9'],
1272 | phone_number_lengths: [6]
1273 | },
1274 | {
1275 | alpha2: 'NE',
1276 | alpha3: 'NER',
1277 | country_code: '227',
1278 | country_name: 'Niger',
1279 | mobile_begin_with: ['9'],
1280 | phone_number_lengths: [8]
1281 | },
1282 | {
1283 | alpha2: 'NF',
1284 | alpha3: 'NFK',
1285 | country_code: '672',
1286 | country_name: 'Norfolk Island',
1287 | mobile_begin_with: ['5', '8'],
1288 | phone_number_lengths: [5]
1289 | },
1290 | {
1291 | alpha2: 'NG',
1292 | alpha3: 'NGA',
1293 | country_code: '234',
1294 | country_name: 'Nigeria',
1295 | mobile_begin_with: ['70', '80', '81', '90', '91'],
1296 | phone_number_lengths: [10]
1297 | },
1298 | {
1299 | alpha2: 'NI',
1300 | alpha3: 'NIC',
1301 | country_code: '505',
1302 | country_name: 'Nicaragua',
1303 | mobile_begin_with: ['7', '8'],
1304 | phone_number_lengths: [8]
1305 | },
1306 | {
1307 | alpha2: 'NU',
1308 | alpha3: 'NIU',
1309 | country_code: '683',
1310 | country_name: 'Niue',
1311 | mobile_begin_with: [],
1312 | phone_number_lengths: [4]
1313 | },
1314 | {
1315 | alpha2: 'NL',
1316 | alpha3: 'NLD',
1317 | country_code: '31',
1318 | country_name: 'Netherlands',
1319 | mobile_begin_with: ['6', '97'],
1320 | phone_number_lengths: [9, 11]
1321 | },
1322 | {
1323 | alpha2: 'NO',
1324 | alpha3: 'NOR',
1325 | country_code: '47',
1326 | country_name: 'Norway',
1327 | mobile_begin_with: ['4', '9'],
1328 | phone_number_lengths: [8]
1329 | },
1330 | {
1331 | alpha2: 'NP',
1332 | alpha3: 'NPL',
1333 | country_code: '977',
1334 | country_name: 'Nepal',
1335 | mobile_begin_with: ['97', '98'],
1336 | phone_number_lengths: [10]
1337 | },
1338 | {
1339 | alpha2: 'NR',
1340 | alpha3: 'NRU',
1341 | country_code: '674',
1342 | country_name: 'Nauru',
1343 | mobile_begin_with: ['555'],
1344 | phone_number_lengths: [7]
1345 | },
1346 | {
1347 | alpha2: 'NZ',
1348 | alpha3: 'NZL',
1349 | country_code: '64',
1350 | country_name: 'New Zealand',
1351 | mobile_begin_with: ['2'],
1352 | phone_number_lengths: [8, 9, 10]
1353 | },
1354 | {
1355 | alpha2: 'OM',
1356 | alpha3: 'OMN',
1357 | country_code: '968',
1358 | country_name: 'Oman',
1359 | mobile_begin_with: ['7', '9'],
1360 | phone_number_lengths: [8]
1361 | },
1362 | {
1363 | alpha2: 'PK',
1364 | alpha3: 'PAK',
1365 | country_code: '92',
1366 | country_name: 'Pakistan',
1367 | mobile_begin_with: ['3'],
1368 | phone_number_lengths: [10]
1369 | },
1370 | {
1371 | alpha2: 'PA',
1372 | alpha3: 'PAN',
1373 | country_code: '507',
1374 | country_name: 'Panama',
1375 | mobile_begin_with: ['6'],
1376 | phone_number_lengths: [8]
1377 | },
1378 | // {alpha2: "PN", alpha3: "PCN", country_code: "", country_name: "Pitcairn", mobile_begin_with: [], phone_number_lengths: []},
1379 | {
1380 | alpha2: 'PE',
1381 | alpha3: 'PER',
1382 | country_code: '51',
1383 | country_name: 'Peru',
1384 | mobile_begin_with: ['9'],
1385 | phone_number_lengths: [9]
1386 | },
1387 | {
1388 | alpha2: 'PH',
1389 | alpha3: 'PHL',
1390 | country_code: '63',
1391 | country_name: 'Philippines',
1392 | mobile_begin_with: ['9'],
1393 | phone_number_lengths: [10]
1394 | },
1395 | {
1396 | alpha2: 'PW',
1397 | alpha3: 'PLW',
1398 | country_code: '680',
1399 | country_name: 'Palau',
1400 | mobile_begin_with: [],
1401 | phone_number_lengths: [7]
1402 | },
1403 | {
1404 | alpha2: 'PG',
1405 | alpha3: 'PNG',
1406 | country_code: '675',
1407 | country_name: 'Papua New Guinea',
1408 | mobile_begin_with: ['7'],
1409 | phone_number_lengths: [8]
1410 | },
1411 | {
1412 | alpha2: 'PL',
1413 | alpha3: 'POL',
1414 | country_code: '48',
1415 | country_name: 'Poland',
1416 | mobile_begin_with: ['4', '5', '6', '7', '8'],
1417 | phone_number_lengths: [9]
1418 | },
1419 | {
1420 | alpha2: 'PR',
1421 | alpha3: 'PRI',
1422 | country_code: '1',
1423 | country_name: 'Puerto Rico',
1424 | mobile_begin_with: ['787', '939'],
1425 | phone_number_lengths: [10]
1426 | },
1427 | // {alpha2: "KP", alpha3: "PRK", country_code: "850", country_name: "Korea, Democratic People's Republic Of", mobile_begin_with: [], phone_number_lengths: []},
1428 | {
1429 | alpha2: 'PT',
1430 | alpha3: 'PRT',
1431 | country_code: '351',
1432 | country_name: 'Portugal',
1433 | mobile_begin_with: ['9'],
1434 | phone_number_lengths: [9]
1435 | },
1436 | {
1437 | alpha2: 'PY',
1438 | alpha3: 'PRY',
1439 | country_code: '595',
1440 | country_name: 'Paraguay',
1441 | mobile_begin_with: ['9'],
1442 | phone_number_lengths: [9]
1443 | },
1444 | {
1445 | alpha2: 'PS',
1446 | alpha3: 'PSE',
1447 | country_code: '970',
1448 | country_name: 'Palestinian Territory, Occupied',
1449 | mobile_begin_with: ['5'],
1450 | phone_number_lengths: [9]
1451 | },
1452 | {
1453 | alpha2: 'PF',
1454 | alpha3: 'PYF',
1455 | country_code: '689',
1456 | country_name: 'French Polynesia',
1457 | mobile_begin_with: ['8'],
1458 | phone_number_lengths: [8]
1459 | },
1460 | {
1461 | alpha2: 'QA',
1462 | alpha3: 'QAT',
1463 | country_code: '974',
1464 | country_name: 'Qatar',
1465 | mobile_begin_with: ['3', '5', '6', '7'],
1466 | phone_number_lengths: [8]
1467 | },
1468 | {
1469 | alpha2: 'RE',
1470 | alpha3: 'REU',
1471 | country_code: '262',
1472 | country_name: 'Réunion',
1473 | mobile_begin_with: ['692', '693'],
1474 | phone_number_lengths: [9]
1475 | },
1476 | {
1477 | alpha2: 'RO',
1478 | alpha3: 'ROU',
1479 | country_code: '40',
1480 | country_name: 'Romania',
1481 | mobile_begin_with: ['7'],
1482 | phone_number_lengths: [9]
1483 | },
1484 | {
1485 | alpha2: 'RU',
1486 | alpha3: 'RUS',
1487 | country_code: '7',
1488 | country_name: 'Russian Federation',
1489 | mobile_begin_with: ['9', '495', '498', '499', '835'],
1490 | phone_number_lengths: [10]
1491 | },
1492 | {
1493 | alpha2: 'RW',
1494 | alpha3: 'RWA',
1495 | country_code: '250',
1496 | country_name: 'Rwanda',
1497 | mobile_begin_with: ['7'],
1498 | phone_number_lengths: [9]
1499 | },
1500 | {
1501 | alpha2: 'SA',
1502 | alpha3: 'SAU',
1503 | country_code: '966',
1504 | country_name: 'Saudi Arabia',
1505 | mobile_begin_with: ['5'],
1506 | phone_number_lengths: [9]
1507 | },
1508 | {
1509 | alpha2: 'SD',
1510 | alpha3: 'SDN',
1511 | country_code: '249',
1512 | country_name: 'Sudan',
1513 | mobile_begin_with: ['9'],
1514 | phone_number_lengths: [9]
1515 | },
1516 | {
1517 | alpha2: 'SS',
1518 | alpha3: 'SSD',
1519 | country_code: '211',
1520 | country_name: 'South Sudan',
1521 | mobile_begin_with: ['9'],
1522 | phone_number_lengths: [9]
1523 | },
1524 | {
1525 | alpha2: 'SN',
1526 | alpha3: 'SEN',
1527 | country_code: '221',
1528 | country_name: 'Senegal',
1529 | mobile_begin_with: ['7'],
1530 | phone_number_lengths: [9]
1531 | },
1532 | {
1533 | alpha2: 'SG',
1534 | alpha3: 'SGP',
1535 | country_code: '65',
1536 | country_name: 'Singapore',
1537 | mobile_begin_with: ['8', '9'],
1538 | phone_number_lengths: [8]
1539 | },
1540 | // {alpha2: "GS", alpha3: "SGS", country_code: "500", country_name: "South Georgia and the South Sandwich Islands", mobile_begin_with: [], phone_number_lengths: []},
1541 | {
1542 | alpha2: 'SH',
1543 | alpha3: 'SHN',
1544 | country_code: '290',
1545 | country_name: 'Saint Helena',
1546 | mobile_begin_with: [],
1547 | phone_number_lengths: [4]
1548 | },
1549 | {
1550 | alpha2: 'SJ',
1551 | alpha3: 'SJM',
1552 | country_code: '47',
1553 | country_name: 'Svalbard And Jan Mayen',
1554 | mobile_begin_with: ['79'],
1555 | phone_number_lengths: [8]
1556 | },
1557 | {
1558 | alpha2: 'SB',
1559 | alpha3: 'SLB',
1560 | country_code: '677',
1561 | country_name: 'Solomon Islands',
1562 | mobile_begin_with: ['7', '8'],
1563 | phone_number_lengths: [7]
1564 | },
1565 | {
1566 | alpha2: 'SL',
1567 | alpha3: 'SLE',
1568 | country_code: '232',
1569 | country_name: 'Sierra Leone',
1570 | mobile_begin_with: ['21', '25', '30', '33', '34', '40', '44', '50', '55', '76', '77', '78', '79', '88'],
1571 | phone_number_lengths: [8]
1572 | },
1573 | {
1574 | alpha2: 'SV',
1575 | alpha3: 'SLV',
1576 | country_code: '503',
1577 | country_name: 'El Salvador',
1578 | mobile_begin_with: ['6', '7'],
1579 | phone_number_lengths: [8]
1580 | },
1581 | {
1582 | alpha2: 'SM',
1583 | alpha3: 'SMR',
1584 | country_code: '378',
1585 | country_name: 'San Marino',
1586 | mobile_begin_with: ['3', '6'],
1587 | phone_number_lengths: [10]
1588 | },
1589 | {
1590 | alpha2: 'SO',
1591 | alpha3: 'SOM',
1592 | country_code: '252',
1593 | country_name: 'Somalia',
1594 | mobile_begin_with: ['61', '62', '63', '65', '66', '68', '69', '71', '90'],
1595 | phone_number_lengths: [9]
1596 | },
1597 | {
1598 | alpha2: 'SX',
1599 | alpha3: 'SXM',
1600 | country_code: '1',
1601 | country_name: 'Sint Maarten',
1602 | mobile_begin_with: ['721'],
1603 | phone_number_lengths: [10]
1604 | },
1605 | {
1606 | alpha2: 'PM',
1607 | alpha3: 'SPM',
1608 | country_code: '508',
1609 | country_name: 'Saint Pierre And Miquelon',
1610 | mobile_begin_with: ['55', '41'],
1611 | phone_number_lengths: [6]
1612 | },
1613 | {
1614 | alpha2: 'RS',
1615 | alpha3: 'SRB',
1616 | country_code: '381',
1617 | country_name: 'Serbia',
1618 | mobile_begin_with: ['6'],
1619 | phone_number_lengths: [8, 9]
1620 | },
1621 | {
1622 | alpha2: 'ST',
1623 | alpha3: 'STP',
1624 | country_code: '239',
1625 | country_name: 'Sao Tome and Principe',
1626 | mobile_begin_with: ['98', '99'],
1627 | phone_number_lengths: [7]
1628 | },
1629 | {
1630 | alpha2: 'SR',
1631 | alpha3: 'SUR',
1632 | country_code: '597',
1633 | country_name: 'Suriname',
1634 | mobile_begin_with: ['6', '7', '8'],
1635 | phone_number_lengths: [7]
1636 | },
1637 | {
1638 | alpha2: 'SK',
1639 | alpha3: 'SVK',
1640 | country_code: '421',
1641 | country_name: 'Slovakia',
1642 | mobile_begin_with: ['9'],
1643 | phone_number_lengths: [9]
1644 | },
1645 | {
1646 | alpha2: 'SI',
1647 | alpha3: 'SVN',
1648 | country_code: '386',
1649 | country_name: 'Slovenia',
1650 | mobile_begin_with: ['3', '4', '5', '6', '7'],
1651 | phone_number_lengths: [8]
1652 | },
1653 | {
1654 | alpha2: 'SE',
1655 | alpha3: 'SWE',
1656 | country_code: '46',
1657 | country_name: 'Sweden',
1658 | mobile_begin_with: ['7'],
1659 | phone_number_lengths: [9]
1660 | },
1661 | {
1662 | alpha2: 'SZ',
1663 | alpha3: 'SWZ',
1664 | country_code: '268',
1665 | country_name: 'Swaziland',
1666 | mobile_begin_with: ['76', '77', '78', '79'],
1667 | phone_number_lengths: [8]
1668 | },
1669 | {
1670 | alpha2: 'SC',
1671 | alpha3: 'SYC',
1672 | country_code: '248',
1673 | country_name: 'Seychelles',
1674 | mobile_begin_with: ['2'],
1675 | phone_number_lengths: [7]
1676 | },
1677 | {
1678 | alpha2: 'SY',
1679 | alpha3: 'SYR',
1680 | country_code: '963',
1681 | country_name: 'Syrian Arab Republic',
1682 | mobile_begin_with: ['9'],
1683 | phone_number_lengths: [9]
1684 | },
1685 | // http://www.howtocallabroad.com/turks-caicos/
1686 | {
1687 | alpha2: 'TC',
1688 | alpha3: 'TCA',
1689 | country_code: '1',
1690 | country_name: 'Turks and Caicos Islands',
1691 | mobile_begin_with: ['6492', '6493', '6494'],
1692 | phone_number_lengths: [10]
1693 | },
1694 | {
1695 | alpha2: 'TD',
1696 | alpha3: 'TCD',
1697 | country_code: '235',
1698 | country_name: 'Chad',
1699 | mobile_begin_with: ['6', '7', '9'],
1700 | phone_number_lengths: [8]
1701 | },
1702 | {
1703 | alpha2: 'TG',
1704 | alpha3: 'TGO',
1705 | country_code: '228',
1706 | country_name: 'Togo',
1707 | mobile_begin_with: ['9'],
1708 | phone_number_lengths: [8]
1709 | },
1710 | {
1711 | alpha2: 'TH',
1712 | alpha3: 'THA',
1713 | country_code: '66',
1714 | country_name: 'Thailand',
1715 | mobile_begin_with: ['6', '8', '9'],
1716 | phone_number_lengths: [9]
1717 | },
1718 | {
1719 | alpha2: 'TJ',
1720 | alpha3: 'TJK',
1721 | country_code: '992',
1722 | country_name: 'Tajikistan',
1723 | mobile_begin_with: ['9'],
1724 | phone_number_lengths: [9]
1725 | },
1726 | {
1727 | alpha2: 'TK',
1728 | alpha3: 'TKL',
1729 | country_code: '690',
1730 | country_name: 'Tokelau',
1731 | mobile_begin_with: [],
1732 | phone_number_lengths: [4]
1733 | },
1734 | {
1735 | alpha2: 'TM',
1736 | alpha3: 'TKM',
1737 | country_code: '993',
1738 | country_name: 'Turkmenistan',
1739 | mobile_begin_with: ['6'],
1740 | phone_number_lengths: [8]
1741 | },
1742 | {
1743 | alpha2: 'TL',
1744 | alpha3: 'TLS',
1745 | country_code: '670',
1746 | country_name: 'Timor-Leste',
1747 | mobile_begin_with: ['7'],
1748 | phone_number_lengths: [8]
1749 | },
1750 | {
1751 | alpha2: 'TO',
1752 | alpha3: 'TON',
1753 | country_code: '676',
1754 | country_name: 'Tonga',
1755 | mobile_begin_with: [],
1756 | phone_number_lengths: [5]
1757 | },
1758 | {
1759 | alpha2: 'TT',
1760 | alpha3: 'TTO',
1761 | country_code: '1',
1762 | country_name: 'Trinidad and Tobago',
1763 | mobile_begin_with: ['868'],
1764 | phone_number_lengths: [10]
1765 | },
1766 | {
1767 | alpha2: 'TN',
1768 | alpha3: 'TUN',
1769 | country_code: '216',
1770 | country_name: 'Tunisia',
1771 | mobile_begin_with: ['2', '4', '5', '9'],
1772 | phone_number_lengths: [8]
1773 | },
1774 | {
1775 | alpha2: 'TR',
1776 | alpha3: 'TUR',
1777 | country_code: '90',
1778 | country_name: 'Turkey',
1779 | mobile_begin_with: ['5'],
1780 | phone_number_lengths: [10]
1781 | },
1782 | {
1783 | alpha2: 'TV',
1784 | alpha3: 'TUV',
1785 | country_code: '688',
1786 | country_name: 'Tuvalu',
1787 | mobile_begin_with: [],
1788 | phone_number_lengths: [5]
1789 | },
1790 | {
1791 | alpha2: 'TW',
1792 | alpha3: 'TWN',
1793 | country_code: '886',
1794 | country_name: 'Taiwan',
1795 | mobile_begin_with: ['9'],
1796 | phone_number_lengths: [9]
1797 | },
1798 | {
1799 | alpha2: 'TZ',
1800 | alpha3: 'TZA',
1801 | country_code: '255',
1802 | country_name: 'Tanzania, United Republic of',
1803 | mobile_begin_with: ['7', '6'],
1804 | phone_number_lengths: [9]
1805 | },
1806 | {
1807 | alpha2: 'UG',
1808 | alpha3: 'UGA',
1809 | country_code: '256',
1810 | country_name: 'Uganda',
1811 | mobile_begin_with: ['7'],
1812 | phone_number_lengths: [9]
1813 | },
1814 | {
1815 | alpha2: 'UA',
1816 | alpha3: 'UKR',
1817 | country_code: '380',
1818 | country_name: 'Ukraine',
1819 | mobile_begin_with: ['39', '50', '63', '66', '67', '68', '73', '75', '77', '9'],
1820 | phone_number_lengths: [9]
1821 | },
1822 | // {alpha2: "UM", alpha3: "UMI", country_code: "", country_name: "United States Minor Outlying Islands", mobile_begin_with: [], phone_number_lengths: []},
1823 | {
1824 | alpha2: 'UY',
1825 | alpha3: 'URY',
1826 | country_code: '598',
1827 | country_name: 'Uruguay',
1828 | mobile_begin_with: ['9'],
1829 | phone_number_lengths: [8]
1830 | },
1831 | {
1832 | alpha2: 'UZ',
1833 | alpha3: 'UZB',
1834 | country_code: '998',
1835 | country_name: 'Uzbekistan',
1836 | mobile_begin_with: ['9', '88', '33'],
1837 | phone_number_lengths: [9]
1838 | },
1839 | // {alpha2: "VA", alpha3: "VAT", country_code: "39", country_name: "Holy See (Vatican City State)", mobile_begin_with: [], phone_number_lengths: []},
1840 | {
1841 | alpha2: 'VC',
1842 | alpha3: 'VCT',
1843 | country_code: '1',
1844 | country_name: 'Saint Vincent And The Grenedines',
1845 | mobile_begin_with: ['784'],
1846 | phone_number_lengths: [10]
1847 | },
1848 | {
1849 | alpha2: 'VE',
1850 | alpha3: 'VEN',
1851 | country_code: '58',
1852 | country_name: 'Venezuela, Bolivarian Republic of',
1853 | mobile_begin_with: ['4'],
1854 | phone_number_lengths: [10]
1855 | },
1856 | {
1857 | alpha2: 'VG',
1858 | alpha3: 'VGB',
1859 | country_code: '1',
1860 | country_name: 'Virgin Islands, British',
1861 | mobile_begin_with: ['284'],
1862 | phone_number_lengths: [10]
1863 | },
1864 | {
1865 | alpha2: 'VI',
1866 | alpha3: 'VIR',
1867 | country_code: '1',
1868 | country_name: 'Virgin Islands, U.S.',
1869 | mobile_begin_with: ['340'],
1870 | phone_number_lengths: [10]
1871 | },
1872 | {
1873 | alpha2: 'VN',
1874 | alpha3: 'VNM',
1875 | country_code: '84',
1876 | country_name: 'Viet Nam',
1877 | mobile_begin_with: ['8', '9', '3', '7', '5'],
1878 | phone_number_lengths: [9]
1879 | },
1880 | {
1881 | alpha2: 'VU',
1882 | alpha3: 'VUT',
1883 | country_code: '678',
1884 | country_name: 'Vanuatu',
1885 | mobile_begin_with: ['5', '7'],
1886 | phone_number_lengths: [7]
1887 | },
1888 | {
1889 | alpha2: 'WF',
1890 | alpha3: 'WLF',
1891 | country_code: '681',
1892 | country_name: 'Wallis and Futuna',
1893 | mobile_begin_with: [],
1894 | phone_number_lengths: [6]
1895 | },
1896 | {
1897 | alpha2: 'WS',
1898 | alpha3: 'WSM',
1899 | country_code: '685',
1900 | country_name: 'Samoa',
1901 | mobile_begin_with: ['7'],
1902 | phone_number_lengths: [7]
1903 | },
1904 | {
1905 | alpha2: 'YE',
1906 | alpha3: 'YEM',
1907 | country_code: '967',
1908 | country_name: 'Yemen',
1909 | mobile_begin_with: ['7'],
1910 | phone_number_lengths: [9]
1911 | },
1912 | {
1913 | alpha2: 'ZA',
1914 | alpha3: 'ZAF',
1915 | country_code: '27',
1916 | country_name: 'South Africa',
1917 | mobile_begin_with: ['1', '2', '3', '4', '5', '6', '7', '8'],
1918 | phone_number_lengths: [9]
1919 | },
1920 | {
1921 | alpha2: 'ZM',
1922 | alpha3: 'ZMB',
1923 | country_code: '260',
1924 | country_name: 'Zambia',
1925 | mobile_begin_with: ['9', '7'],
1926 | phone_number_lengths: [9]
1927 | },
1928 | {
1929 | alpha2: 'ZW',
1930 | alpha3: 'ZWE',
1931 | country_code: '263',
1932 | country_name: 'Zimbabwe',
1933 | mobile_begin_with: ['71', '73', '77', '78'],
1934 | phone_number_lengths: [9]
1935 | }
1936 | ];
1937 |
--------------------------------------------------------------------------------