@webority-technologies/mobile-core 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/formatters/index.js +72 -0
- package/lib/commonjs/formatters/phone.js +221 -2
- package/lib/commonjs/index.js +72 -0
- package/lib/commonjs/phone/countries.js +265 -0
- package/lib/module/formatters/index.js +1 -1
- package/lib/module/formatters/phone.js +179 -2
- package/lib/module/index.js +5 -1
- package/lib/module/phone/countries.js +261 -0
- package/lib/typescript/commonjs/formatters/index.d.ts +2 -2
- package/lib/typescript/commonjs/formatters/phone.d.ts +92 -9
- package/lib/typescript/commonjs/index.d.ts +6 -2
- package/lib/typescript/commonjs/phone/countries.d.ts +13 -0
- package/lib/typescript/module/formatters/index.d.ts +2 -2
- package/lib/typescript/module/formatters/phone.d.ts +92 -9
- package/lib/typescript/module/index.d.ts +6 -2
- package/lib/typescript/module/phone/countries.d.ts +13 -0
- package/package.json +11 -1
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PHONE_COUNTRY_NAMES = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* English display names for every country libphonenumber-js knows, keyed by
|
|
9
|
+
* ISO 3166-1 alpha-2. GENERATED by scripts/gen-phone-countries.mjs from Node's
|
|
10
|
+
* Intl.DisplayNames('en', { type: 'region' }) over getCountries() on 2026-09-14;
|
|
11
|
+
* '&' is written as 'and'. Re-run the script rather than editing by hand.
|
|
12
|
+
*
|
|
13
|
+
* Lives on its own import path (mobile-core/phone/countries) so an app that
|
|
14
|
+
* never opens a full country list does not carry these 245 strings in its
|
|
15
|
+
* bundle. Pair with getPhoneCountries() from the package root for the calling
|
|
16
|
+
* codes; a country picker that needs another language supplies its own names.
|
|
17
|
+
*/
|
|
18
|
+
const PHONE_COUNTRY_NAMES = exports.PHONE_COUNTRY_NAMES = {
|
|
19
|
+
AF: 'Afghanistan',
|
|
20
|
+
AX: 'Åland Islands',
|
|
21
|
+
AL: 'Albania',
|
|
22
|
+
DZ: 'Algeria',
|
|
23
|
+
AS: 'American Samoa',
|
|
24
|
+
AD: 'Andorra',
|
|
25
|
+
AO: 'Angola',
|
|
26
|
+
AI: 'Anguilla',
|
|
27
|
+
AG: 'Antigua and Barbuda',
|
|
28
|
+
AR: 'Argentina',
|
|
29
|
+
AM: 'Armenia',
|
|
30
|
+
AW: 'Aruba',
|
|
31
|
+
AC: 'Ascension Island',
|
|
32
|
+
AU: 'Australia',
|
|
33
|
+
AT: 'Austria',
|
|
34
|
+
AZ: 'Azerbaijan',
|
|
35
|
+
BS: 'Bahamas',
|
|
36
|
+
BH: 'Bahrain',
|
|
37
|
+
BD: 'Bangladesh',
|
|
38
|
+
BB: 'Barbados',
|
|
39
|
+
BY: 'Belarus',
|
|
40
|
+
BE: 'Belgium',
|
|
41
|
+
BZ: 'Belize',
|
|
42
|
+
BJ: 'Benin',
|
|
43
|
+
BM: 'Bermuda',
|
|
44
|
+
BT: 'Bhutan',
|
|
45
|
+
BO: 'Bolivia',
|
|
46
|
+
BA: 'Bosnia and Herzegovina',
|
|
47
|
+
BW: 'Botswana',
|
|
48
|
+
BR: 'Brazil',
|
|
49
|
+
IO: 'British Indian Ocean Territory',
|
|
50
|
+
VG: 'British Virgin Islands',
|
|
51
|
+
BN: 'Brunei',
|
|
52
|
+
BG: 'Bulgaria',
|
|
53
|
+
BF: 'Burkina Faso',
|
|
54
|
+
BI: 'Burundi',
|
|
55
|
+
KH: 'Cambodia',
|
|
56
|
+
CM: 'Cameroon',
|
|
57
|
+
CA: 'Canada',
|
|
58
|
+
CV: 'Cape Verde',
|
|
59
|
+
BQ: 'Caribbean Netherlands',
|
|
60
|
+
KY: 'Cayman Islands',
|
|
61
|
+
CF: 'Central African Republic',
|
|
62
|
+
TD: 'Chad',
|
|
63
|
+
CL: 'Chile',
|
|
64
|
+
CN: 'China',
|
|
65
|
+
CX: 'Christmas Island',
|
|
66
|
+
CC: 'Cocos (Keeling) Islands',
|
|
67
|
+
CO: 'Colombia',
|
|
68
|
+
KM: 'Comoros',
|
|
69
|
+
CG: 'Congo - Brazzaville',
|
|
70
|
+
CD: 'Congo - Kinshasa',
|
|
71
|
+
CK: 'Cook Islands',
|
|
72
|
+
CR: 'Costa Rica',
|
|
73
|
+
CI: 'Côte d’Ivoire',
|
|
74
|
+
HR: 'Croatia',
|
|
75
|
+
CU: 'Cuba',
|
|
76
|
+
CW: 'Curaçao',
|
|
77
|
+
CY: 'Cyprus',
|
|
78
|
+
CZ: 'Czechia',
|
|
79
|
+
DK: 'Denmark',
|
|
80
|
+
DJ: 'Djibouti',
|
|
81
|
+
DM: 'Dominica',
|
|
82
|
+
DO: 'Dominican Republic',
|
|
83
|
+
EC: 'Ecuador',
|
|
84
|
+
EG: 'Egypt',
|
|
85
|
+
SV: 'El Salvador',
|
|
86
|
+
GQ: 'Equatorial Guinea',
|
|
87
|
+
ER: 'Eritrea',
|
|
88
|
+
EE: 'Estonia',
|
|
89
|
+
SZ: 'Eswatini',
|
|
90
|
+
ET: 'Ethiopia',
|
|
91
|
+
FK: 'Falkland Islands',
|
|
92
|
+
FO: 'Faroe Islands',
|
|
93
|
+
FJ: 'Fiji',
|
|
94
|
+
FI: 'Finland',
|
|
95
|
+
FR: 'France',
|
|
96
|
+
GF: 'French Guiana',
|
|
97
|
+
PF: 'French Polynesia',
|
|
98
|
+
GA: 'Gabon',
|
|
99
|
+
GM: 'Gambia',
|
|
100
|
+
GE: 'Georgia',
|
|
101
|
+
DE: 'Germany',
|
|
102
|
+
GH: 'Ghana',
|
|
103
|
+
GI: 'Gibraltar',
|
|
104
|
+
GR: 'Greece',
|
|
105
|
+
GL: 'Greenland',
|
|
106
|
+
GD: 'Grenada',
|
|
107
|
+
GP: 'Guadeloupe',
|
|
108
|
+
GU: 'Guam',
|
|
109
|
+
GT: 'Guatemala',
|
|
110
|
+
GG: 'Guernsey',
|
|
111
|
+
GN: 'Guinea',
|
|
112
|
+
GW: 'Guinea-Bissau',
|
|
113
|
+
GY: 'Guyana',
|
|
114
|
+
HT: 'Haiti',
|
|
115
|
+
HN: 'Honduras',
|
|
116
|
+
HK: 'Hong Kong SAR China',
|
|
117
|
+
HU: 'Hungary',
|
|
118
|
+
IS: 'Iceland',
|
|
119
|
+
IN: 'India',
|
|
120
|
+
ID: 'Indonesia',
|
|
121
|
+
IR: 'Iran',
|
|
122
|
+
IQ: 'Iraq',
|
|
123
|
+
IE: 'Ireland',
|
|
124
|
+
IM: 'Isle of Man',
|
|
125
|
+
IL: 'Israel',
|
|
126
|
+
IT: 'Italy',
|
|
127
|
+
JM: 'Jamaica',
|
|
128
|
+
JP: 'Japan',
|
|
129
|
+
JE: 'Jersey',
|
|
130
|
+
JO: 'Jordan',
|
|
131
|
+
KZ: 'Kazakhstan',
|
|
132
|
+
KE: 'Kenya',
|
|
133
|
+
KI: 'Kiribati',
|
|
134
|
+
XK: 'Kosovo',
|
|
135
|
+
KW: 'Kuwait',
|
|
136
|
+
KG: 'Kyrgyzstan',
|
|
137
|
+
LA: 'Laos',
|
|
138
|
+
LV: 'Latvia',
|
|
139
|
+
LB: 'Lebanon',
|
|
140
|
+
LS: 'Lesotho',
|
|
141
|
+
LR: 'Liberia',
|
|
142
|
+
LY: 'Libya',
|
|
143
|
+
LI: 'Liechtenstein',
|
|
144
|
+
LT: 'Lithuania',
|
|
145
|
+
LU: 'Luxembourg',
|
|
146
|
+
MO: 'Macao SAR China',
|
|
147
|
+
MG: 'Madagascar',
|
|
148
|
+
MW: 'Malawi',
|
|
149
|
+
MY: 'Malaysia',
|
|
150
|
+
MV: 'Maldives',
|
|
151
|
+
ML: 'Mali',
|
|
152
|
+
MT: 'Malta',
|
|
153
|
+
MH: 'Marshall Islands',
|
|
154
|
+
MQ: 'Martinique',
|
|
155
|
+
MR: 'Mauritania',
|
|
156
|
+
MU: 'Mauritius',
|
|
157
|
+
YT: 'Mayotte',
|
|
158
|
+
MX: 'Mexico',
|
|
159
|
+
FM: 'Micronesia',
|
|
160
|
+
MD: 'Moldova',
|
|
161
|
+
MC: 'Monaco',
|
|
162
|
+
MN: 'Mongolia',
|
|
163
|
+
ME: 'Montenegro',
|
|
164
|
+
MS: 'Montserrat',
|
|
165
|
+
MA: 'Morocco',
|
|
166
|
+
MZ: 'Mozambique',
|
|
167
|
+
MM: 'Myanmar (Burma)',
|
|
168
|
+
NA: 'Namibia',
|
|
169
|
+
NR: 'Nauru',
|
|
170
|
+
NP: 'Nepal',
|
|
171
|
+
NL: 'Netherlands',
|
|
172
|
+
NC: 'New Caledonia',
|
|
173
|
+
NZ: 'New Zealand',
|
|
174
|
+
NI: 'Nicaragua',
|
|
175
|
+
NE: 'Niger',
|
|
176
|
+
NG: 'Nigeria',
|
|
177
|
+
NU: 'Niue',
|
|
178
|
+
NF: 'Norfolk Island',
|
|
179
|
+
KP: 'North Korea',
|
|
180
|
+
MK: 'North Macedonia',
|
|
181
|
+
MP: 'Northern Mariana Islands',
|
|
182
|
+
NO: 'Norway',
|
|
183
|
+
OM: 'Oman',
|
|
184
|
+
PK: 'Pakistan',
|
|
185
|
+
PW: 'Palau',
|
|
186
|
+
PS: 'Palestinian Territories',
|
|
187
|
+
PA: 'Panama',
|
|
188
|
+
PG: 'Papua New Guinea',
|
|
189
|
+
PY: 'Paraguay',
|
|
190
|
+
PE: 'Peru',
|
|
191
|
+
PH: 'Philippines',
|
|
192
|
+
PL: 'Poland',
|
|
193
|
+
PT: 'Portugal',
|
|
194
|
+
PR: 'Puerto Rico',
|
|
195
|
+
QA: 'Qatar',
|
|
196
|
+
RE: 'Réunion',
|
|
197
|
+
RO: 'Romania',
|
|
198
|
+
RU: 'Russia',
|
|
199
|
+
RW: 'Rwanda',
|
|
200
|
+
WS: 'Samoa',
|
|
201
|
+
SM: 'San Marino',
|
|
202
|
+
ST: 'São Tomé and Príncipe',
|
|
203
|
+
SA: 'Saudi Arabia',
|
|
204
|
+
SN: 'Senegal',
|
|
205
|
+
RS: 'Serbia',
|
|
206
|
+
SC: 'Seychelles',
|
|
207
|
+
SL: 'Sierra Leone',
|
|
208
|
+
SG: 'Singapore',
|
|
209
|
+
SX: 'Sint Maarten',
|
|
210
|
+
SK: 'Slovakia',
|
|
211
|
+
SI: 'Slovenia',
|
|
212
|
+
SB: 'Solomon Islands',
|
|
213
|
+
SO: 'Somalia',
|
|
214
|
+
ZA: 'South Africa',
|
|
215
|
+
KR: 'South Korea',
|
|
216
|
+
SS: 'South Sudan',
|
|
217
|
+
ES: 'Spain',
|
|
218
|
+
LK: 'Sri Lanka',
|
|
219
|
+
BL: 'St. Barthélemy',
|
|
220
|
+
SH: 'St. Helena',
|
|
221
|
+
KN: 'St. Kitts and Nevis',
|
|
222
|
+
LC: 'St. Lucia',
|
|
223
|
+
MF: 'St. Martin',
|
|
224
|
+
PM: 'St. Pierre and Miquelon',
|
|
225
|
+
VC: 'St. Vincent and Grenadines',
|
|
226
|
+
SD: 'Sudan',
|
|
227
|
+
SR: 'Suriname',
|
|
228
|
+
SJ: 'Svalbard and Jan Mayen',
|
|
229
|
+
SE: 'Sweden',
|
|
230
|
+
CH: 'Switzerland',
|
|
231
|
+
SY: 'Syria',
|
|
232
|
+
TW: 'Taiwan',
|
|
233
|
+
TJ: 'Tajikistan',
|
|
234
|
+
TZ: 'Tanzania',
|
|
235
|
+
TH: 'Thailand',
|
|
236
|
+
TL: 'Timor-Leste',
|
|
237
|
+
TG: 'Togo',
|
|
238
|
+
TK: 'Tokelau',
|
|
239
|
+
TO: 'Tonga',
|
|
240
|
+
TT: 'Trinidad and Tobago',
|
|
241
|
+
TA: 'Tristan da Cunha',
|
|
242
|
+
TN: 'Tunisia',
|
|
243
|
+
TR: 'Türkiye',
|
|
244
|
+
TM: 'Turkmenistan',
|
|
245
|
+
TC: 'Turks and Caicos Islands',
|
|
246
|
+
TV: 'Tuvalu',
|
|
247
|
+
VI: 'U.S. Virgin Islands',
|
|
248
|
+
UG: 'Uganda',
|
|
249
|
+
UA: 'Ukraine',
|
|
250
|
+
AE: 'United Arab Emirates',
|
|
251
|
+
GB: 'United Kingdom',
|
|
252
|
+
US: 'United States',
|
|
253
|
+
UY: 'Uruguay',
|
|
254
|
+
UZ: 'Uzbekistan',
|
|
255
|
+
VU: 'Vanuatu',
|
|
256
|
+
VA: 'Vatican City',
|
|
257
|
+
VE: 'Venezuela',
|
|
258
|
+
VN: 'Vietnam',
|
|
259
|
+
WF: 'Wallis and Futuna',
|
|
260
|
+
EH: 'Western Sahara',
|
|
261
|
+
YE: 'Yemen',
|
|
262
|
+
ZM: 'Zambia',
|
|
263
|
+
ZW: 'Zimbabwe'
|
|
264
|
+
};
|
|
265
|
+
//# sourceMappingURL=countries.js.map
|
|
@@ -5,5 +5,5 @@ export { formatDate, formatDateTime, formatRelativeTime, formatTime } from "./da
|
|
|
5
5
|
export { addDays, diffMs, formatDateDDMMMYYYY, formatDateISO, formatDatePattern, formatTime12h, formatTimeInWindowsZone, formatTimeInZone, isDateAfter, isDateBefore, isSameDay, startOfDay } from "./dateMath.js";
|
|
6
6
|
export { getInitials } from "./initials.js";
|
|
7
7
|
export { formatCompactNumber, formatNumber, formatPercent } from "./number.js";
|
|
8
|
-
export { detectPhoneCountry, formatPhone, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from "./phone.js";
|
|
8
|
+
export { AsYouType, clampNationalNumber, countryFlagEmoji, detectPhoneCountry, formatPhone, formatPhoneAsTyped, getCountries, getCountryCallingCode, getPhoneCountries, isSupportedCountry, isValidNationalNumber, isValidPhoneNumber, maxNationalNumberLength, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString, splitPhoneNumber, validatePhoneNumberLength } from "./phone.js";
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -7,8 +7,13 @@
|
|
|
7
7
|
* module exists is validation and formatting accuracy, the more accurate
|
|
8
8
|
* variant wins throughout this file, not just for validation.
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import { Metadata } from 'libphonenumber-js/core';
|
|
11
|
+
import { AsYouType, getCountries, getCountryCallingCode, parsePhoneNumberFromString, validatePhoneNumberLength } from 'libphonenumber-js/max';
|
|
12
|
+
// `Metadata` comes from the core entry with the max data passed in by hand:
|
|
13
|
+
// the max entry exports it in its ESM build only, and the CommonJS build jest
|
|
14
|
+
// and node resolve has no `Metadata` at all (libphonenumber-js 1.13.12).
|
|
15
|
+
import phoneMetadata from 'libphonenumber-js/metadata.max.json';
|
|
16
|
+
export { AsYouType, getCountries, getCountryCallingCode, isSupportedCountry, isValidPhoneNumber, parsePhoneNumber, parsePhoneNumberFromString, validatePhoneNumberLength } from 'libphonenumber-js/max';
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
19
|
* Re-exported under our own name rather than importing CountryCode directly
|
|
@@ -122,4 +127,176 @@ export function formatPhone(input, arg) {
|
|
|
122
127
|
}
|
|
123
128
|
return fallbackRest.startsWith('+') ? bestEffortGroup(fallbackRest.slice(1)) : fallbackRest.replace(/(.{4})(?=.)/g, '$1 ').trim();
|
|
124
129
|
}
|
|
130
|
+
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Structured-value helpers. These back PhoneNumberInput in mobile-ui, and are
|
|
133
|
+
// exported so an app's own form and API code validates with the same rules
|
|
134
|
+
// the field shows on screen, rather than a second regex table.
|
|
135
|
+
// ---------------------------------------------------------------------------
|
|
136
|
+
|
|
137
|
+
/** Country calling code + national digits, the way a phone field stores them. */
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Which kinds of number count as valid. `'any'` is libphonenumber's own
|
|
141
|
+
* answer (a fixed line passes). `'mobile'` narrows to MOBILE and
|
|
142
|
+
* FIXED_LINE_OR_MOBILE, which is what an OTP or WhatsApp field wants: in India
|
|
143
|
+
* a 10-digit number starting with 1 to 5 is a real fixed line and passes
|
|
144
|
+
* `'any'`, but no SMS will ever reach it.
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
const onlyDigits = input => input.replace(/\D/g, '');
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Split a typed or pasted number into calling code + national digits.
|
|
151
|
+
* `'+919876543210'` resolves to IN / 91 / 9876543210 from its own prefix; a
|
|
152
|
+
* bare `'9876543210'` needs `defaultCountry` to resolve at all. Returns null
|
|
153
|
+
* when the input has no digits or no country can be told. A shared calling
|
|
154
|
+
* code (`+1` for US and CA) resolves to the country whose area code matches,
|
|
155
|
+
* which is why the country comes back as part of the answer rather than being
|
|
156
|
+
* looked up again from the code.
|
|
157
|
+
*/
|
|
158
|
+
export const splitPhoneNumber = (input, defaultCountry) => {
|
|
159
|
+
const normalized = normalizePhone(input);
|
|
160
|
+
if (!normalized || onlyDigits(normalized).length === 0) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const parsed = normalized.startsWith('+') ? parsePhoneNumberFromString(normalized) : defaultCountry ? parsePhoneNumberFromString(normalized, defaultCountry) : undefined;
|
|
164
|
+
if (!parsed) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
country: parsed.country ?? null,
|
|
169
|
+
callingCode: parsed.countryCallingCode,
|
|
170
|
+
nationalNumber: parsed.nationalNumber
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Cut national digits that run past the longest number the country's plan
|
|
176
|
+
* allows, so a field stops accepting the impossible without a per-country
|
|
177
|
+
* length table. This is the PLAN's ceiling, not a mobile number's: India runs
|
|
178
|
+
* to 13 digits (toll-free 1800 numbers), the US to 10, Germany to 15. A field
|
|
179
|
+
* that should stop where a subscriber's number ends asks
|
|
180
|
+
* `maxNationalNumberLength` instead. Digits within range, including a number
|
|
181
|
+
* still too short, pass through untouched.
|
|
182
|
+
*/
|
|
183
|
+
export const clampNationalNumber = (nationalDigits, country) => {
|
|
184
|
+
let digits = onlyDigits(nationalDigits);
|
|
185
|
+
while (digits.length > 0 && validatePhoneNumberLength(digits, country) === 'TOO_LONG') {
|
|
186
|
+
digits = digits.slice(0, -1);
|
|
187
|
+
}
|
|
188
|
+
return digits;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// The number types a person types into a phone field. Toll-free, premium,
|
|
192
|
+
// shared-cost and pager ranges are what push a plan's ceiling past them.
|
|
193
|
+
const SUBSCRIBER_TYPES = {
|
|
194
|
+
any: ['MOBILE', 'FIXED_LINE'],
|
|
195
|
+
mobile: ['MOBILE']
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// libphonenumber-js types `numberingPlan` without its per-type accessor; the
|
|
199
|
+
// runtime object has it, and a type with no lengths of its own answers with the
|
|
200
|
+
// plan's.
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The most national digits a subscriber's number can have in a country, so a
|
|
204
|
+
* field can refuse the next digit as it is typed rather than trimming after.
|
|
205
|
+
* `'any'` (default) covers mobile and fixed lines, `'mobile'` mobiles only: India
|
|
206
|
+
* is 10 either way (its plan's 13 belongs to toll-free numbers), Germany is 15
|
|
207
|
+
* for `'any'` and 11 for `'mobile'`, the UAE 9. A country whose metadata lists
|
|
208
|
+
* no lengths by type falls back to the plan's longest number.
|
|
209
|
+
*/
|
|
210
|
+
export const maxNationalNumberLength = (country, kind = 'any') => {
|
|
211
|
+
const metadata = new Metadata(phoneMetadata);
|
|
212
|
+
metadata.selectNumberingPlan(country);
|
|
213
|
+
const plan = metadata.numberingPlan;
|
|
214
|
+
if (!plan) {
|
|
215
|
+
return E164_MAX_NATIONAL_DIGITS;
|
|
216
|
+
}
|
|
217
|
+
const byType = SUBSCRIBER_TYPES[kind].flatMap(type => plan.type(type)?.possibleLengths() ?? []);
|
|
218
|
+
return Math.max(...(byType.length > 0 ? byType : plan.possibleLengths()));
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// E.164 allows 15 digits in total; a national number can never exceed it.
|
|
222
|
+
const E164_MAX_NATIONAL_DIGITS = 15;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* National digits grouped the way the country writes them, updated on every
|
|
226
|
+
* keystroke: `'98765'` for IN is `'98765'`, `'9876543210'` is `'98765 43210'`,
|
|
227
|
+
* `'2025550123'` for US is `'(202) 555-0123'`. Output is for display only; the
|
|
228
|
+
* digits are what a value stores. Digits past the plan's longest possible
|
|
229
|
+
* number are dropped first, so an overflowing paste never formats as a longer
|
|
230
|
+
* number; digits that fit no pattern come back ungrouped rather than forced
|
|
231
|
+
* into a shape.
|
|
232
|
+
*
|
|
233
|
+
* Countries that write a leading 0 (the UAE, the UK, Australia, Saudi Arabia)
|
|
234
|
+
* only group in national mode when that 0 is typed, and a value never holds
|
|
235
|
+
* it. When national mode hands the digits back untouched, the grouping comes
|
|
236
|
+
* from the international form with the calling code removed: `'501234567'`
|
|
237
|
+
* for AE is `'50 123 4567'`. Countries that group nationally are unaffected.
|
|
238
|
+
*/
|
|
239
|
+
export const formatPhoneAsTyped = (nationalDigits, country) => {
|
|
240
|
+
const digits = clampNationalNumber(nationalDigits, country);
|
|
241
|
+
if (!digits) {
|
|
242
|
+
return '';
|
|
243
|
+
}
|
|
244
|
+
const national = new AsYouType(country).input(digits);
|
|
245
|
+
if (national !== digits) {
|
|
246
|
+
return national;
|
|
247
|
+
}
|
|
248
|
+
const prefix = `+${getCountryCallingCode(country)}`;
|
|
249
|
+
const international = new AsYouType().input(`${prefix}${digits}`);
|
|
250
|
+
return international.startsWith(prefix) ? international.slice(prefix.length).trimStart() || digits : digits;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Whether national digits form a real number for the country, by the
|
|
255
|
+
* country's own numbering plan rather than a length check. `kind: 'mobile'`
|
|
256
|
+
* additionally rejects fixed lines; a number whose type the metadata cannot
|
|
257
|
+
* tell is accepted, since the metadata, not the number, is what is missing.
|
|
258
|
+
*/
|
|
259
|
+
export const isValidNationalNumber = (nationalDigits, country, kind = 'any') => {
|
|
260
|
+
const digits = onlyDigits(nationalDigits);
|
|
261
|
+
if (!digits) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
const parsed = parsePhoneNumberFromString(digits, country);
|
|
265
|
+
if (!parsed?.isValid()) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
if (kind === 'any') {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
const type = parsed.getType();
|
|
272
|
+
return type === undefined || type === 'MOBILE' || type === 'FIXED_LINE_OR_MOBILE';
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* The flag as an emoji built from the ISO code's two regional-indicator
|
|
277
|
+
* letters, so no font asset ships with the library: iOS and Android both draw
|
|
278
|
+
* these from the system font. An unknown or malformed code returns ''. (Windows
|
|
279
|
+
* browsers render the two letters instead of a flag; that is the platform, not
|
|
280
|
+
* the code.)
|
|
281
|
+
*/
|
|
282
|
+
export const countryFlagEmoji = iso => {
|
|
283
|
+
const code = iso.trim().toUpperCase();
|
|
284
|
+
if (!/^[A-Z]{2}$/.test(code)) {
|
|
285
|
+
return '';
|
|
286
|
+
}
|
|
287
|
+
return String.fromCodePoint(0x1f1e6 + code.charCodeAt(0) - 65, 0x1f1e6 + code.charCodeAt(1) - 65);
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
/** Calling code + ISO for one country, the shape a country picker lists. */
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Every country libphonenumber-js knows, with its calling code, in metadata
|
|
294
|
+
* order. Names are deliberately not here: they are display data, in one
|
|
295
|
+
* language, and live on their own import path (`mobile-core/phone/countries`)
|
|
296
|
+
* so an app that never opens a full country list does not carry them.
|
|
297
|
+
*/
|
|
298
|
+
export const getPhoneCountries = () => getCountries().map(iso => ({
|
|
299
|
+
iso,
|
|
300
|
+
callingCode: getCountryCallingCode(iso)
|
|
301
|
+
}));
|
|
125
302
|
//# sourceMappingURL=phone.js.map
|
package/lib/module/index.js
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
* @webority-technologies/mobile-core/download a filesystem module
|
|
15
15
|
* @webority-technologies/mobile-core/smsRetriever Android only, own TurboModule
|
|
16
16
|
*
|
|
17
|
+
* One more path is separate for size, not for a native package:
|
|
18
|
+
*
|
|
19
|
+
* @webority-technologies/mobile-core/phone/countries 245 English country names
|
|
20
|
+
*
|
|
17
21
|
* react-native-keychain is the exception and is a REQUIRED peer: the HTTP client
|
|
18
22
|
* reads the bearer token, so it is reachable from the main barrel by design.
|
|
19
23
|
*/
|
|
@@ -30,7 +34,7 @@ export { getConfig, getConfigValue, resetConfig, setConfig } from "./config/inde
|
|
|
30
34
|
// Deep links
|
|
31
35
|
export { DeepLink, parseDeepLink, useDeepLink } from "./deepLink/index.js";
|
|
32
36
|
// Formatters
|
|
33
|
-
export { addDays, detectPhoneCountry, diffMs, formatCompactNumber, formatCurrency, formatDate, formatDateDDMMMYYYY, formatDateISO, formatDatePattern, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, formatTime12h, formatTimeInWindowsZone, formatTimeInZone, getInitials, isDateAfter, isDateBefore, isSameDay, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString, startOfDay } from "./formatters/index.js";
|
|
37
|
+
export { AsYouType, addDays, clampNationalNumber, countryFlagEmoji, detectPhoneCountry, diffMs, formatCompactNumber, formatCurrency, formatDate, formatDateDDMMMYYYY, formatDateISO, formatDatePattern, formatDateTime, formatNumber, formatPercent, formatPhone, formatPhoneAsTyped, formatRelativeTime, formatTime, formatTime12h, formatTimeInWindowsZone, formatTimeInZone, getCountries, getCountryCallingCode, getInitials, getPhoneCountries, isDateAfter, isDateBefore, isSameDay, isSupportedCountry, isValidNationalNumber, isValidPhoneNumber, maxNationalNumberLength, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString, splitPhoneNumber, startOfDay, validatePhoneNumberLength } from "./formatters/index.js";
|
|
34
38
|
// Initialization
|
|
35
39
|
export { initWebority } from "./initSDK.js";
|
|
36
40
|
export { initUserAuth } from "./initUserAuth.js";
|