Upgrading to 1.0
1.0 renames a few methods, replaces the two result types with one, and changes how errors are shaped. This page is the migration list, built from the two changelogs. Work through the tables, then the behaviour changes, then run your tests.
Requirements
Section titled “Requirements”Dart 3.11 or Flutter 3.41 or later. For the generator, your project’s analyzer has to resolve between 10 and 14, which every Flutter release from 3.41 does. With freezed, use 3.2.x on Dart 3.11 and 4 on Dart 3.13 or later.
dependencies: luthor: ^1.0.0dev_dependencies: luthor_generator: ^1.0.0Runtime calls
Section titled “Runtime calls”| 0.x | 1.0 |
|---|---|
l.number() |
l.num() |
l.boolean() |
l.bool() |
v.validateValue(x) |
v.validate(x) |
schema.validateSchema(map) |
schema.validate(map) |
schema.validateSchema<User>(map, fromJson: User.fromJson) |
schema.validateSchema(map, fromJson: User.fromJson) |
SingleValidationResult<T>, SchemaValidationResult<T> |
ValidationResult<T> |
SingleValidationSuccess(data:), SchemaValidationSuccess(data:) |
ValidationSuccess(:final data) |
SingleValidationError(errors:) |
ValidationFailure(:final messages) |
SchemaValidationError(errors:) |
ValidationFailure(:final errors) |
(result as SchemaValidationError).getError('a.b') |
result.getError('a.b'), on any result |
errors['[DEFAULT]'] |
result.getErrors('') |
l.list(validators: [v]) |
l.list(v) |
l.list(validators: [a, b]) |
l.list(l.union([a, b])) |
l.list() |
l.list(l.any()) |
l.custom(f), l.required() |
l.any().custom(f), l.any().required() |
l.withName('x').string() |
l.string().withName('x') |
l.string().regex(r'^\d+$') |
l.string().regex(RegExp(r'^\d+$')) |
messageFn: () => 'text' |
messageBuilder: (issue) => 'text' |
custom((Object? value) => ...) |
custom((value) => ...), where value has the validator’s type |
customWithSchema((value, Map data) => ...) |
customWithSchema((value, SchemaData data) => ...) |
Validator v = l.string() |
StringValidator v = l.string() |
Validator(initialValidations: ...) |
Removed. Start from l. |
Annotations
Section titled “Annotations”| 0.x | 1.0 |
|---|---|
@HasMinDouble(1.5), @HasMinNumber(1) |
@HasMin(1.5), @HasMin(1) |
@HasMaxDouble(1.5), @HasMaxNumber(1) |
@HasMax(1.5), @HasMax(1) |
@IsEmail(messageFn: f) |
@IsEmail(messageBuilder: f), where f takes a ValidationIssue |
@WithCustomValidator(bool Function(Object?) f) |
@WithCustomValidator(f), where f takes the field’s type |
@WithSchemaCustomValidator(bool Function(Object?, Map) f) |
@WithSchemaCustomValidator(f), where f takes the field’s type and SchemaData |
@MatchRegex(r'...') |
Unchanged. The generator builds the RegExp. New flags: caseSensitive, multiLine, unicode, dotAll. |
@luthorForwardRef |
Deprecated, no effect. Remove it; every nested reference is a forward reference now. |
Generated code
Section titled “Generated code”| 0.x | 1.0 |
|---|---|
Validator $XSchema |
final SchemaValidator $XSchema |
$XValidate(Map<String, dynamic>) returning SchemaValidationResult<X> |
$XValidate(Object?) returning ValidationResult<X> |
XErrorKeys.address for a nested model: a record of paths |
The same record plus $key, the nested field’s own path |
Public $YSchema, YSchemaKeys, $YValidate for a class without @luthor |
Private _$YSchema only. Annotate Y with @luthor for the public API. |
validateSelf() on every model |
Only on models with toJson() or a dart_mappable toMap() |
build.yaml with source_gen:combining_builder for plain classes |
Not needed |
Behaviour changes to check
Section titled “Behaviour changes to check”These change results without changing your code. Each links to the page that explains the new behaviour.
- Unknown keys are stripped. The output of a schema, and the map a generated
fromJsonreceives, contain only declared fields. Add.passthrough()to keep extra keys. Schemas. - Validation stops after a failed type check.
l.int().min(1).validate('5')reports one issue, not two. How validators work. - Custom validators are not called for
nulland receive the typed value. Add.required()wherenullmust fail. Custom validators. customWithSchemaoutside a schema runs with emptySchemaDatainstead of passing automatically.- List element errors are per element, at
items.1, not one message for the list. Map value errors sit atscores.key; key errors areinvalidKeyissues atscores. Errors and error paths. - Object-level errors from
.custom()on a schema are at'', not mixed into field errors. getErrornever throws and returnsnullfor a path that holds nested errors.withNamereturns a copy and no longer renames the receiver. Call it on the validator, not onl.l.nullValue()has no.required().- Recursive schemas validate every level. Input that used to pass because nested levels were skipped may now fail.
forwardRef(). - Deep input fails with
tooDeeppastl.maxDepth, default 512. Max depth. - Stricter formats.
dateTime()rejects impossible dates and the basic format;uri()requires a scheme;emoji()rejects arrows and punctuation;cuid()is anchored at the start;ip()matches the whole string and accepts::1. See each modifier’s reference page. l.file()is structural.File,TypedData,ByteBuffer,List<int>andStream<List<int>>pass; a class named like a file does not. Useaccept:for package types.l.file().- Default messages changed in places:
must be a mapis lowercase, the regex message names the pattern, and list messages no longer say “or does not match the validations”. Error messages. - Generated enums validate. An enum field used to be unsupported; it now generates
l.oneOf()of the serialized values. @IsFileworks on any field type, including package classes such asMultipartFileand lists of them, withaccept:receiving the whole value.- Generated annotation order follows source order.
@HasMin(8) @HasMax(200)generates.min(8).max(200). - Generation fails for
freezedunions, generic models, and annotations on a field type they do not apply to. These used to generate code that skipped validation. doublefields still generatel.double(), which rejects JSON integers. Type the field asnumif your API may send1for1.0. Supported field types.
Removed
Section titled “Removed”Validation, the concrete *Validation classes, and the internal members validations, schemaValidation, hasRequiredValidation, setSchemaDataForValidations, validateValueWithFieldName and validateSchemaWithFieldName are no longer exported. luthor_generator’s internals moved under lib/src; package:luthor_generator/builder.dart and package:luthor_generator/luthor_generator.dart are the public entry points.