| import type { MessageKey } from '../i18n/en' |
|
|
| const MAX_MAJOR = 1_000_000 |
|
|
| |
| export function validateAmount(raw: string): MessageKey | undefined { |
| const s = raw.trim() |
| if (!s) return 'error.amountEmpty' |
| if (!/^\d*\.?\d*$/.test(s) || s === '.') return 'error.amountInvalid' |
| const n = Number(s) |
| if (!Number.isFinite(n)) return 'error.amountInvalid' |
| if (n < 0) return 'error.amountNegative' |
| if (n === 0) return 'error.amountZero' |
| if (n > MAX_MAJOR) return 'error.amountTooLarge' |
| if (!/^\d+(\.\d{1,2})?$/.test(s)) return 'error.amountInvalid' |
| return undefined |
| } |
|
|
| |
| export function isValidSaudiIban(raw: string): boolean { |
| const s = raw.replace(/\s+/g, '').toUpperCase() |
| if (!/^SA\d{22}$/.test(s)) return false |
| const rearranged = s.slice(4) + s.slice(0, 4) |
| let rem = 0 |
| for (const ch of rearranged) { |
| const val = ch >= 'A' && ch <= 'Z' ? String(ch.charCodeAt(0) - 55) : ch |
| for (const d of val) rem = (rem * 10 + (d.charCodeAt(0) - 48)) % 97 |
| } |
| return rem === 1 |
| } |
|
|
| export function validateIban(raw: string): MessageKey | undefined { |
| if (!raw.trim()) return 'error.payeeEmpty' |
| return isValidSaudiIban(raw) ? undefined : 'error.ibanInvalid' |
| } |
|
|
| export function validateMerchant(raw: string): MessageKey | undefined { |
| return raw.trim() ? undefined : 'error.merchantEmpty' |
| } |
|
|