Releases: kthehatter/go-validator
v1.1.6
What's Changed
- improving validation error handling and improving min lenght and max … by @kthehatter in #13
- Fixes improvements by @kthehatter in #16
Full Changelog: v1.1.5...v1.1.6
Release v1.1.5 - New Validators EachWithOptions and Bug Fixes
Overview
This release introduces the EachWithOptions validator function to the go-validator package, enhancing support for validating arrays or slices of objects (maps or structs) with nested validation rules. It improves JSON structure validation by maintaining case sensitivity for keys and adds robust handling for structs via JSON tags. This update builds on the existing functionality without introducing breaking changes.
Features
- New EachWithOptions Function:
- Validates each element in a slice or array against a set of ValidationOption rules.
- Supports both map[string]interface{} and structs, with struct-to-map conversion via StructToMap.
- Returns the first error encountered, prefixed with the element index (e.g., "element at index 0: 'name' is required").
- Handles nil inputs and non-array types with appropriate error messages.
- Enhanced StructToMap:
- Maps struct fields to keys using json tags (e.g., Name string json:"name"`` → "name"), falling back to field names if no tag is present.
- Processes only exported fields, preventing reflection panics on unexported fields.
- Preserves case sensitivity, ensuring keys like "name" and "Name" are treated as distinct, aligning with JSON’s case-sensitive nature.
Improvements
- Case-Sensitive JSON Validation:
- Ensures distinct handling of keys differing only in case (e.g., {"name": "ahmed", "Name": 123}), critical for accurate JSON structure validation.
- Robustness:
- Added checks for nil and invalid input types in EachWithOptions.
- Improved struct handling to support JSON-unmarshaled data seamlessly.
Testing
- New Test Suite:
- Added TestEachWithOptions with comprehensive test cases:
- Valid and invalid arrays of maps and structs.
- Edge cases: nil, empty arrays, and non-array inputs.
- Mixed-case JSON keys and structs with json tags.
- Verified with go test -v -run ^TestEachWithOptions$ github.com/kthehatter/go-validator/validator.
- Added TestEachWithOptions with comprehensive test cases:
Bug Fixes
- Fixed reflection panic when accessing unexported struct fields in StructToMap.
- Corrected struct field mapping to use json tags properly, resolving validation failures for tagged fields.
Usage Example
import "github.com/kthehatter/go-validator/validator"
options := []validator.ValidationOption{
{Key: "name", IsOptional: false, Validators: []validator.Validator{validator.CreateValidator(validator.IsString, "must be string")}},
{Key: "value", IsOptional: false, Validators: []validator.Validator{validator.CreateValidator(validator.IsNotEmpty, "required")}},
}
data := []interface{}{
map[string]interface{}{"name": "color", "value": "red", "Name": 123},
}
err := validator.EachWithOptions(options)(data)
if err != nil {
// Handle error: e.g., "element at index 0: 'name' is required"
}
```
## What's Changed
* Add EachWithOptions for Validating Arrays of Objects by @kthehatter in https://github.com/kthehatter/go-validator/pull/12
**Full Changelog**: https://github.com/kthehatter/go-validator/compare/v1.1.4...v1.1.5Release v1.1.4 - New Validators and Bug Fixes
Release v1.1.4 - New Validators and Bug Fixes
Release Date: March 16, 2025
Repository: github.com/kthehatter/go-validator
This release introduces new validation functions, improves error messaging, and resolves test inconsistencies in the go-validator package. It’s a minor update that enhances functionality while maintaining compatibility with existing code.
What’s New
- Added IsInArray Validator: Checks if a value exists within a provided array or slice. Useful for validating against dynamic lists of allowed values.
- Added IsNotInArray Validator: Ensures a value is not present in a given array or slice, complementing IsInArray for exclusion checks.
Enhancements
- Improved Error Messages: Updated IsInArray and IsNotInArray to include the array contents in error messages (e.g., "value must be one of [apple banana cherry]"), making validation failures more informative.
- Consistency in IsNotIn: Adjusted behavior and error handling for better alignment with expected outcomes, especially for type mismatches.
Bug Fixes
- Fixed Failing Tests: Resolved discrepancies in TestIsNotIn, TestIsInArray, and TestIsNotInArray where expected error messages and wrong-type handling didn’t match actual behavior.
Usage Example
package main
import (
"fmt"
"github.com/kthehatter/go-validator/validator"
)
func main() {
// Check if a value is in an array
err := validator.IsInArray([]string{"apple", "banana", "cherry"})("apple")
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Value is in the array!")
}
// Check if a value is not in a list
err = validator.IsNotIn("apple", "banana")("grape")
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Value is not disallowed!")
}
}
```v1.1.3
New Features
- Base64 Image Validation:
- Added
IsBase64Imagevalidator to check if a string is a valid Base64-encoded image. - Supported image formats: JPEG, PNG, GIF, BMP, and WebP.
- Added
Example Usage
Here’s how you can use the new IsBase64Image validator:
rules := []validator.ValidationOption{
{
Key: "profile_picture",
IsOptional: false,
Validators: []validator.Validator{
validator.CreateValidator(validator.IsBase64Image, "invalid base64 image"),
},
},
}v1.1.2
**Release v1.1.2 - New Transformation Functions
New Features
-
Transformation Functions:
-
Added support for transformation functions that can be applied to fields before validation. This allows you to modify input data (e.g., trimming whitespace, converting to lowercase) as part of the validation process.
-
Supported transformations:
-
Trim: Trims leading and trailing whitespace from strings. -
ToLower: Converts strings to lowercase.
-
-
Example Usage
Here’s how you can use the new transformation features:
rules := []validator.ValidationOption{
{
Key: "username",
IsOptional: false,
Transformers: []validator.TransformerFunc{
validator.Trim,
validator.ToLower,
},
Validators: []core.Validator{
validator.CreateValidator(validator.IsNotEmpty, "username is required"),
validator.CreateValidator(validator.MinLength(3), "username must be at least 3 characters long"),
},
},
{
Key: "email",
IsOptional: false,
Transformers: []validator.TransformerFunc{
validator.Trim,
validator.ToLower,
},
Validators: []validator.Validator{
validator.CreateValidator(validator.IsEmail, "invalid email address"),
},
},
}Breaking Changes
- None. This release is fully backward-compatible with
v1.1.1.
v1.1.1
Release v1.1.1 - Transformation Functions and Unicode-Aware Title Casing
New Features
-
Transformation Functions:
-
Added support for transformation functions that can be applied to fields before validation. This allows you to modify input data as part of the validation process.
-
Supported transformations:
-
ToTitleCase: Converts strings to title case (Unicode-aware). -
RemoveSpecialChars: Removes special characters from strings. -
ToInt: Converts strings or floats to integers. -
ToFloat: Converts strings or integers to floats. -
DefaultValue: Sets a default value if the field is empty or nil. -
Truncate: Truncates strings to a specified maximum length. -
Replace: Replaces occurrences of a substring with another string.
-
-
-
Unicode-Aware Title Casing:
- Replaced the deprecated
strings.Titlefunction with the Unicode-awaregolang.org/x/text/casespackage for title casing. This ensures proper handling of Unicode punctuation and word boundaries.
- Replaced the deprecated
Improvements
-
Enhanced Flexibility:
-
Transformations can now be applied alongside validators and nested validators, making it easier to preprocess data before validation.
-
Transformations are applied before validators, ensuring that the validated data is in the desired format.
-
-
Better Error Handling:
- Improved error messages for invalid transformations and validations.
Example Usage
Here’s how you can use the new transformation features:
rules := []validator.ValidationOption{
{
Key: "username",
IsOptional: false,
Transformers: []validator.TransformerFunc{
validator.RemoveSpecialChars,
validator.ToTitleCase,
},
Validators: []core.Validator{
validator.CreateValidator(validator.IsNotEmpty, "username is required"),
validator.CreateValidator(validator.MinLength(3), "username must be at least 3 characters long"),
},
},
{
Key: "email",
IsOptional: false,
Transformers: []validator.TransformerFunc{
validator.RemoveSpecialChars,
validator.ToTitleCase,
},
Validators: []validator.Validator{
validator.CreateValidator(validator.IsEmail, "invalid email address"),
},
},
}Breaking Changes
- None. This release is fully backward-compatible with
v1.1.0.
v1.1.0
Release v1.1.0
This release introduces several new validators and a powerful Each function to validate elements in slices or arrays. Below is a summary of the changes:
New Validators
-
IsArabic:- Checks if a string contains only Arabic characters.
- Example:
validator.CreateValidator(validator.IsArabic, "Value must contain only Arabic characters")
-
IsArabicNumeric:- Checks if a string contains only Arabic numerals (٠١٢٣٤٥٦٧٨٩).
- Example:
validator.CreateValidator(validator.IsArabicNumeric, "Value must contain only Arabic numerals")
-
IsAlphaArabic:- Checks if a string contains only Arabic and Latin alphabetic characters.
- Example:
validator.CreateValidator(validator.IsAlphaArabic, "Value must contain only Arabic and Latin alphabetic characters")
-
IsAlphaArabicNumeric:- Checks if a string contains only Arabic and Latin alphabetic characters and Arabic numerals.
- Example:
validator.CreateValidator(validator.IsAlphaArabicNumeric, "Value must contain only Arabic and Latin alphabetic characters and Arabic numerals")
New Function
Each:- Validates that every element in a slice or array satisfies the provided validator function.
- Example:
validator.CreateValidator(validator.Each(validator.IsString), "Each element must be a string")
Example Usage
Here’s an example of how to use the new validators and the Each function:
options := []validator.ValidationOption{
{
Key: "name",
Validators: []validator.Validator{
validator.CreateValidator(validator.IsArabic, "Name must contain only Arabic characters"),
},
},
{
Key: "numbers",
Validators: []validator.Validator{
validator.CreateValidator(validator.Each(validator.IsArabicNumeric), "Each element must be an Arabic numeral"),
},
},
}
input := map[string]interface{}{
"name": "مرحبا",
"numbers": []interface{}{"٠", "١", "٢"},
}
if err := validator.Validate(input, options); err != nil {
fmt.Println("Validation error:", err)
} else {
fmt.Println("Validation passed!")
}v1.0.1
more tests added to the package