Ack is a schema validation library for Dart and Flutter that helps you validate data with a simple, fluent API. Ack is short for "acknowledge".
- Simplify Validation: Easily handle complex data validation logic
- Ensure Data Integrity: Guarantee data consistency from external sources (APIs, user input)
- Single Source of Truth: Define data structures and rules in one place
- Reduce Boilerplate: Minimize repetitive code for validation and JSON conversion
- Type Safety: Generate type-safe schema classes from your Dart models
This repository is a monorepo containing:
- ack: Core validation library with fluent schema building API
- ack_generator: Code generator for creating schema classes from annotated Dart models
- example: Example projects demonstrating usage of both packages
Add Ack to your project:
dart pub add ack
Define and use a schema:
import 'package:ack/ack.dart';
// Define a schema for a user object
final userSchema = Ack.object({
'name': Ack.string().minLength(2).maxLength(50),
'email': Ack.string().email(),
'age': Ack.integer().min(0).max(120).optional(),
});
// Validate data against the schema
final result = userSchema.safeParse({
'name': 'John Doe',
'email': '[email protected]',
'age': 30
});
// Check if validation passed
if (result.isOk) {
final validData = result.getOrThrow();
print('Valid user: $validData');
} else {
final error = result.getError();
print('Validation failed: $error');
}
Use .optional()
when a field may be omitted entirely. Chain .nullable()
if a present field may hold null
, or combine both for an optional-and-nullable value.
For more complex validation scenarios:
import 'package:ack/ack.dart';
// Complex nested object validation
final orderSchema = Ack.object({
'id': Ack.string().uuid(),
'customer': Ack.object({
'name': Ack.string().minLength(2),
'email': Ack.string().email(),
}),
'items': Ack.list(Ack.object({
'product': Ack.string(),
'quantity': Ack.integer().positive(),
'price': Ack.double().positive(),
})).minLength(1),
'total': Ack.double().positive(),
}).refine(
(order) {
// Custom validation: total should match sum of items
final items = order['items'] as List;
final calculatedTotal = items.fold<double>(0, (sum, item) {
final itemMap = item as Map<String, Object?>;
final quantity = itemMap['quantity'] as int;
final price = itemMap['price'] as double;
return sum + (quantity * price);
});
final total = order['total'] as double;
return (calculatedTotal - total).abs() < 0.01;
},
message: 'Total must match sum of item prices',
);
// Validate complex data
final result = orderSchema.safeParse(orderData);
if (result.isOk) {
final validOrder = result.getOrThrow();
print('Valid order: ${validOrder['id']}');
} else {
print('Validation failed: ${result.getError()}');
}
Detailed documentation is available at docs.page/btwld/ack.
This project uses Melos to manage the monorepo.
# Install Melos (if not already installed)
dart pub global activate melos
# Bootstrap the workspace (installs dependencies for all packages)
melos bootstrap
# Run tests across all packages
melos test
# Format code across all packages
melos format
# Analyze code across all packages
melos analyze
# Check for outdated dependencies
melos deps-outdated
# Run build_runner for packages that need it (e.g., ack_generator, example)
melos build
# Clean build artifacts
melos clean
# Bump patch version (0.0.x)
melos version-patch
# Bump minor version (0.x.0)
melos version-minor
# Bump major version (x.0.0)
melos version-major
# Dry-run publish (validation only)
melos publish-dry
# Publish packages to pub.dev
melos publish
The project includes additional development tools for maintainers:
# JSON Schema validation (ensures compatibility with JSON Schema Draft-7)
melos validate-jsonschema
# API compatibility checking using Dart script (for semantic versioning)
melos api-check v0.2.0
# See all available scripts
melos list-scripts
Note: Additional development documentation is available in the
tools/
directory for project maintainers.
This project uses GitHub Releases to manage versioning and publishing. For detailed instructions on how to create releases and publish packages, see PUBLISHING.md.
Contributions are welcome! A detailed CONTRIBUTING.md file will be added soon with specific guidelines.
In the meantime, please follow these basic steps:
- Fork the repository
- Create a feature branch
- Add your changes
- Run tests with
melos test
- Make sure to follow Conventional Commits in your commit messages
- Submit a pull request