@webority-technologies/mobile-core 0.0.2 → 0.0.4

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.
@@ -69,12 +69,30 @@ Object.defineProperty(exports, "getInitials", {
69
69
  return _initials.getInitials;
70
70
  }
71
71
  });
72
+ Object.defineProperty(exports, "isValidPhoneNumber", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _phone.isValidPhoneNumber;
76
+ }
77
+ });
72
78
  Object.defineProperty(exports, "normalizePhone", {
73
79
  enumerable: true,
74
80
  get: function () {
75
81
  return _phone.normalizePhone;
76
82
  }
77
83
  });
84
+ Object.defineProperty(exports, "parsePhoneNumber", {
85
+ enumerable: true,
86
+ get: function () {
87
+ return _phone.parsePhoneNumber;
88
+ }
89
+ });
90
+ Object.defineProperty(exports, "parsePhoneNumberFromString", {
91
+ enumerable: true,
92
+ get: function () {
93
+ return _phone.parsePhoneNumberFromString;
94
+ }
95
+ });
78
96
  var _currency = require("./currency.js");
79
97
  var _date = require("./date.js");
80
98
  var _initials = require("./initials.js");
@@ -5,7 +5,42 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.detectPhoneCountry = void 0;
7
7
  exports.formatPhone = formatPhone;
8
+ Object.defineProperty(exports, "isValidPhoneNumber", {
9
+ enumerable: true,
10
+ get: function () {
11
+ return _max.isValidPhoneNumber;
12
+ }
13
+ });
8
14
  exports.normalizePhone = void 0;
15
+ Object.defineProperty(exports, "parsePhoneNumber", {
16
+ enumerable: true,
17
+ get: function () {
18
+ return _max.parsePhoneNumber;
19
+ }
20
+ });
21
+ Object.defineProperty(exports, "parsePhoneNumberFromString", {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _max.parsePhoneNumberFromString;
25
+ }
26
+ });
27
+ var _max = require("libphonenumber-js/max");
28
+ /**
29
+ * The bare 'libphonenumber-js' entry point actually resolves to the library's
30
+ * OWN slimmed-down min/ metadata internally, not its full data - './max' is
31
+ * the variant with complete per-country metadata. Since the reason this
32
+ * module exists is validation and formatting accuracy, the more accurate
33
+ * variant wins throughout this file, not just for validation.
34
+ */
35
+
36
+ /**
37
+ * Re-exported under our own name rather than importing CountryCode directly
38
+ * everywhere, so a future need to diverge (or re-narrow) has one place to do
39
+ * it. Every ISO 3166-1 alpha-2 code libphonenumber-js recognises - formatPhone
40
+ * and detectPhoneCountry below are genuinely correct for all of them, not a
41
+ * curated subset.
42
+ */
43
+
9
44
  /**
10
45
  * Strip everything except digits and a leading `+` (preserved if present).
11
46
  */
@@ -18,82 +53,32 @@ const normalizePhone = input => {
18
53
  const digits = trimmed.replace(/\D/g, '');
19
54
  return hasPlus ? `+${digits}` : digits;
20
55
  };
21
- exports.normalizePhone = normalizePhone;
22
- const groupIndianMobile = digits => {
23
- // Indian mobile is 10 digits: format as `XXXXX XXXXX`.
24
- if (digits.length !== 10) {
25
- return digits;
26
- }
27
- return `${digits.slice(0, 5)} ${digits.slice(5)}`;
28
- };
29
-
30
- // Longest calling code first so a 3-digit code is never shadowed by a shorter one.
31
- const COUNTRY_RULES = [{
32
- country: 'AE',
33
- callingCode: '971',
34
- nationalLength: 9,
35
- group: n => `${n.slice(0, 2)} ${n.slice(2, 5)} ${n.slice(5)}`
36
- }, {
37
- country: 'IN',
38
- callingCode: '91',
39
- nationalLength: 10,
40
- group: groupIndianMobile
41
- }, {
42
- country: 'GB',
43
- callingCode: '44',
44
- nationalLength: 10,
45
- group: n => `${n.slice(0, 4)} ${n.slice(4, 7)} ${n.slice(7)}`
46
- }, {
47
- country: 'AU',
48
- callingCode: '61',
49
- nationalLength: 9,
50
- group: n => `${n.slice(0, 3)} ${n.slice(3, 6)} ${n.slice(6)}`
51
- }, {
52
- country: 'SG',
53
- callingCode: '65',
54
- nationalLength: 8,
55
- group: n => `${n.slice(0, 4)} ${n.slice(4)}`
56
- }, {
57
- country: 'US',
58
- callingCode: '1',
59
- nationalLength: 10,
60
- group: n => `(${n.slice(0, 3)}) ${n.slice(3, 6)}-${n.slice(6)}`
61
- },
62
- // US and CA share a calling code and are indistinguishable from it alone;
63
- // this row only serves an explicit `country: 'CA'` override, never detection
64
- // (it sits after the US row, and findRuleByCallingCode returns the first match).
65
- {
66
- country: 'CA',
67
- callingCode: '1',
68
- nationalLength: 10,
69
- group: n => `(${n.slice(0, 3)}) ${n.slice(3, 6)}-${n.slice(6)}`
70
- }];
71
- const findRuleByCallingCode = rest => COUNTRY_RULES.find(rule => rest.startsWith(rule.callingCode));
72
- const findRuleByCountry = country => COUNTRY_RULES.find(rule => rule.country === country);
73
56
 
74
57
  /**
75
58
  * Detect the country of a phone number: from its own `+` country code when
76
59
  * present, otherwise from `defaultCountryCode`. Returns null when neither
77
- * carries a recognised calling code.
60
+ * parses to a recognised country.
78
61
  */
62
+ exports.normalizePhone = normalizePhone;
79
63
  const detectPhoneCountry = (input, defaultCountryCode = '+91') => {
80
64
  const normalized = normalizePhone(input);
81
65
  if (!normalized) {
82
66
  return null;
83
67
  }
84
68
  if (normalized.startsWith('+')) {
85
- return findRuleByCallingCode(normalized.slice(1))?.country ?? null;
69
+ return (0, _max.parsePhoneNumberFromString)(normalized)?.country ?? null;
86
70
  }
87
71
  const normalizedDefault = normalizePhone(defaultCountryCode);
88
72
  if (!normalizedDefault.startsWith('+')) {
89
73
  return null;
90
74
  }
91
- return findRuleByCallingCode(normalizedDefault.slice(1))?.country ?? null;
75
+ return (0, _max.parsePhoneNumberFromString)(normalizedDefault + normalized)?.country ?? null;
92
76
  };
93
77
  exports.detectPhoneCountry = detectPhoneCountry;
94
78
  const bestEffortGroup = rest => {
95
- // No known country code matched (or matched but the wrong length): split
96
- // the country code (first 1-3 digits) and group the rest in 4s.
79
+ // Not a parseable number at all (garbage input, or a real number that's an
80
+ // unsupported length for its country): split the country code (first 1-3
81
+ // digits) and group the rest in 4s, rather than returning nothing.
97
82
  const ccLen = rest.length > 11 ? 3 : rest.length > 10 ? 2 : 1;
98
83
  const cc = rest.slice(0, ccLen);
99
84
  const number = rest.slice(ccLen);
@@ -102,13 +87,18 @@ const bestEffortGroup = rest => {
102
87
  };
103
88
 
104
89
  /**
105
- * Format a phone number for human display.
90
+ * Format a phone number for human display, via libphonenumber-js's own
91
+ * per-country formatting rather than a hand-rolled grouping table - correct
92
+ * for every country it recognises, not a curated subset.
106
93
  *
107
- * - Indian mobile (10 digits) `XXXXX XXXXX`
108
- * - With `+91` country code `+91 XXXXX XXXXX`
109
- * - A number that already carries a recognised country code is grouped for
110
- * that country regardless of `defaultCountryCode`.
111
- * - Other inputs are returned as `+CC NNNN NNNN…` best-effort grouping.
94
+ * - A number that already carries a `+` country code formats for that country.
95
+ * - A bare national number formats for `options.country` when given, else for
96
+ * the country implied by `defaultCountryCode` (default `+91`).
97
+ * - `includeCountryCode` controls international vs national format; defaults
98
+ * to international whenever the country was detected rather than passed in
99
+ * explicitly as `options.country`, and to national when it was.
100
+ * - Input libphonenumber-js can't parse into a valid number for the resolved
101
+ * country falls back to a best-effort `+CC NNNN NNNN…` digit grouping.
112
102
  */
113
103
 
114
104
  function formatPhone(input, arg) {
@@ -121,35 +111,40 @@ function formatPhone(input, arg) {
121
111
  }
122
112
  const options = typeof arg === 'string' ? {} : arg ?? {};
123
113
  const defaultCountryCode = typeof arg === 'string' ? arg : options.defaultCountryCode ?? '+91';
124
- if (normalized.startsWith('+')) {
125
- const rest = normalized.slice(1);
126
- const detectedRule = findRuleByCallingCode(rest);
127
- const activeRule = options.country ? findRuleByCountry(options.country) : detectedRule;
128
- if (activeRule) {
129
- const national = detectedRule ? rest.slice(detectedRule.callingCode.length) : rest;
130
- if (national.length === activeRule.nationalLength) {
131
- const includeCc = options.includeCountryCode ?? true;
132
- const body = activeRule.group(national);
133
- return includeCc ? `+${activeRule.callingCode} ${body}` : body;
134
- }
135
- }
136
- return bestEffortGroup(rest);
137
- }
114
+ const hasOwnCountryCode = normalized.startsWith('+');
115
+ let parsed;
116
+ // What to best-effort group if parsing fails to produce a valid number.
117
+ // Defaults to the plain input; the defaultCountryCode branch below points
118
+ // it at the combined digits instead, so a bare number that turns out
119
+ // invalid for its detected country still shows that country's code rather
120
+ // than silently discarding it.
121
+ let fallbackRest = normalized;
138
122
  if (options.country) {
139
- const rule = findRuleByCountry(options.country);
140
- if (rule && normalized.length === rule.nationalLength) {
141
- const includeCc = options.includeCountryCode ?? false;
142
- const body = rule.group(normalized);
143
- return includeCc ? `+${rule.callingCode} ${body}` : body;
123
+ // parsePhoneNumberFromString ignores this hint when normalized already
124
+ // carries its own +, so a real E.164 number is never overridden by a
125
+ // wrong or stale options.country.
126
+ parsed = (0, _max.parsePhoneNumberFromString)(normalized, options.country);
127
+ } else if (hasOwnCountryCode) {
128
+ parsed = (0, _max.parsePhoneNumberFromString)(normalized);
129
+ } else {
130
+ const normalizedDefault = normalizePhone(defaultCountryCode);
131
+ if (normalizedDefault.startsWith('+')) {
132
+ const combined = normalizedDefault + normalized;
133
+ parsed = (0, _max.parsePhoneNumberFromString)(combined);
134
+ fallbackRest = combined;
135
+ } else {
136
+ parsed = undefined;
144
137
  }
145
- return normalized.replace(/(.{4})(?=.)/g, '$1 ').trim();
146
138
  }
147
139
 
148
- // No country code; assume default if length matches Indian mobile.
149
- if (normalized.length === 10) {
150
- return `${defaultCountryCode} ${groupIndianMobile(normalized)}`;
140
+ // International by default whenever the country came from the number
141
+ // itself (or from defaultCountryCode); national by default only when a
142
+ // bare number relied on an explicit options.country to resolve at all.
143
+ const includeCcDefault = hasOwnCountryCode || !options.country;
144
+ if (parsed?.isValid()) {
145
+ const includeCc = options.includeCountryCode ?? includeCcDefault;
146
+ return includeCc ? parsed.formatInternational() : parsed.formatNational();
151
147
  }
152
- // Otherwise just return groups of 4.
153
- return normalized.replace(/(.{4})(?=.)/g, '$1 ').trim();
148
+ return fallbackRest.startsWith('+') ? bestEffortGroup(fallbackRest.slice(1)) : fallbackRest.replace(/(.{4})(?=.)/g, '$1 ').trim();
154
149
  }
155
150
  //# sourceMappingURL=phone.js.map
@@ -321,6 +321,12 @@ Object.defineProperty(exports, "isUrl", {
321
321
  return _index7.isUrl;
322
322
  }
323
323
  });
324
+ Object.defineProperty(exports, "isValidPhoneNumber", {
325
+ enumerable: true,
326
+ get: function () {
327
+ return _index3.isValidPhoneNumber;
328
+ }
329
+ });
324
330
  Object.defineProperty(exports, "logCurl", {
325
331
  enumerable: true,
326
332
  get: function () {
@@ -351,6 +357,18 @@ Object.defineProperty(exports, "parseDeepLink", {
351
357
  return _index2.parseDeepLink;
352
358
  }
353
359
  });
360
+ Object.defineProperty(exports, "parsePhoneNumber", {
361
+ enumerable: true,
362
+ get: function () {
363
+ return _index3.parsePhoneNumber;
364
+ }
365
+ });
366
+ Object.defineProperty(exports, "parsePhoneNumberFromString", {
367
+ enumerable: true,
368
+ get: function () {
369
+ return _index3.parsePhoneNumberFromString;
370
+ }
371
+ });
354
372
  Object.defineProperty(exports, "publicClient", {
355
373
  enumerable: true,
356
374
  get: function () {
@@ -196,7 +196,7 @@ const getAllKeys = async () => {
196
196
  * All operations swallow errors (logging them) and return a falsy result
197
197
  * so that storage problems never crash the app.
198
198
  *
199
- * Backed by `@react-native-async-storage/async-storage` by default;
199
+ * Backed by `expo-sqlite/kv-store` by default;
200
200
  * override with `setStorageImplementation()` for MMKV or custom adapters.
201
201
  */
202
202
  const Storage = exports.Storage = {
@@ -4,5 +4,5 @@ export { formatCurrency } from "./currency.js";
4
4
  export { formatDate, formatDateTime, formatRelativeTime, formatTime } from "./date.js";
5
5
  export { getInitials } from "./initials.js";
6
6
  export { formatCompactNumber, formatNumber, formatPercent } from "./number.js";
7
- export { detectPhoneCountry, formatPhone, normalizePhone } from "./phone.js";
7
+ export { detectPhoneCountry, formatPhone, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from "./phone.js";
8
8
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,23 @@
1
1
  "use strict";
2
2
 
3
+ /**
4
+ * The bare 'libphonenumber-js' entry point actually resolves to the library's
5
+ * OWN slimmed-down min/ metadata internally, not its full data - './max' is
6
+ * the variant with complete per-country metadata. Since the reason this
7
+ * module exists is validation and formatting accuracy, the more accurate
8
+ * variant wins throughout this file, not just for validation.
9
+ */
10
+ import { parsePhoneNumberFromString } from 'libphonenumber-js/max';
11
+ export { isValidPhoneNumber, parsePhoneNumber, parsePhoneNumberFromString } from 'libphonenumber-js/max';
12
+
13
+ /**
14
+ * Re-exported under our own name rather than importing CountryCode directly
15
+ * everywhere, so a future need to diverge (or re-narrow) has one place to do
16
+ * it. Every ISO 3166-1 alpha-2 code libphonenumber-js recognises - formatPhone
17
+ * and detectPhoneCountry below are genuinely correct for all of them, not a
18
+ * curated subset.
19
+ */
20
+
3
21
  /**
4
22
  * Strip everything except digits and a leading `+` (preserved if present).
5
23
  */
@@ -12,62 +30,11 @@ export const normalizePhone = input => {
12
30
  const digits = trimmed.replace(/\D/g, '');
13
31
  return hasPlus ? `+${digits}` : digits;
14
32
  };
15
- const groupIndianMobile = digits => {
16
- // Indian mobile is 10 digits: format as `XXXXX XXXXX`.
17
- if (digits.length !== 10) {
18
- return digits;
19
- }
20
- return `${digits.slice(0, 5)} ${digits.slice(5)}`;
21
- };
22
-
23
- // Longest calling code first so a 3-digit code is never shadowed by a shorter one.
24
- const COUNTRY_RULES = [{
25
- country: 'AE',
26
- callingCode: '971',
27
- nationalLength: 9,
28
- group: n => `${n.slice(0, 2)} ${n.slice(2, 5)} ${n.slice(5)}`
29
- }, {
30
- country: 'IN',
31
- callingCode: '91',
32
- nationalLength: 10,
33
- group: groupIndianMobile
34
- }, {
35
- country: 'GB',
36
- callingCode: '44',
37
- nationalLength: 10,
38
- group: n => `${n.slice(0, 4)} ${n.slice(4, 7)} ${n.slice(7)}`
39
- }, {
40
- country: 'AU',
41
- callingCode: '61',
42
- nationalLength: 9,
43
- group: n => `${n.slice(0, 3)} ${n.slice(3, 6)} ${n.slice(6)}`
44
- }, {
45
- country: 'SG',
46
- callingCode: '65',
47
- nationalLength: 8,
48
- group: n => `${n.slice(0, 4)} ${n.slice(4)}`
49
- }, {
50
- country: 'US',
51
- callingCode: '1',
52
- nationalLength: 10,
53
- group: n => `(${n.slice(0, 3)}) ${n.slice(3, 6)}-${n.slice(6)}`
54
- },
55
- // US and CA share a calling code and are indistinguishable from it alone;
56
- // this row only serves an explicit `country: 'CA'` override, never detection
57
- // (it sits after the US row, and findRuleByCallingCode returns the first match).
58
- {
59
- country: 'CA',
60
- callingCode: '1',
61
- nationalLength: 10,
62
- group: n => `(${n.slice(0, 3)}) ${n.slice(3, 6)}-${n.slice(6)}`
63
- }];
64
- const findRuleByCallingCode = rest => COUNTRY_RULES.find(rule => rest.startsWith(rule.callingCode));
65
- const findRuleByCountry = country => COUNTRY_RULES.find(rule => rule.country === country);
66
33
 
67
34
  /**
68
35
  * Detect the country of a phone number: from its own `+` country code when
69
36
  * present, otherwise from `defaultCountryCode`. Returns null when neither
70
- * carries a recognised calling code.
37
+ * parses to a recognised country.
71
38
  */
72
39
  export const detectPhoneCountry = (input, defaultCountryCode = '+91') => {
73
40
  const normalized = normalizePhone(input);
@@ -75,17 +42,18 @@ export const detectPhoneCountry = (input, defaultCountryCode = '+91') => {
75
42
  return null;
76
43
  }
77
44
  if (normalized.startsWith('+')) {
78
- return findRuleByCallingCode(normalized.slice(1))?.country ?? null;
45
+ return parsePhoneNumberFromString(normalized)?.country ?? null;
79
46
  }
80
47
  const normalizedDefault = normalizePhone(defaultCountryCode);
81
48
  if (!normalizedDefault.startsWith('+')) {
82
49
  return null;
83
50
  }
84
- return findRuleByCallingCode(normalizedDefault.slice(1))?.country ?? null;
51
+ return parsePhoneNumberFromString(normalizedDefault + normalized)?.country ?? null;
85
52
  };
86
53
  const bestEffortGroup = rest => {
87
- // No known country code matched (or matched but the wrong length): split
88
- // the country code (first 1-3 digits) and group the rest in 4s.
54
+ // Not a parseable number at all (garbage input, or a real number that's an
55
+ // unsupported length for its country): split the country code (first 1-3
56
+ // digits) and group the rest in 4s, rather than returning nothing.
89
57
  const ccLen = rest.length > 11 ? 3 : rest.length > 10 ? 2 : 1;
90
58
  const cc = rest.slice(0, ccLen);
91
59
  const number = rest.slice(ccLen);
@@ -94,13 +62,18 @@ const bestEffortGroup = rest => {
94
62
  };
95
63
 
96
64
  /**
97
- * Format a phone number for human display.
65
+ * Format a phone number for human display, via libphonenumber-js's own
66
+ * per-country formatting rather than a hand-rolled grouping table - correct
67
+ * for every country it recognises, not a curated subset.
98
68
  *
99
- * - Indian mobile (10 digits) `XXXXX XXXXX`
100
- * - With `+91` country code `+91 XXXXX XXXXX`
101
- * - A number that already carries a recognised country code is grouped for
102
- * that country regardless of `defaultCountryCode`.
103
- * - Other inputs are returned as `+CC NNNN NNNN…` best-effort grouping.
69
+ * - A number that already carries a `+` country code formats for that country.
70
+ * - A bare national number formats for `options.country` when given, else for
71
+ * the country implied by `defaultCountryCode` (default `+91`).
72
+ * - `includeCountryCode` controls international vs national format; defaults
73
+ * to international whenever the country was detected rather than passed in
74
+ * explicitly as `options.country`, and to national when it was.
75
+ * - Input libphonenumber-js can't parse into a valid number for the resolved
76
+ * country falls back to a best-effort `+CC NNNN NNNN…` digit grouping.
104
77
  */
105
78
 
106
79
  export function formatPhone(input, arg) {
@@ -113,35 +86,40 @@ export function formatPhone(input, arg) {
113
86
  }
114
87
  const options = typeof arg === 'string' ? {} : arg ?? {};
115
88
  const defaultCountryCode = typeof arg === 'string' ? arg : options.defaultCountryCode ?? '+91';
116
- if (normalized.startsWith('+')) {
117
- const rest = normalized.slice(1);
118
- const detectedRule = findRuleByCallingCode(rest);
119
- const activeRule = options.country ? findRuleByCountry(options.country) : detectedRule;
120
- if (activeRule) {
121
- const national = detectedRule ? rest.slice(detectedRule.callingCode.length) : rest;
122
- if (national.length === activeRule.nationalLength) {
123
- const includeCc = options.includeCountryCode ?? true;
124
- const body = activeRule.group(national);
125
- return includeCc ? `+${activeRule.callingCode} ${body}` : body;
126
- }
127
- }
128
- return bestEffortGroup(rest);
129
- }
89
+ const hasOwnCountryCode = normalized.startsWith('+');
90
+ let parsed;
91
+ // What to best-effort group if parsing fails to produce a valid number.
92
+ // Defaults to the plain input; the defaultCountryCode branch below points
93
+ // it at the combined digits instead, so a bare number that turns out
94
+ // invalid for its detected country still shows that country's code rather
95
+ // than silently discarding it.
96
+ let fallbackRest = normalized;
130
97
  if (options.country) {
131
- const rule = findRuleByCountry(options.country);
132
- if (rule && normalized.length === rule.nationalLength) {
133
- const includeCc = options.includeCountryCode ?? false;
134
- const body = rule.group(normalized);
135
- return includeCc ? `+${rule.callingCode} ${body}` : body;
98
+ // parsePhoneNumberFromString ignores this hint when normalized already
99
+ // carries its own +, so a real E.164 number is never overridden by a
100
+ // wrong or stale options.country.
101
+ parsed = parsePhoneNumberFromString(normalized, options.country);
102
+ } else if (hasOwnCountryCode) {
103
+ parsed = parsePhoneNumberFromString(normalized);
104
+ } else {
105
+ const normalizedDefault = normalizePhone(defaultCountryCode);
106
+ if (normalizedDefault.startsWith('+')) {
107
+ const combined = normalizedDefault + normalized;
108
+ parsed = parsePhoneNumberFromString(combined);
109
+ fallbackRest = combined;
110
+ } else {
111
+ parsed = undefined;
136
112
  }
137
- return normalized.replace(/(.{4})(?=.)/g, '$1 ').trim();
138
113
  }
139
114
 
140
- // No country code; assume default if length matches Indian mobile.
141
- if (normalized.length === 10) {
142
- return `${defaultCountryCode} ${groupIndianMobile(normalized)}`;
115
+ // International by default whenever the country came from the number
116
+ // itself (or from defaultCountryCode); national by default only when a
117
+ // bare number relied on an explicit options.country to resolve at all.
118
+ const includeCcDefault = hasOwnCountryCode || !options.country;
119
+ if (parsed?.isValid()) {
120
+ const includeCc = options.includeCountryCode ?? includeCcDefault;
121
+ return includeCc ? parsed.formatInternational() : parsed.formatNational();
143
122
  }
144
- // Otherwise just return groups of 4.
145
- return normalized.replace(/(.{4})(?=.)/g, '$1 ').trim();
123
+ return fallbackRest.startsWith('+') ? bestEffortGroup(fallbackRest.slice(1)) : fallbackRest.replace(/(.{4})(?=.)/g, '$1 ').trim();
146
124
  }
147
125
  //# sourceMappingURL=phone.js.map
@@ -29,7 +29,7 @@ export { getConfig, getConfigValue, resetConfig, setConfig } from "./config/inde
29
29
  // Deep links
30
30
  export { DeepLink, parseDeepLink, useDeepLink } from "./deepLink/index.js";
31
31
  // Formatters
32
- export { detectPhoneCountry, formatCompactNumber, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, getInitials, normalizePhone } from "./formatters/index.js";
32
+ export { detectPhoneCountry, formatCompactNumber, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, getInitials, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from "./formatters/index.js";
33
33
  // Initialization
34
34
  export { initWebority } from "./initSDK.js";
35
35
  export { initUserAuth } from "./initUserAuth.js";
@@ -190,7 +190,7 @@ const getAllKeys = async () => {
190
190
  * All operations swallow errors (logging them) and return a falsy result
191
191
  * so that storage problems never crash the app.
192
192
  *
193
- * Backed by `@react-native-async-storage/async-storage` by default;
193
+ * Backed by `expo-sqlite/kv-store` by default;
194
194
  * override with `setStorageImplementation()` for MMKV or custom adapters.
195
195
  */
196
196
  export const Storage = {
@@ -4,6 +4,6 @@ export type { DateInput, DateStyle, TimeStyle } from './date';
4
4
  export { formatDate, formatDateTime, formatRelativeTime, formatTime } from './date';
5
5
  export { getInitials } from './initials';
6
6
  export { formatCompactNumber, formatNumber, formatPercent } from './number';
7
- export type { FormatPhoneOptions, PhoneCountry } from './phone';
8
- export { detectPhoneCountry, formatPhone, normalizePhone } from './phone';
7
+ export type { FormatPhoneOptions, PhoneCountry, PhoneNumber } from './phone';
8
+ export { detectPhoneCountry, formatPhone, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from './phone';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,21 @@
1
- export type PhoneCountry = 'IN' | 'US' | 'GB' | 'AE' | 'AU' | 'SG' | 'CA';
1
+ /**
2
+ * The bare 'libphonenumber-js' entry point actually resolves to the library's
3
+ * OWN slimmed-down min/ metadata internally, not its full data - './max' is
4
+ * the variant with complete per-country metadata. Since the reason this
5
+ * module exists is validation and formatting accuracy, the more accurate
6
+ * variant wins throughout this file, not just for validation.
7
+ */
8
+ import { type CountryCode } from 'libphonenumber-js/max';
9
+ export type { PhoneNumber } from 'libphonenumber-js/max';
10
+ export { isValidPhoneNumber, parsePhoneNumber, parsePhoneNumberFromString } from 'libphonenumber-js/max';
11
+ /**
12
+ * Re-exported under our own name rather than importing CountryCode directly
13
+ * everywhere, so a future need to diverge (or re-narrow) has one place to do
14
+ * it. Every ISO 3166-1 alpha-2 code libphonenumber-js recognises - formatPhone
15
+ * and detectPhoneCountry below are genuinely correct for all of them, not a
16
+ * curated subset.
17
+ */
18
+ export type PhoneCountry = CountryCode;
2
19
  export interface FormatPhoneOptions {
3
20
  defaultCountryCode?: string;
4
21
  country?: PhoneCountry;
@@ -11,17 +28,22 @@ export declare const normalizePhone: (input: string) => string;
11
28
  /**
12
29
  * Detect the country of a phone number: from its own `+` country code when
13
30
  * present, otherwise from `defaultCountryCode`. Returns null when neither
14
- * carries a recognised calling code.
31
+ * parses to a recognised country.
15
32
  */
16
33
  export declare const detectPhoneCountry: (input: string, defaultCountryCode?: string) => PhoneCountry | null;
17
34
  /**
18
- * Format a phone number for human display.
35
+ * Format a phone number for human display, via libphonenumber-js's own
36
+ * per-country formatting rather than a hand-rolled grouping table - correct
37
+ * for every country it recognises, not a curated subset.
19
38
  *
20
- * - Indian mobile (10 digits) `XXXXX XXXXX`
21
- * - With `+91` country code `+91 XXXXX XXXXX`
22
- * - A number that already carries a recognised country code is grouped for
23
- * that country regardless of `defaultCountryCode`.
24
- * - Other inputs are returned as `+CC NNNN NNNN…` best-effort grouping.
39
+ * - A number that already carries a `+` country code formats for that country.
40
+ * - A bare national number formats for `options.country` when given, else for
41
+ * the country implied by `defaultCountryCode` (default `+91`).
42
+ * - `includeCountryCode` controls international vs national format; defaults
43
+ * to international whenever the country was detected rather than passed in
44
+ * explicitly as `options.country`, and to national when it was.
45
+ * - Input libphonenumber-js can't parse into a valid number for the resolved
46
+ * country falls back to a best-effort `+CC NNNN NNNN…` digit grouping.
25
47
  */
26
48
  export declare function formatPhone(input: string, defaultCountryCode?: string): string;
27
49
  export declare function formatPhone(input: string, options?: FormatPhoneOptions): string;
@@ -28,8 +28,8 @@ export type { Config, Environment, LogLevel } from './config';
28
28
  export { getConfig, getConfigValue, resetConfig, setConfig } from './config';
29
29
  export type { DeepLinkConfig, DeepLinkRoute, ParsedLink } from './deepLink';
30
30
  export { DeepLink, parseDeepLink, useDeepLink } from './deepLink';
31
- export type { DateInput, DateStyle, FormatCurrencyOptions, FormatPhoneOptions, PhoneCountry, TimeStyle } from './formatters';
32
- export { detectPhoneCountry, formatCompactNumber, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, getInitials, normalizePhone } from './formatters';
31
+ export type { DateInput, DateStyle, FormatCurrencyOptions, FormatPhoneOptions, PhoneCountry, PhoneNumber, TimeStyle } from './formatters';
32
+ export { detectPhoneCountry, formatCompactNumber, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, getInitials, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from './formatters';
33
33
  export type { InitConfig } from './initSDK';
34
34
  export { initWebority } from './initSDK';
35
35
  export type { AuthActions } from './initUserAuth';
@@ -56,7 +56,7 @@ export interface StorageApi {
56
56
  * All operations swallow errors (logging them) and return a falsy result
57
57
  * so that storage problems never crash the app.
58
58
  *
59
- * Backed by `@react-native-async-storage/async-storage` by default;
59
+ * Backed by `expo-sqlite/kv-store` by default;
60
60
  * override with `setStorageImplementation()` for MMKV or custom adapters.
61
61
  */
62
62
  export declare const Storage: StorageApi;
@@ -4,6 +4,6 @@ export type { DateInput, DateStyle, TimeStyle } from './date.js';
4
4
  export { formatDate, formatDateTime, formatRelativeTime, formatTime } from './date.js';
5
5
  export { getInitials } from './initials.js';
6
6
  export { formatCompactNumber, formatNumber, formatPercent } from './number.js';
7
- export type { FormatPhoneOptions, PhoneCountry } from './phone.js';
8
- export { detectPhoneCountry, formatPhone, normalizePhone } from './phone.js';
7
+ export type { FormatPhoneOptions, PhoneCountry, PhoneNumber } from './phone.js';
8
+ export { detectPhoneCountry, formatPhone, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from './phone.js';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1,4 +1,21 @@
1
- export type PhoneCountry = 'IN' | 'US' | 'GB' | 'AE' | 'AU' | 'SG' | 'CA';
1
+ /**
2
+ * The bare 'libphonenumber-js' entry point actually resolves to the library's
3
+ * OWN slimmed-down min/ metadata internally, not its full data - './max' is
4
+ * the variant with complete per-country metadata. Since the reason this
5
+ * module exists is validation and formatting accuracy, the more accurate
6
+ * variant wins throughout this file, not just for validation.
7
+ */
8
+ import { type CountryCode } from 'libphonenumber-js/max';
9
+ export type { PhoneNumber } from 'libphonenumber-js/max';
10
+ export { isValidPhoneNumber, parsePhoneNumber, parsePhoneNumberFromString } from 'libphonenumber-js/max';
11
+ /**
12
+ * Re-exported under our own name rather than importing CountryCode directly
13
+ * everywhere, so a future need to diverge (or re-narrow) has one place to do
14
+ * it. Every ISO 3166-1 alpha-2 code libphonenumber-js recognises - formatPhone
15
+ * and detectPhoneCountry below are genuinely correct for all of them, not a
16
+ * curated subset.
17
+ */
18
+ export type PhoneCountry = CountryCode;
2
19
  export interface FormatPhoneOptions {
3
20
  defaultCountryCode?: string;
4
21
  country?: PhoneCountry;
@@ -11,17 +28,22 @@ export declare const normalizePhone: (input: string) => string;
11
28
  /**
12
29
  * Detect the country of a phone number: from its own `+` country code when
13
30
  * present, otherwise from `defaultCountryCode`. Returns null when neither
14
- * carries a recognised calling code.
31
+ * parses to a recognised country.
15
32
  */
16
33
  export declare const detectPhoneCountry: (input: string, defaultCountryCode?: string) => PhoneCountry | null;
17
34
  /**
18
- * Format a phone number for human display.
35
+ * Format a phone number for human display, via libphonenumber-js's own
36
+ * per-country formatting rather than a hand-rolled grouping table - correct
37
+ * for every country it recognises, not a curated subset.
19
38
  *
20
- * - Indian mobile (10 digits) `XXXXX XXXXX`
21
- * - With `+91` country code `+91 XXXXX XXXXX`
22
- * - A number that already carries a recognised country code is grouped for
23
- * that country regardless of `defaultCountryCode`.
24
- * - Other inputs are returned as `+CC NNNN NNNN…` best-effort grouping.
39
+ * - A number that already carries a `+` country code formats for that country.
40
+ * - A bare national number formats for `options.country` when given, else for
41
+ * the country implied by `defaultCountryCode` (default `+91`).
42
+ * - `includeCountryCode` controls international vs national format; defaults
43
+ * to international whenever the country was detected rather than passed in
44
+ * explicitly as `options.country`, and to national when it was.
45
+ * - Input libphonenumber-js can't parse into a valid number for the resolved
46
+ * country falls back to a best-effort `+CC NNNN NNNN…` digit grouping.
25
47
  */
26
48
  export declare function formatPhone(input: string, defaultCountryCode?: string): string;
27
49
  export declare function formatPhone(input: string, options?: FormatPhoneOptions): string;
@@ -28,8 +28,8 @@ export type { Config, Environment, LogLevel } from './config/index.js';
28
28
  export { getConfig, getConfigValue, resetConfig, setConfig } from './config/index.js';
29
29
  export type { DeepLinkConfig, DeepLinkRoute, ParsedLink } from './deepLink/index.js';
30
30
  export { DeepLink, parseDeepLink, useDeepLink } from './deepLink/index.js';
31
- export type { DateInput, DateStyle, FormatCurrencyOptions, FormatPhoneOptions, PhoneCountry, TimeStyle } from './formatters/index.js';
32
- export { detectPhoneCountry, formatCompactNumber, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, getInitials, normalizePhone } from './formatters/index.js';
31
+ export type { DateInput, DateStyle, FormatCurrencyOptions, FormatPhoneOptions, PhoneCountry, PhoneNumber, TimeStyle } from './formatters/index.js';
32
+ export { detectPhoneCountry, formatCompactNumber, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatPhone, formatRelativeTime, formatTime, getInitials, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from './formatters/index.js';
33
33
  export type { InitConfig } from './initSDK.js';
34
34
  export { initWebority } from './initSDK.js';
35
35
  export type { AuthActions } from './initUserAuth.js';
@@ -56,7 +56,7 @@ export interface StorageApi {
56
56
  * All operations swallow errors (logging them) and return a falsy result
57
57
  * so that storage problems never crash the app.
58
58
  *
59
- * Backed by `@react-native-async-storage/async-storage` by default;
59
+ * Backed by `expo-sqlite/kv-store` by default;
60
60
  * override with `setStorageImplementation()` for MMKV or custom adapters.
61
61
  */
62
62
  export declare const Storage: StorageApi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority-technologies/mobile-core",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Platform layer for Webority React Native apps: HTTP clients, auth/token storage, config, logging, formatters, validators, network status, permissions, storage and version checks. No UI.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -133,7 +133,8 @@
133
133
  "typecheck": "tsc --noEmit"
134
134
  },
135
135
  "dependencies": {
136
- "axios": "^1.19.0"
136
+ "axios": "^1.19.0",
137
+ "libphonenumber-js": "^1.12.41"
137
138
  },
138
139
  "peerDependencies": {
139
140
  "@op-engineering/op-sqlite": "*",