package ui import ( "errors" "fmt" "github.com/go-playground/validator/v10" "regexp" ) // Instancia global del validador var validate *validator.Validate func init() { validate = validator.New() _ = validate.RegisterValidation("username", validateUsername) } // GetValidator devuelve la instancia del validador func GetValidator() *validator.Validate { return validate } // Validación personalizada de username (ejemplo) func validateUsername(fl validator.FieldLevel) bool { value := fl.Field().String() re := regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9_]$`) if !re.MatchString(value) { return false } if regexp.MustCompile(`[.-]{2}`).MatchString(value) { return false } return true } var ErrorMessages = map[string]string{ "required": "Este campo es obligatorio", "min": "Debe tener al menos %s caracteres", "max": "No puede tener más de %s caracteres", "email": "Correo electrónico no válido", "alphanum": "Solo se permiten letras y números", "alpha": "Solo se permiten letras", "numeric": "Solo se permiten números", "len": "Debe tener exactamente %s caracteres", "url": "Formato de URL no válido", "containsany": "Debe contener al menos uno de estos caracteres: %s", "username": "Formato de usuario no válido", } // translateError convierte un error de validación a mensaje legible func translateError(err validator.FieldError) string { template, exists := ErrorMessages[err.Tag()] if !exists { return "Valor inválido" } // Si el mensaje tiene placeholder, reemplazar con el parámetro if err.Param() != "" { return fmt.Sprintf(template, err.Param()) } return template } // GetFirstError extrae el primer error de validación func GetFirstError(err error) string { var validationErrors validator.ValidationErrors if errors.As(err, &validationErrors) { if len(validationErrors) > 0 { return translateError(validationErrors[0]) } } return "Error de validación" }