lucid_validation 0.0.6 copy "lucid_validation: ^0.0.6" to clipboard
lucid_validation: ^0.0.6 copied to clipboard

A Dart/Flutter package for building strongly typed validation rules inspired by FluentValidation and created by the Flutterando community.

LucidValidation #

LucidValidation is a pure Dart package for building strongly typed validation rules, inspired by FluentValidation. Created by the Flutterando community, this package offers a fluent and extensible API for validations, both in frontend (with Flutter) and backend applications.

Features #

  • Strongly typed validation rules.
  • Fluent API for defining validations.
  • Extensible with custom validators.
  • Consistent usage across backend and frontend (Flutter).

Installation #

Execute a pub.add command:

dart pub add lucid_validation

Basic Usage #

First, make a model:

class UserModel {
  String email;
  String password;
  int age;

  UserModel({
    required this.email,
    required this.password,
    required this.age,
  });

}

After that, create a LucidValidator class and extends to LucidValidator:

import 'package:lucid_validation/lucid_validation.dart';

class UserValidator extends LucidValidator<UserModel> {
  UserValidator() {
    ruleFor((user) => user.email, key: 'email')
        .notEmpty()
        .validEmail();

    ruleFor((user) => user.password, key: 'password') //
        .notEmpty()
        .minLength(8, message: 'Must be at least 8 characters long')
        .mustHaveLowercase()
        .mustHaveUppercase()
        .mustHaveNumbers()
        .mustHaveSpecialCharacter();

    ruleFor((user) => user.age, key: 'age')
        .min(18, message: 'Minimum age is 18 years');
  }
}

Now, just validate!


void main() {
  final user = UserModel(email: 'test@example.com', password: 'Passw0rd!', age: 25);
  final validator = UserValidator();

  final errors = validator.validate(user);
  
  if (errors.isEmpty) {
    print('User is valid');
  } else {
    print('Validation errors: \${errors.map((e) => e.message).join(', ')}');
  }
}

Note, the validate method returns a list of errors with all validation exceptions.

Available Validations #

Here’s a complete list of available validators you can use:

  • must: custom validation.
  • mustWith: custom validation with entity.
  • equalTo: checks if value is equal to another value.
  • greaterThan: Checks if number is greater than minimum value.
  • lessThan: Checks if the number is less than max value.
  • notEmpty: Checks if a string is not empty.
  • matchesPattern: Checks if the a string matches the pattern (Regex).
  • range: Checks whether a number is within the range of a minimum and maximum value.
  • validEmail: Checks if a string is a valid email address.
  • minLength: Checks if a string has a minimum length.
  • maxLength: Checks if a string does not exceed a maximum length.
  • mustHaveLowercase: Checks if a string contains at least one lowercase letter.
  • mustHaveUppercase: Checks if a string contains at least one uppercase letter.
  • mustHaveNumbers: Checks if a string contains at least one number.
  • mustHaveSpecialCharacter: Checks if a string contains at least one special character.
  • min: Checks if a number is greater than or equal to a minimum value.
  • max: Checks if a number is less than or equal to a maximum value.
  • isNull: Checks if a value is null.
  • isNotNull: Checks if a value is not null.
  • isEmpty: Checks if a string is empty.
  • validCPF: Checks if a string is a valid CPF (for use in Brazil).
  • validCNPJ: Checks if a string is a valid CNPJ (for use in Brazil).
  • validCEP: Checks if a string is a valid CEP (for use in Brazil).
  • validCredCard: Checks if a string is a valid Credit Card.

Usage with Flutter #

If you’re using the lucid_validation package in a Flutter app, integrating with TextFormField is straightforward.

Use the byField(entity, 'key') for this:

import 'package:flutter/material.dart';
import 'package:lucid_validation/lucid_validation.dart';

class LoginForm extends StatelessWidget {
  final validator = CredentialsValidation();
  final credentials = CredentialsModel();

  @override
  Widget build(BuildContext context) {
    return Form(
      child: Column(
        children: [
          TextFormField(
            decoration: const InputDecoration(hintText: 'Email'),
            validator: validator.byField(credentials, 'email'),
          ),
          TextFormField(
            decoration: const InputDecoration(hintText: 'Password'),
            validator: validator.byField(credentials, 'password'),
            obscureText: true,
          ),
        ],
      ),
    );
  }
}

Cascate Mode #

CascadeMode in LucidValidation controls the behavior of rule execution when a validation failure occurs for a property. By default, the validation rules continue to execute even if a previous rule for the same property fails. However, you can change this behavior using the CascadeMode.

Available Modes #

CascadeMode.continueExecution (Default): All validation rules for a property are executed, even if one fails. This mode is useful when you want to collect all validation errors at once.

CascadeMode.stopOnFirstFailure: Stops executing further validation rules for a property as soon as a failure is detected. This is useful when you want to prevent unnecessary validation checks after an error has been found.

You can apply CascadeMode to your validation chain using the cascaded method:

 return notEmpty() //
        .cascade(CascadeMode.stopOnFirstFailure); // change cascade mode

        .minLength(5, message: 'Must be at least 8 characters long')
        .mustHaveLowercase()
        .mustHaveUppercase()
        .mustHaveNumbers()
        .mustHaveSpecialCharacter()

Creating Custom Rules #

You can easily extend the functionality of LucidValidation by creating your own custom rules using extensions. Here’s an example of how to create a validation for phone numbers:

extension CustomValidPhoneValidator on LucidValidationBuilder<String, dynamic> {
  LucidValidationBuilder<String> customValidPhone({String message = 'Invalid phone number format'}) {
    return matchesPattern(
      r'^\(?(\d{2})\)?\s?9?\d{4}-?\d{4}\$',
      message,
      'invalid_phone_format',
    );
  }
}

extension CustomValidPasswordValidator on LucidValidationBuilder<String, dynamic> {
  LucidValidationBuilder<String> customValidPassword() {
    return notEmpty()
        .minLength(8)
        .mustHaveLowercase()
        .mustHaveUppercase()
        .mustHaveNumbers()
        .mustHaveSpecialCharacter();
  }
}

Use directly!


 ruleFor((user) => user.password, key: 'password')
        .customValidPassword();

Contributing #

Feel free to open issues or pull requests on the GitHub repository if you find any issues or have suggestions for improvements.

License #

This package is available under the MIT License. See the LICENSE file for more details.

9
likes
0
pub points
51%
popularity

Publisher

verified publisherflutterando.com.br

A Dart/Flutter package for building strongly typed validation rules inspired by FluentValidation and created by the Flutterando community.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

More

Packages that depend on lucid_validation