filterable_generator 1.0.0
filterable_generator: ^1.0.0 copied to clipboard
Code generator for creating type-safe filter and sort functionality for Dart models. Works with build_runner and filterable_annotation.
filterable_generator #
Code generator for creating type-safe filter and sort functionality for Dart models annotated with @Filterable. Works with build_runner to generate extension methods that enable dynamic filtering and sorting.
โจ Features #
- ๐ฏ Type-safe code generation - Compile-time type validation
- โก High performance - Optimized generated code
- ๐ง Highly customizable - Custom comparators and comparison functions
- ๐ Enum support - Filter by value, index (int), or name (string)
- ๐ List operations - Contains checks and length comparisons
- ๐จ UI-ready - Generates field metadata for dynamic UI generation
- ๐งฉ Clean architecture - Well-structured, maintainable generated code
๐ฆ Installation #
Add to your pubspec.yaml:
dependencies:
filterable_annotation: ^1.0.0
dev_dependencies:
filterable_generator: ^1.0.0
build_runner: ^2.4.0 # or ^2.3.0, works with multiple versions
Version Compatibility #
filterable_generator is designed to work with a wide range of dependency versions:
- Build Runner: 2.4.0 - 2.10.x โ TESTED
- Analyzer: 5.2.0 - 9.x (supports both Element and Element2 APIs)
- Build: 2.4.0 - 4.x (works across major versions)
- Source Gen: 1.2.0 - 4.x (adaptive version support)
- Flutter: 3.0.0+ and Dart 3.0.0+
Recommended Versions
For maximum compatibility (works with most other packages):
dev_dependencies:
filterable_generator: ^1.0.0
build_runner: ^2.4.0 # Most compatible
For latest features (newer projects):
dev_dependencies:
filterable_generator: ^1.0.0
build_runner: ^2.7.0 # Latest
This ensures compatibility with:
- โ Older Flutter projects (SDK 3.0.0+)
- โ Latest Flutter stable
- โ Mixed dependency environments
- โ Other code generators (json_serializable, freezed, riverpod_generator, etc.)
See COMPATIBILITY.md and TEST_RESULTS.md for detailed version information and test results.
๐ Quick Start #
1. Annotate your model #
import 'package:filterable_annotation/filterable_annotation.dart';
part 'product.filterable.g.dart';
@Filterable()
class Product {
@FilterableField(label: 'Name', comparatorsType: String)
final String name;
@FilterableField(label: 'Price', comparatorsType: double)
final double price;
@FilterableField(label: 'Category', comparatorsType: String)
final String category;
@FilterableField(label: 'Tags', comparatorsType: String)
final List<String> tags;
Product({
required this.name,
required this.price,
required this.category,
required this.tags,
});
}
2. Run code generation #
# One-time generation
dart run build_runner build
# Watch for changes
dart run build_runner watch
# Clean and rebuild
dart run build_runner build --delete-conflicting-outputs
3. Use generated code #
// Filter products
final criteria = FilterCriteria(
field: 'price',
comparator: '>=',
value: 100.0,
);
final predicate = ProductFilterExtension.buildPredicate(criteria);
final filtered = products.where(predicate).toList();
// Sort products
final sortCriteria = SortCriteria(field: 'name', ascending: true);
final sorter = ProductFilterExtension.buildSorter(sortCriteria);
products.sort(sorter);
// Access metadata
final fields = ProductFilterExtension.filterableFields;
๐ Generated Code #
For the example above, the generator creates:
extension ProductFilterExtension on Product {
static bool Function(Product) buildPredicate(FilterCriteria criteria) {
// Generated filtering logic
}
static int Function(Product, Product) buildSorter(SortCriteria criteria) {
// Generated sorting logic
}
static List<FilterableFieldInfo> get filterableFields => [
// Field metadata for UI generation
];
}
๐ฏ Supported Operations #
String Fields #
==,!=- Equality/inequalitycontains- Substring searchstartsWith,endsWith- Prefix/suffix matching
Numeric Fields (int, double) #
==,!=- Equality/inequality>,<,>=,<=- Comparison
DateTime Fields #
==,!=- Equality/inequality>,<,>=,<=- Date comparison
Boolean Fields #
==,!=- Equality/inequality
Enum Fields #
==,!=- Can compare by:- Enum value:
Status.active - Index (int):
0,1,2 - Name (string):
'active','inactive'
- Enum value:
List Fields #
contains,notContains- Element presencelength==,length!=,length>,length<,length>=,length<=- Length comparison
๐ง Advanced Usage #
Custom Comparators #
Limit allowed comparison operators:
@FilterableField(
label: 'Status',
comparatorsType: String,
comparators: ['==', '!='], // Only equality checks
)
final String status;
Custom Comparison Functions #
Use custom logic for complex comparisons:
@Filterable()
class Order {
@FilterableField(
label: 'Items',
comparatorsType: int,
customCompare: Order.itemHasId,
)
final List<OrderItem> items;
Order({required this.items});
static bool itemHasId(OrderItem item, int id) {
return item.id == id;
}
}
// Usage
final criteria = FilterCriteria(
field: 'items',
comparator: 'contains',
value: 123,
);
Enum Filtering #
enum Priority { low, medium, high, critical }
@Filterable()
class Task {
@FilterableField(label: 'Priority', comparatorsType: Priority)
final Priority priority;
}
// Filter by enum value
final c1 = FilterCriteria(field: 'priority', comparator: '==', value: Priority.high);
// Filter by index
final c2 = FilterCriteria(field: 'priority', comparator: '>=', value: 2);
// Filter by name
final c3 = FilterCriteria(field: 'priority', comparator: '==', value: 'critical');
Nullable Fields #
Automatically handles null safety:
@FilterableField(label: 'Description', comparatorsType: String)
final String? description; // Null-safe comparisons generated
๐๏ธ Architecture #
The generator uses a clean, modular architecture:
- Field Extraction - Parses annotations and field metadata
- Predicate Generation - Creates type-safe filter functions
- Sorter Generation - Creates comparison functions
- Metadata Generation - Produces UI-ready field information
Key components:
_extractFilterableFields()- Processes field annotations_generateBuildPredicate()- Generates filter logic_generateBuildSorter()- Generates sort logic_generateFilterableFieldsInfo()- Generates metadata
Analyzer Compatibility #
The generator is designed to work with multiple versions of the analyzer package:
- Automatic Detection: Detects available API (Element vs Element2)
- Wide Version Range: Supports analyzer 5.x through 9.x
- Graceful Adaptation: Uses compatible API calls for each version
- No Breaking Changes: Works seamlessly across analyzer updates
๐งช Testing #
The generated code is tested through:
- Type safety validation at compile time
- Runtime testing in the example app
- Integration with real-world use cases
๐ค Related Packages #
- filterable_annotation - Annotations (required)
- build_runner - Build system (required)
๐ Examples #
Check out the example app for:
- Complete working implementation
- UI integration examples
- Custom comparator usage
- Dynamic filter generation
๐ Issues and Feedback #
File issues, bugs, or feature requests in our issue tracker.
๐ License #
MIT License - see LICENSE file for details.
๐ Contributing #
Contributions welcome! Please read our contributing guidelines first.
๐ Changelog #
See CHANGELOG.md for version history.