40 lines
1.2 KiB
TypeScript
40 lines
1.2 KiB
TypeScript
const PERSIAN_DIGITS = '۰۱۲۳۴۵۶۷۸۹';
|
||
const ARABIC_DIGITS = '٠١٢٣٤٥٦٧٨٩';
|
||
const INVISIBLE_CHARS = /[\u200c\u200d\u202a-\u202e\ufeff]/g;
|
||
|
||
export const IRAN_MOBILE_REGEX = /^09\d{9}$/;
|
||
|
||
function toAsciiDigits(value: string): string {
|
||
return value.replace(/[۰-۹٠-٩]/g, (ch) => {
|
||
const persian = PERSIAN_DIGITS.indexOf(ch);
|
||
if (persian >= 0) return String(persian);
|
||
const arabic = ARABIC_DIGITS.indexOf(ch);
|
||
if (arabic >= 0) return String(arabic);
|
||
return ch;
|
||
});
|
||
}
|
||
|
||
/** Normalize Iranian mobile to 09xxxxxxxxx (11 digits). */
|
||
export function normalizeIranMobile(raw: string): string {
|
||
let mobile = toAsciiDigits(String(raw ?? '').trim());
|
||
mobile = mobile.replace(INVISIBLE_CHARS, '');
|
||
|
||
let digits = mobile.replace(/\D/g, '');
|
||
if (!digits) return '';
|
||
|
||
if (digits.startsWith('0098')) {
|
||
digits = digits.slice(2);
|
||
}
|
||
if (digits.startsWith('98') && digits.length >= 12) {
|
||
digits = `0${digits.slice(2)}`;
|
||
} else if (digits.startsWith('9') && digits.length === 10) {
|
||
digits = `0${digits}`;
|
||
}
|
||
|
||
return digits;
|
||
}
|
||
|
||
export function isValidIranMobile(mobile: string): boolean {
|
||
return IRAN_MOBILE_REGEX.test(mobile);
|
||
}
|