My name is Nabeel. I am a Flutter and Dart developer ๐!
exaby73 / luthor Goto Github PK
View Code? Open in Web Editor NEWPure Dart validation library inspired by https://zod.dev
Home Page: https://pub.dev/packages/luthor
License: MIT License
Pure Dart validation library inspired by https://zod.dev
Home Page: https://pub.dev/packages/luthor
License: MIT License
Take the following code sample:
void main() {
final v = l.list(validators: [l.number().required()]);
print(v.validateValue([1, 2, 3, null]));
}
Currently, the above code results in a success case, even though the only validator that exists is a required number validator. This means, null
should have been caught and an error should have been returned instead of a success
The following code throws a null error due to covariant
being used in SchemaValidation
. Simplest solution is to remove the covariant
and manually check the type at runtime.
final nestedSchema = nestedSchema = l.schema({
'address': l.schema({
'city': l.string().required(),
'state': l.string().required(),
}).required(),
});
nestedSchema.validateSchema({}); // throws
Right now, if you want to convert your validated data into a Dart object, you have to do the conversion manually, or through a package like json_serializable
. Take the following code:
class AuthDto {
final String email;
final String password;
const AuthDto({required this.email, required this.password});
factory AuthDto.fromJson(Map<String, dynamic> json) {
return AuthDto(email: json['email'] as String, password: json['password'] as String);
}
}
final v = l.schema({'email': l.string().email().required(), 'password': l.string().min(8).required()});
final rawJson = {'email': '[email protected]', 'password': 'password'};
final result = v.validateSchema(rawJson);
switch (result) {
case SchemaValidationSuccess(data: final validatedJson):
final dto = AuthDto.fromJson(validatedJson);
// Do something with the dto
case SchemaValidationError(data: _, errors: final errors):
// Do something with the errors
}
Here we have to manually call fromJson
rather than SchemaValidationSuccess
giving us the dto in the first place. This proposal would add a fromJson
argument to validateSchema
and validateSchemaWithFieldName
so we can do this:
final v = l.schema({'email': l.string().email().required(), 'password': l.string().min(8).required()});
final rawJson = {'email': '[email protected]', 'password': 'password'};
final result = v.validateSchema(rawJson, fromJson: AuthDto.fromJson);
switch (result) {
case SchemaValidationSuccess(data: final dto):
// Do something with the dto. dto is of type `AuthDto`
case SchemaValidationError(data: _, errors: final errors):
// Do something with the errors
}
Currently, using luthor_generator
, we have to manually convert the dto. But ideally, luthor_generator
can do this for us using this technique. We don't need to add functionality to luthor
but we can rely on code generation to generate this behavior for us instead of adding this argument, but I think this could be useful for those who don't want to use code generation, and just want to use the base package instead.
Currently, luthor does not support name in JsonKey and fieldRename in JsonSerializable, which prevents luthor from being used in some projects.
For example:
@luthor
@freezed
class TestEntity with _$TestEntity {
@JsonSerializable(fieldRename: FieldRename.snake)
const factory TestEntity({
required String firstTestField,
@JsonKey(name: "second") required String secondTestField,
}) = _TestEntity;
static SchemaValidationResult<TestEntity> validate(Map<String, dynamic> json) => _$validate(json);
factory TestEntity.fromJson(Map<String, dynamic> json) => _$TestEntityFromJson(json);
}
will generate:
Validator $TestEntitySchema = l.schema({
'firstTestField': l.string().required(),
'secondTestField': l.string().required(),
});
but should:
Validator $TestEntitySchema = l.schema({
'first_test_field': l.string().required(),
'second': l.string().required(),
});
Hello!
One aspect of Zod which works well with TypeScript is the union types returned from parsing/validating a schema:
const input = z.string().safeParse(123);
console.log(input.data) // type error!
if (!input.success) {
console.log(input.message);
return;
}
console.log(input.data) // ok!
Based on the readme, at the moment the result doesn't handle this scenario which makes things less type safe. Using freezed unions, you could internally return a Validation
union, something like:
final result = l.string().validate('hello');
result.when(
success: (String value) => print(value),
error: (String message) => throw Exception(message),
)
Currently, luthor
gives single strings as error messages, even if you're validating a schema. Ideally, it should return a list of strings for single validations, and a map of strings and list of strings for schema validations.
final v = l.string().email().required();
final r = v.validate(1);
print(r.whenOrNull(error: (e) => e)); // "value is not a string"
final s = l.schema({
email: l.string.email().required(),
password: l.string.min(8).required(),
});
final r = v.validate({'email': 1});
print(r.whenOrNull(error: (e) => e)); // "email is not a string"
final v = l.string().email().required();
final r = v.validate(1);
print(r.whenOrNull(error: (e) => e)); // ["value is not a string", "value is not a valid email"]
final s = l.schema({
email: l.string.email().required(),
password: l.string.min(8).required(),
});
final r = v.validate({'email': 1});
print(r.whenOrNull(error: (e) => e));
/*
{
"email": ["email is not a string", "email is not a valid email"],
"password: ["password is not a string", "password must be at least 8 characters long", "password is required"]
}
*/
Consider a non-nullable field is validated. If that field doesn't exist, the validation catches it but still tries to call fromJson
which may throw a type error if fromJson
is expecting a non-null value, which is intended. Single fix is to remove data
from SchemaValidationError
.
luthor/packages/luthor/lib/src/validator.dart
Lines 130 to 142 in da7ea81
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.