48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
|
|
// Shared input validators for sign-up, profile, and inventory forms.
|
|||
|
|
|
|||
|
|
export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|||
|
|
|
|||
|
|
// Phone: allows digits, spaces, parens, +, -, . — must contain at least 7 digits.
|
|||
|
|
export const PHONE_REGEX = /^\+?[\d\s().\-]{7,20}$/;
|
|||
|
|
|
|||
|
|
// CAS Registry Number: 2–7 digits, 2 digits, 1 check digit (e.g. 67-56-1).
|
|||
|
|
export const CAS_REGEX = /^\d{2,7}-\d{2}-\d$/;
|
|||
|
|
|
|||
|
|
export function validateEmail(value: string): boolean {
|
|||
|
|
return EMAIL_REGEX.test(value.trim());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function validatePhone(value: string): boolean {
|
|||
|
|
const trimmed = value.trim();
|
|||
|
|
if (!PHONE_REGEX.test(trimmed)) return false;
|
|||
|
|
// Require at least 7 actual digits to avoid strings of only punctuation.
|
|||
|
|
return trimmed.replace(/\D/g, '').length >= 7;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function validatePhoneOrEmail(value: string): boolean {
|
|||
|
|
return validateEmail(value) || validatePhone(value);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function validateCAS(value: string): boolean {
|
|||
|
|
return CAS_REGEX.test(value.trim());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export interface NumberOpts {
|
|||
|
|
min?: number;
|
|||
|
|
max?: number;
|
|||
|
|
integer?: boolean;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export function validateNumber(
|
|||
|
|
value: string | number | undefined | null,
|
|||
|
|
opts: NumberOpts = {},
|
|||
|
|
): boolean {
|
|||
|
|
if (value == null || value === '') return false;
|
|||
|
|
const n = typeof value === 'number' ? value : Number(value);
|
|||
|
|
if (!Number.isFinite(n)) return false;
|
|||
|
|
if (opts.integer && !Number.isInteger(n)) return false;
|
|||
|
|
if (opts.min != null && n < opts.min) return false;
|
|||
|
|
if (opts.max != null && n > opts.max) return false;
|
|||
|
|
return true;
|
|||
|
|
}
|