validateInputFieldsWithRules

JavaScript
// Validates an object against field rules and returns field-level error messages.
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export function validateInputFields(input, schema) {
  const errors = {};
  const values = {};
  for (const [field, rules] of Object.entries(schema)) {
    const label = rules.label ?? field;
    const raw = input?.[field];
    const missing = raw === undefined || raw === null || raw === '';
    if (missing) {
      if (rules.required) errors[field] = `${label} is required`;
      continue;
    }
    if (rules.type === 'number') {
      const number = Number(raw);
      if (!Number.isFinite(number)) {
        errors[field] = `${label} must be a number`;
      } else if (rules.min !== undefined && number < rules.min) {
        errors[field] = `${label} must be at least ${rules.min}`;
      } else if (rules.max !== undefined && number > rules.max) {
        errors[field] = `${label} must be at most ${rules.max}`;
      } else {
        values[field] = number;
      }
      continue;
    }
    const text = String(raw).trim();
    if (rules.pattern && !rules.pattern.test(text)) {
      errors[field] = rules.message ?? `${label} has an invalid format`;
    } else if (rules.format === 'email' && !emailPattern.test(text)) {
      errors[field] = `${label} must be a valid email address`;
    } else {
      values[field] = text;
    }
  }
  return { valid: Object.keys(errors).length === 0, errors, values };
}