expensify-common 2.0.208 → 2.0.211
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/dist/ExpensiMark.js +11 -6
- package/dist/esm/ExpensiMark.js +11 -6
- package/dist/esm/str.d.ts +40 -20
- package/dist/esm/str.js +163 -140
- package/dist/str.d.ts +40 -20
- package/dist/str.js +163 -140
- package/package.json +1 -1
package/dist/esm/str.js
CHANGED
|
@@ -15,6 +15,126 @@ function resultFn(parameter, ...args) {
|
|
|
15
15
|
}
|
|
16
16
|
return parameter;
|
|
17
17
|
}
|
|
18
|
+
// Str methods that other Str methods call are plain module-level functions instead of being reached through
|
|
19
|
+
// `this`: react-native-worklets 0.13 no longer keeps an object literal together on a Worklet Runtime, so `this`
|
|
20
|
+
// inside a workletized method does not point to Str there.
|
|
21
|
+
function compare(strA, strB) {
|
|
22
|
+
if (strA < strB) {
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
if (strA > strB) {
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
function caseInsensitiveCompare(strA, strB) {
|
|
31
|
+
const lowerCaseStrA = strA.toLocaleLowerCase();
|
|
32
|
+
const lowerCaseStrB = strB.toLocaleLowerCase();
|
|
33
|
+
return compare(lowerCaseStrA, lowerCaseStrB);
|
|
34
|
+
}
|
|
35
|
+
function contains(haystack, needle) {
|
|
36
|
+
return haystack.indexOf(needle) !== -1;
|
|
37
|
+
}
|
|
38
|
+
function cutAfter(str, substr) {
|
|
39
|
+
const index = str.indexOf(substr);
|
|
40
|
+
if (index !== -1) {
|
|
41
|
+
return str.substring(0, index);
|
|
42
|
+
}
|
|
43
|
+
return str;
|
|
44
|
+
}
|
|
45
|
+
function cutBefore(str, substr) {
|
|
46
|
+
const index = str.indexOf(substr);
|
|
47
|
+
if (index !== -1) {
|
|
48
|
+
return str.substring(index + substr.length);
|
|
49
|
+
}
|
|
50
|
+
return str;
|
|
51
|
+
}
|
|
52
|
+
function extractEmailDomain(email) {
|
|
53
|
+
return cutBefore(email, '@');
|
|
54
|
+
}
|
|
55
|
+
function getExtension(url) {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
if (typeof url !== 'string') {
|
|
58
|
+
Log.warn('Str.getExtension: url is not a string', { url });
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return (_b = (_a = url.split('.').pop()) === null || _a === void 0 ? void 0 : _a.split('?')[0]) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
|
62
|
+
}
|
|
63
|
+
function getRawByteSize(inputChar) {
|
|
64
|
+
const onlyChar = String(inputChar);
|
|
65
|
+
const c = onlyChar.charCodeAt(0);
|
|
66
|
+
// If we are grabbing the byte size, we need to temporarily diable no-bitwise for linting
|
|
67
|
+
/* eslint-disable no-bitwise */
|
|
68
|
+
if (c < 1 << 7) {
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
if (c < 1 << 11) {
|
|
72
|
+
return 2;
|
|
73
|
+
}
|
|
74
|
+
if (c < 1 << 16) {
|
|
75
|
+
return 3;
|
|
76
|
+
}
|
|
77
|
+
if (c < 1 << 21) {
|
|
78
|
+
return 4;
|
|
79
|
+
}
|
|
80
|
+
if (c < 1 << 26) {
|
|
81
|
+
return 5;
|
|
82
|
+
}
|
|
83
|
+
if (c < 1 << 31) {
|
|
84
|
+
return 6;
|
|
85
|
+
}
|
|
86
|
+
/* eslint-enable no-bitwise */
|
|
87
|
+
return Number.NaN;
|
|
88
|
+
}
|
|
89
|
+
function htmlDecode(s) {
|
|
90
|
+
return HtmlEntities.decode(s);
|
|
91
|
+
}
|
|
92
|
+
function htmlEncode(s) {
|
|
93
|
+
return HtmlEntities.encode(s);
|
|
94
|
+
}
|
|
95
|
+
function isTypeOf(obj, type) {
|
|
96
|
+
return Object.prototype.toString.call(obj) === `[object ${type}]`;
|
|
97
|
+
}
|
|
98
|
+
function isNumber(obj) {
|
|
99
|
+
return isTypeOf(obj, 'Number');
|
|
100
|
+
}
|
|
101
|
+
function isString(obj) {
|
|
102
|
+
return isTypeOf(obj, 'String');
|
|
103
|
+
}
|
|
104
|
+
function isUndefined(obj) {
|
|
105
|
+
// eslint-disable-next-line no-void
|
|
106
|
+
return obj === void 0;
|
|
107
|
+
}
|
|
108
|
+
function isValidE164Phone(phone) {
|
|
109
|
+
return Constants.CONST.SMS.E164_REGEX.test(phone);
|
|
110
|
+
}
|
|
111
|
+
function isValidEmail(str) {
|
|
112
|
+
if (!str || typeof str !== 'string') {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
const unicodeVersion = Punycode.toUnicode(str);
|
|
116
|
+
if (String(unicodeVersion).match(Constants.CONST.REG_EXP.EMOJI_RULE)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return !!String(str).match(Constants.CONST.REG_EXP.EMAIL);
|
|
120
|
+
}
|
|
121
|
+
function maskFirstNCharacters(str, num, mask) {
|
|
122
|
+
// if str is empty, str or mask aren't strings,
|
|
123
|
+
// or n is not a number, do nothing
|
|
124
|
+
if (!isString(str) || !isString(mask) || str.length === 0 || !isNumber(num)) {
|
|
125
|
+
return str;
|
|
126
|
+
}
|
|
127
|
+
return str.substring(0, num).replaceAll(/./g, mask) + str.substring(num);
|
|
128
|
+
}
|
|
129
|
+
function removeSMSDomain(text) {
|
|
130
|
+
return text.replaceAll(REMOVE_SMS_DOMAIN_PATTERN, '');
|
|
131
|
+
}
|
|
132
|
+
function removeTrailingComma(str) {
|
|
133
|
+
return str.trim().replaceAll(/(,$)/g, '');
|
|
134
|
+
}
|
|
135
|
+
function startsWith(haystack, needle) {
|
|
136
|
+
return isString(haystack) && isString(needle) && haystack.substring(0, needle.length) === needle;
|
|
137
|
+
}
|
|
18
138
|
const Str = {
|
|
19
139
|
/**
|
|
20
140
|
* Return true if the string is ending with the provided suffix
|
|
@@ -72,18 +192,14 @@ const Str = {
|
|
|
72
192
|
* @param s The string to decode.
|
|
73
193
|
* @returns The decoded string.
|
|
74
194
|
*/
|
|
75
|
-
htmlDecode
|
|
76
|
-
return HtmlEntities.decode(s);
|
|
77
|
-
},
|
|
195
|
+
htmlDecode,
|
|
78
196
|
/**
|
|
79
197
|
* HTML encodes the given string.
|
|
80
198
|
*
|
|
81
199
|
* @param s The string to encode.
|
|
82
200
|
* @return string @p s HTML encoded.
|
|
83
201
|
*/
|
|
84
|
-
htmlEncode
|
|
85
|
-
return HtmlEntities.encode(s);
|
|
86
|
-
},
|
|
202
|
+
htmlEncode,
|
|
87
203
|
/**
|
|
88
204
|
* Decodes the given HTML encoded string.
|
|
89
205
|
*
|
|
@@ -127,7 +243,7 @@ const Str = {
|
|
|
127
243
|
* @returns True when first === second, ignoring HTML encoding
|
|
128
244
|
*/
|
|
129
245
|
htmlEncodingInsensitiveEquals(first, second) {
|
|
130
|
-
return first === second ||
|
|
246
|
+
return first === second || htmlDecode(first) === second || htmlEncode(first) === second;
|
|
131
247
|
},
|
|
132
248
|
/**
|
|
133
249
|
* Creates an ID that can be used as an HTML attribute from @p str.
|
|
@@ -213,32 +329,7 @@ const Str = {
|
|
|
213
329
|
* one.
|
|
214
330
|
* @returns Byte size of the character
|
|
215
331
|
*/
|
|
216
|
-
getRawByteSize
|
|
217
|
-
const onlyChar = String(inputChar);
|
|
218
|
-
const c = onlyChar.charCodeAt(0);
|
|
219
|
-
// If we are grabbing the byte size, we need to temporarily diable no-bitwise for linting
|
|
220
|
-
/* eslint-disable no-bitwise */
|
|
221
|
-
if (c < 1 << 7) {
|
|
222
|
-
return 1;
|
|
223
|
-
}
|
|
224
|
-
if (c < 1 << 11) {
|
|
225
|
-
return 2;
|
|
226
|
-
}
|
|
227
|
-
if (c < 1 << 16) {
|
|
228
|
-
return 3;
|
|
229
|
-
}
|
|
230
|
-
if (c < 1 << 21) {
|
|
231
|
-
return 4;
|
|
232
|
-
}
|
|
233
|
-
if (c < 1 << 26) {
|
|
234
|
-
return 5;
|
|
235
|
-
}
|
|
236
|
-
if (c < 1 << 31) {
|
|
237
|
-
return 6;
|
|
238
|
-
}
|
|
239
|
-
/* eslint-enable no-bitwise */
|
|
240
|
-
return Number.NaN;
|
|
241
|
-
},
|
|
332
|
+
getRawByteSize,
|
|
242
333
|
/**
|
|
243
334
|
* Gets the length of a string in bytes, including non-ASCII characters
|
|
244
335
|
* @returns The number of bytes used by string
|
|
@@ -246,7 +337,7 @@ const Str = {
|
|
|
246
337
|
getByteLength(input) {
|
|
247
338
|
// Force string type
|
|
248
339
|
const stringInput = String(input);
|
|
249
|
-
const byteLength = Array.from(stringInput).reduce((acc, char) => acc +
|
|
340
|
+
const byteLength = Array.from(stringInput).reduce((acc, char) => acc + getRawByteSize(char), 0);
|
|
250
341
|
return byteLength;
|
|
251
342
|
},
|
|
252
343
|
/**
|
|
@@ -258,7 +349,7 @@ const Str = {
|
|
|
258
349
|
const stringInput = String(input);
|
|
259
350
|
let totalByteLength = 0;
|
|
260
351
|
for (let i = 0; i < stringInput.length; i++) {
|
|
261
|
-
const charByteSize =
|
|
352
|
+
const charByteSize = getRawByteSize(stringInput[i]);
|
|
262
353
|
if (charByteSize + totalByteLength > maxSize) {
|
|
263
354
|
// If the next character exceeds the limit, stop and return the truncated string.
|
|
264
355
|
return `${stringInput.substr(0, i - 3)}...`;
|
|
@@ -274,9 +365,7 @@ const Str = {
|
|
|
274
365
|
* @param needle The case-sensitive string to search for
|
|
275
366
|
* @returns True if the haystack starts with the needle.
|
|
276
367
|
*/
|
|
277
|
-
startsWith
|
|
278
|
-
return this.isString(haystack) && this.isString(needle) && haystack.substring(0, needle.length) === needle;
|
|
279
|
-
},
|
|
368
|
+
startsWith,
|
|
280
369
|
/**
|
|
281
370
|
* Gets the textual value of the given string.
|
|
282
371
|
*
|
|
@@ -284,7 +373,7 @@ const Str = {
|
|
|
284
373
|
* @returns The text from within the HTML string.
|
|
285
374
|
*/
|
|
286
375
|
stripHTML(str) {
|
|
287
|
-
if (!
|
|
376
|
+
if (!isString(str)) {
|
|
288
377
|
return '';
|
|
289
378
|
}
|
|
290
379
|
return str.replaceAll(/<[^>]*>?/gm, '');
|
|
@@ -307,13 +396,7 @@ const Str = {
|
|
|
307
396
|
* @param substr The substring to search for.
|
|
308
397
|
* @returns The cut/trimmed string.
|
|
309
398
|
*/
|
|
310
|
-
cutAfter
|
|
311
|
-
const index = str.indexOf(substr);
|
|
312
|
-
if (index !== -1) {
|
|
313
|
-
return str.substring(0, index);
|
|
314
|
-
}
|
|
315
|
-
return str;
|
|
316
|
-
},
|
|
399
|
+
cutAfter,
|
|
317
400
|
/**
|
|
318
401
|
* Returns a string containing all the characters str from after the first
|
|
319
402
|
* occurrence of substr to the end of the string.
|
|
@@ -323,13 +406,7 @@ const Str = {
|
|
|
323
406
|
* @param substr The substring to search for.
|
|
324
407
|
* @returns The cut/trimmed string.
|
|
325
408
|
*/
|
|
326
|
-
cutBefore
|
|
327
|
-
const index = str.indexOf(substr);
|
|
328
|
-
if (index !== -1) {
|
|
329
|
-
return str.substring(index + substr.length);
|
|
330
|
-
}
|
|
331
|
-
return str;
|
|
332
|
-
},
|
|
409
|
+
cutBefore,
|
|
333
410
|
/**
|
|
334
411
|
* Checks that the string is a domain name (e.g. example.com)
|
|
335
412
|
*
|
|
@@ -356,16 +433,7 @@ const Str = {
|
|
|
356
433
|
*
|
|
357
434
|
* @returns True if the string is an email
|
|
358
435
|
*/
|
|
359
|
-
isValidEmail
|
|
360
|
-
if (!str || typeof str !== 'string') {
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
const unicodeVersion = Punycode.toUnicode(str);
|
|
364
|
-
if (String(unicodeVersion).match(Constants.CONST.REG_EXP.EMOJI_RULE)) {
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
367
|
-
return !!String(str).match(Constants.CONST.REG_EXP.EMAIL);
|
|
368
|
-
},
|
|
436
|
+
isValidEmail,
|
|
369
437
|
/**
|
|
370
438
|
* Checks if the string is an valid email address formed during comment markdown formation.
|
|
371
439
|
*
|
|
@@ -383,9 +451,7 @@ const Str = {
|
|
|
383
451
|
*
|
|
384
452
|
* @returns string with the trailing comma removed
|
|
385
453
|
*/
|
|
386
|
-
removeTrailingComma
|
|
387
|
-
return str.trim().replaceAll(/(,$)/g, '');
|
|
388
|
-
},
|
|
454
|
+
removeTrailingComma,
|
|
389
455
|
/**
|
|
390
456
|
* Checks that the string is a list of coma separated email addresss.
|
|
391
457
|
*
|
|
@@ -394,12 +460,12 @@ const Str = {
|
|
|
394
460
|
* @returns True if all emails are valid or if input is empty
|
|
395
461
|
*/
|
|
396
462
|
areValidEmails(str) {
|
|
397
|
-
const string =
|
|
463
|
+
const string = removeTrailingComma(str);
|
|
398
464
|
if (string === '') {
|
|
399
465
|
return true;
|
|
400
466
|
}
|
|
401
467
|
const emails = string.split(',');
|
|
402
|
-
const result = emails.every((email) =>
|
|
468
|
+
const result = emails.every((email) => isValidEmail(email.trim()));
|
|
403
469
|
return result;
|
|
404
470
|
},
|
|
405
471
|
/**
|
|
@@ -416,9 +482,7 @@ const Str = {
|
|
|
416
482
|
*
|
|
417
483
|
* @returns The domain name in the email address.
|
|
418
484
|
*/
|
|
419
|
-
extractEmailDomain
|
|
420
|
-
return this.cutBefore(email, '@');
|
|
421
|
-
},
|
|
485
|
+
extractEmailDomain,
|
|
422
486
|
/**
|
|
423
487
|
* Tries to extract the company name from the given email address
|
|
424
488
|
* (e.g. "yelp" for "joe@yelp.co.uk").
|
|
@@ -428,7 +492,7 @@ const Str = {
|
|
|
428
492
|
* @returns The company name in the email address or null.
|
|
429
493
|
*/
|
|
430
494
|
extractCompanyNameFromEmailDomain(email) {
|
|
431
|
-
const domain =
|
|
495
|
+
const domain = extractEmailDomain(email);
|
|
432
496
|
if (!domain) {
|
|
433
497
|
return null;
|
|
434
498
|
}
|
|
@@ -447,7 +511,7 @@ const Str = {
|
|
|
447
511
|
* @returns The local part in the email address.
|
|
448
512
|
*/
|
|
449
513
|
extractEmailLocalPart(email) {
|
|
450
|
-
return
|
|
514
|
+
return cutAfter(email, '@');
|
|
451
515
|
},
|
|
452
516
|
/**
|
|
453
517
|
* Sanitize phone number to return only numbers. Return null if non valid phone number.
|
|
@@ -505,13 +569,13 @@ const Str = {
|
|
|
505
569
|
* @returns true if the length is in the range, false otherwise
|
|
506
570
|
*/
|
|
507
571
|
isOfLength(str, minimumLength, maximumLength) {
|
|
508
|
-
if (!
|
|
572
|
+
if (!isString(str)) {
|
|
509
573
|
return false;
|
|
510
574
|
}
|
|
511
575
|
if (str.length < minimumLength) {
|
|
512
576
|
return false;
|
|
513
577
|
}
|
|
514
|
-
if (!
|
|
578
|
+
if (!isUndefined(maximumLength) && str.length > maximumLength) {
|
|
515
579
|
return false;
|
|
516
580
|
}
|
|
517
581
|
return true;
|
|
@@ -565,9 +629,7 @@ const Str = {
|
|
|
565
629
|
*
|
|
566
630
|
* @returns Returns true if the haystack contains the needle
|
|
567
631
|
*/
|
|
568
|
-
contains
|
|
569
|
-
return haystack.indexOf(needle) !== -1;
|
|
570
|
-
},
|
|
632
|
+
contains,
|
|
571
633
|
/**
|
|
572
634
|
* Returns true if the haystack contains the needle, ignoring case
|
|
573
635
|
*
|
|
@@ -577,7 +639,7 @@ const Str = {
|
|
|
577
639
|
* @returns Returns true if the haystack contains the needle, ignoring case
|
|
578
640
|
*/
|
|
579
641
|
caseInsensitiveContains(haystack, needle) {
|
|
580
|
-
return
|
|
642
|
+
return contains(haystack.toLowerCase(), needle.toLowerCase());
|
|
581
643
|
},
|
|
582
644
|
/**
|
|
583
645
|
* Case insensitive compare function
|
|
@@ -589,11 +651,7 @@ const Str = {
|
|
|
589
651
|
* 1 if first string > second string
|
|
590
652
|
* 0 if first string = second string
|
|
591
653
|
*/
|
|
592
|
-
caseInsensitiveCompare
|
|
593
|
-
const lowerCaseStrA = strA.toLocaleLowerCase();
|
|
594
|
-
const lowerCaseStrB = strB.toLocaleLowerCase();
|
|
595
|
-
return this.compare(lowerCaseStrA, lowerCaseStrB);
|
|
596
|
-
},
|
|
654
|
+
caseInsensitiveCompare,
|
|
597
655
|
/**
|
|
598
656
|
* Case insensitive equals
|
|
599
657
|
*
|
|
@@ -602,7 +660,7 @@ const Str = {
|
|
|
602
660
|
* @returns true when first == second except for case
|
|
603
661
|
*/
|
|
604
662
|
caseInsensitiveEquals(strA, strB) {
|
|
605
|
-
return
|
|
663
|
+
return caseInsensitiveCompare(strA, strB) === 0;
|
|
606
664
|
},
|
|
607
665
|
/**
|
|
608
666
|
* Compare function
|
|
@@ -614,15 +672,7 @@ const Str = {
|
|
|
614
672
|
* 1 if first string > second string
|
|
615
673
|
* 0 if first string = second string
|
|
616
674
|
*/
|
|
617
|
-
compare
|
|
618
|
-
if (strA < strB) {
|
|
619
|
-
return -1;
|
|
620
|
-
}
|
|
621
|
-
if (strA > strB) {
|
|
622
|
-
return 1;
|
|
623
|
-
}
|
|
624
|
-
return 0;
|
|
625
|
-
},
|
|
675
|
+
compare,
|
|
626
676
|
/**
|
|
627
677
|
* Check if a file extension is supported by SmartReports
|
|
628
678
|
*/
|
|
@@ -646,48 +696,39 @@ const Str = {
|
|
|
646
696
|
// Hide these numbers completely
|
|
647
697
|
// We should not be getting account numbers this small or large
|
|
648
698
|
if (len < 6 || len > 20) {
|
|
649
|
-
return
|
|
699
|
+
return maskFirstNCharacters(accountNumber, len, 'X');
|
|
650
700
|
}
|
|
651
701
|
// Can show last 4
|
|
652
702
|
if (len < 14) {
|
|
653
|
-
return
|
|
703
|
+
return maskFirstNCharacters(accountNumber, len - 4, 'X');
|
|
654
704
|
}
|
|
655
705
|
// Can show first 6 and last 4
|
|
656
706
|
const first = accountNumber.substr(0, 6);
|
|
657
707
|
const last = accountNumber.substr(7);
|
|
658
|
-
const masked =
|
|
708
|
+
const masked = maskFirstNCharacters(last, len - 11, 'X');
|
|
659
709
|
return `${first}${masked}`;
|
|
660
710
|
},
|
|
661
711
|
/**
|
|
662
712
|
* Checks if something is a string
|
|
663
713
|
* Stolen from underscore
|
|
664
714
|
*/
|
|
665
|
-
isString
|
|
666
|
-
return this.isTypeOf(obj, 'String');
|
|
667
|
-
},
|
|
715
|
+
isString,
|
|
668
716
|
/**
|
|
669
717
|
* Checks if something is a number
|
|
670
718
|
* Stolen from underscore
|
|
671
719
|
* @param obj
|
|
672
720
|
*/
|
|
673
|
-
isNumber
|
|
674
|
-
return this.isTypeOf(obj, 'Number');
|
|
675
|
-
},
|
|
721
|
+
isNumber,
|
|
676
722
|
/**
|
|
677
723
|
* Checks if something is a certain type
|
|
678
724
|
* Stolen from underscore
|
|
679
725
|
*/
|
|
680
|
-
isTypeOf
|
|
681
|
-
return Object.prototype.toString.call(obj) === `[object ${type}]`;
|
|
682
|
-
},
|
|
726
|
+
isTypeOf,
|
|
683
727
|
/**
|
|
684
728
|
* Checks to see if something is undefined
|
|
685
729
|
* Stolen from underscore
|
|
686
730
|
*/
|
|
687
|
-
isUndefined
|
|
688
|
-
// eslint-disable-next-line no-void
|
|
689
|
-
return obj === void 0;
|
|
690
|
-
},
|
|
731
|
+
isUndefined,
|
|
691
732
|
/**
|
|
692
733
|
* Replace first N characters of the string with maskChar
|
|
693
734
|
* eg: maskFirstNCharacters( '1234567890', 6, 'X' ) yields XXXXXX7890
|
|
@@ -696,14 +737,7 @@ const Str = {
|
|
|
696
737
|
* @param mask String we want replace the first N chars with
|
|
697
738
|
* @returns Masked string
|
|
698
739
|
*/
|
|
699
|
-
maskFirstNCharacters
|
|
700
|
-
// if str is empty, str or mask aren't strings,
|
|
701
|
-
// or n is not a number, do nothing
|
|
702
|
-
if (!this.isString(str) || !this.isString(mask) || str.length === 0 || !this.isNumber(num)) {
|
|
703
|
-
return str;
|
|
704
|
-
}
|
|
705
|
-
return str.substring(0, num).replaceAll(/./g, mask) + str.substring(num);
|
|
706
|
-
},
|
|
740
|
+
maskFirstNCharacters,
|
|
707
741
|
/**
|
|
708
742
|
* Trim a string
|
|
709
743
|
*/
|
|
@@ -715,7 +749,7 @@ const Str = {
|
|
|
715
749
|
* @param percentageString The percentage as a string
|
|
716
750
|
*/
|
|
717
751
|
percentageStringToNumber(percentageString) {
|
|
718
|
-
return Number(
|
|
752
|
+
return Number(cutAfter(percentageString, '%'));
|
|
719
753
|
},
|
|
720
754
|
/**
|
|
721
755
|
* Remove all the spaces from a string
|
|
@@ -761,7 +795,7 @@ const Str = {
|
|
|
761
795
|
* Converts a value to boolean, case-insensitive.
|
|
762
796
|
*/
|
|
763
797
|
toBool(value) {
|
|
764
|
-
if (
|
|
798
|
+
if (isString(value)) {
|
|
765
799
|
return value.toLowerCase() === 'true';
|
|
766
800
|
}
|
|
767
801
|
return !!value;
|
|
@@ -811,9 +845,7 @@ const Str = {
|
|
|
811
845
|
/**
|
|
812
846
|
* Check for whether a phone number is valid according to E.164 standard.
|
|
813
847
|
*/
|
|
814
|
-
isValidE164Phone
|
|
815
|
-
return Constants.CONST.SMS.E164_REGEX.test(phone);
|
|
816
|
-
},
|
|
848
|
+
isValidE164Phone,
|
|
817
849
|
/**
|
|
818
850
|
* Check for whether a phone number is valid in different formats/standards. For example:
|
|
819
851
|
* significant: 4404589784
|
|
@@ -842,14 +874,12 @@ const Str = {
|
|
|
842
874
|
/**
|
|
843
875
|
* Returns text without our SMS domain
|
|
844
876
|
*/
|
|
845
|
-
removeSMSDomain
|
|
846
|
-
return text.replaceAll(REMOVE_SMS_DOMAIN_PATTERN, '');
|
|
847
|
-
},
|
|
877
|
+
removeSMSDomain,
|
|
848
878
|
/**
|
|
849
879
|
* Returns true if the text is a valid E.164 phone number with our SMS domain removed
|
|
850
880
|
*/
|
|
851
881
|
isSMSLogin(text) {
|
|
852
|
-
return
|
|
882
|
+
return isValidE164Phone(removeSMSDomain(text));
|
|
853
883
|
},
|
|
854
884
|
/**
|
|
855
885
|
* This method will return all matches of a single regex like preg_match_all() in PHP. This is not a common part of
|
|
@@ -907,7 +937,7 @@ const Str = {
|
|
|
907
937
|
return url;
|
|
908
938
|
}
|
|
909
939
|
const website = match[3] ? match[2] : `${defaultScheme}://${match[2]}`;
|
|
910
|
-
return website.toLowerCase() +
|
|
940
|
+
return website.toLowerCase() + cutBefore(match[1], match[2]);
|
|
911
941
|
},
|
|
912
942
|
/**
|
|
913
943
|
* Checks if parameter is a string or function
|
|
@@ -919,14 +949,7 @@ const Str = {
|
|
|
919
949
|
* Get file extension for a given url with or
|
|
920
950
|
* without query parameters
|
|
921
951
|
*/
|
|
922
|
-
getExtension
|
|
923
|
-
var _a, _b;
|
|
924
|
-
if (typeof url !== 'string') {
|
|
925
|
-
Log.warn('Str.getExtension: url is not a string', { url });
|
|
926
|
-
return undefined;
|
|
927
|
-
}
|
|
928
|
-
return (_b = (_a = url.split('.').pop()) === null || _a === void 0 ? void 0 : _a.split('?')[0]) === null || _b === void 0 ? void 0 : _b.toLowerCase();
|
|
929
|
-
},
|
|
952
|
+
getExtension,
|
|
930
953
|
/**
|
|
931
954
|
* Takes in a URL and checks if the file extension is PDF
|
|
932
955
|
*
|
|
@@ -934,7 +957,7 @@ const Str = {
|
|
|
934
957
|
* @returns Whether file path is PDF or not
|
|
935
958
|
*/
|
|
936
959
|
isPDF(url) {
|
|
937
|
-
return
|
|
960
|
+
return getExtension(url) === 'pdf';
|
|
938
961
|
},
|
|
939
962
|
/**
|
|
940
963
|
* Takes in a URL and checks if the file extension is an image
|
|
@@ -945,7 +968,7 @@ const Str = {
|
|
|
945
968
|
* https://reactnative.dev/docs/image#source
|
|
946
969
|
*/
|
|
947
970
|
isImage(url) {
|
|
948
|
-
const extension =
|
|
971
|
+
const extension = getExtension(url);
|
|
949
972
|
if (!extension) {
|
|
950
973
|
return false;
|
|
951
974
|
}
|
|
@@ -961,7 +984,7 @@ const Str = {
|
|
|
961
984
|
* https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs
|
|
962
985
|
*/
|
|
963
986
|
isVideo(url) {
|
|
964
|
-
const extension =
|
|
987
|
+
const extension = getExtension(url);
|
|
965
988
|
if (!extension) {
|
|
966
989
|
return false;
|
|
967
990
|
}
|
|
@@ -974,7 +997,7 @@ const Str = {
|
|
|
974
997
|
* @returns True if is a domain account email, otherwise false.
|
|
975
998
|
*/
|
|
976
999
|
isDomainEmail(email) {
|
|
977
|
-
return
|
|
1000
|
+
return startsWith(email, '+@');
|
|
978
1001
|
},
|
|
979
1002
|
/**
|
|
980
1003
|
* Find the minimum indentation of any line in the string,
|