@@ -30,6 +30,47 @@ type MaskReplaceResult = {
3030const MASK_FLAGS = new Set ( 'aACL09#&?' ) ;
3131const MASK_REQUIRED_FLAGS = new Set ( '0#LA&' ) ;
3232
33+ const DIGIT_ZERO_CODEPOINTS = [
34+ 0x0030 , // ASCII
35+ 0x0660 , // Arabic-Indic
36+ 0x06f0 , // Extended Arabic-Indic
37+ 0x0966 , // Devanagari
38+ 0x09e6 , // Bengali
39+ 0x0a66 , // Gurmukhi
40+ 0x0ae6 , // Gujarati
41+ 0x0b66 , // Oriya
42+ 0x0c66 , // Telugu
43+ 0x0ce6 , // Kannada
44+ 0x0d66 , // Malayalam
45+ 0x0e50 , // Thai
46+ 0x0ed0 , // Lao
47+ 0x0f20 , // Tibetan
48+ 0x1040 , // Myanmar
49+ 0x17e0 , // Khmer
50+ 0x1810 , // Mongolian
51+ 0xff10 , // Full-width
52+ ] as const ;
53+
54+ function replaceUnicodeNumbers ( text : string ) : string {
55+ const matcher = / \p{ Nd} / gu;
56+ const ascii_zero = 0x0030 ;
57+
58+ return text . replace ( matcher , ( digit ) => {
59+ let digitValue = 0 ;
60+ const codePoint = digit . charCodeAt ( 0 ) ;
61+
62+ for ( const zeroCodePoint of DIGIT_ZERO_CODEPOINTS ) {
63+ if ( codePoint >= zeroCodePoint && codePoint <= zeroCodePoint + 9 ) {
64+ digitValue = zeroCodePoint ;
65+ break ;
66+ }
67+ }
68+
69+ digitValue = codePoint - digitValue ;
70+ return String . fromCharCode ( ascii_zero + digitValue ) ;
71+ } ) ;
72+ }
73+
3374const MASK_PATTERNS = new Map ( [
3475 [ 'C' , / (? ! ^ $ ) / u] , // Non-empty (any character that is not an empty string)
3576 [ '&' , / [ ^ \p{ Separator} ] / u] , // Any non-whitespace character (Unicode-aware)
@@ -42,25 +83,6 @@ const MASK_PATTERNS = new Map([
4283 [ '#' , / [ \p{ Number} \- + ] / u] , // Numeric and sign characters (+, -)
4384] ) ;
4485
45- function replaceIMENumbers ( string : string ) : string {
46- return string . replace (
47- / [ 0 1 2 3 4 5 6 7 8 9 ] / g,
48- ( num ) =>
49- ( {
50- '1' : '1' ,
51- '2' : '2' ,
52- '3' : '3' ,
53- '4' : '4' ,
54- '5' : '5' ,
55- '6' : '6' ,
56- '7' : '7' ,
57- '8' : '8' ,
58- '9' : '9' ,
59- '0' : '0' ,
60- } ) [ num ] as string
61- ) ;
62- }
63-
6486function validate ( char : string , flag : string ) : boolean {
6587 return MASK_PATTERNS . get ( flag ) ?. test ( char ) ?? false ;
6688}
@@ -265,7 +287,7 @@ export class MaskParser {
265287 // Initialize the array for the masked string or get a fresh mask with prompts and/or literals
266288 const maskedChars = Array . from ( maskString || this . apply ( '' ) ) ;
267289
268- const inputChars = Array . from ( replaceIMENumbers ( value ) ) ;
290+ const inputChars = Array . from ( replaceUnicodeNumbers ( value ) ) ;
269291 const inputLength = inputChars . length ;
270292
271293 // Clear any non-literal positions from `start` to `endBoundary`
0 commit comments