Type-Specific Validation

Type-Specific Validation

Different data types require specific validation approaches:

class TypeValidator {
    // Numeric validation with range checking
    static validateInteger(value, min = null, max = null) {
        const num = parseInt(value, 10);
        
        if (isNaN(num) || num.toString() !== value.toString()) {
            throw new Error('Invalid integer format');
        }
        
        if (min !== null && num < min) {
            throw new Error(`Value must be at least ${min}`);
        }
        
        if (max !== null && num > max) {
            throw new Error(`Value must be at most ${max}`);
        }
        
        return num;
    }
    
    // Date validation with format checking
    static validateDate(dateString, format = 'YYYY-MM-DD') {
        const formats = {
            'YYYY-MM-DD': /^\d{4}-\d{2}-\d{2}$/,
            'MM/DD/YYYY': /^\d{2}\/\d{2}\/\d{4}$/,
            'DD-MM-YYYY': /^\d{2}-\d{2}-\d{4}$/
        };
        
        if (!formats[format].test(dateString)) {
            throw new Error(`Date must be in ${format} format`);
        }
        
        const date = new Date(dateString);
        if (isNaN(date.getTime())) {
            throw new Error('Invalid date');
        }
        
        // Prevent unrealistic dates
        const minDate = new Date('1900-01-01');
        const maxDate = new Date();
        maxDate.setFullYear(maxDate.getFullYear() + 10);
        
        if (date < minDate || date > maxDate) {
            throw new Error('Date out of acceptable range');
        }
        
        return date;
    }
    
    // Array validation for bulk operations
    static validateArray(arr, itemValidator, maxLength = 1000) {
        if (!Array.isArray(arr)) {
            throw new Error('Input must be an array');
        }
        
        if (arr.length > maxLength) {
            throw new Error(`Array exceeds maximum length of ${maxLength}`);
        }
        
        return arr.map((item, index) => {
            try {
                return itemValidator(item);
            } catch (error) {
                throw new Error(`Invalid item at index ${index}: ${error.message}`);
            }
        });
    }
}

// Usage example
try {
    const userId = TypeValidator.validateInteger(request.params.id, 1, 999999);
    const startDate = TypeValidator.validateDate(request.query.start);
    const categoryIds = TypeValidator.validateArray(
        request.body.categories,
        (id) => TypeValidator.validateInteger(id, 1, 100),
        50
    );
} catch (error) {
    response.status(400).json({ error: error.message });
}