Dartz Plus Generator

A code generator that automatically creates mapping extensions between your data transfer objects (DTOs) and domain entities.

Features

  • Automatic Mapper Generation: Generate bidirectional mapping extensions with a single annotation
  • Type-Safe: Compile-time code generation ensures type safety
  • Customizable: Control whether reverse mapping is generated
  • Smart Field Resolution: Handles optional and nullable parameters intelligently
  • Inheritance Support: Works with class hierarchies by collecting fields from superclasses
  • No Runtime Dependencies: Pure code generation with no additional runtime dependencies

Installation

Add dartz_plus_generator as a dev dependency in your pubspec.yaml:

dev_dependencies:
  build_runner: ^2.10.4
  dartz_plus_generator: ^0.1.1

Then run:

flutter pub get

Usage

Basic Example

  1. Annotate your DTO class with @Mapper and specify the target entity type:
import 'package:dartz_plus_generator/annotations.dart';

part 'user_model.g.dart'; // Include the generated file

@Mapper(UserEntity)
class UserModel {
  final String name;
  final int age;

  UserModel({required this.name, required this.age});
}

class UserEntity {
  final String name;
  final int age;
  final String? email;

  const UserEntity(this.name, this.age, {this.email});
}
  1. Run the code generator:
dart run build_runner build
# or for watch mode
dart run build_runner watch
  1. The generator creates extension methods for mapping:
// Generated extension allows you to convert DTO to Entity
final model = UserModel(name: 'John', age: 30);
final entity = model.toUserEntity(); // UserEntity(name: 'John', age: 30)

// Reverse mapping is also generated by default
final backToModel = entity.toUserModel(); // UserModel(name: 'John', age: 30)

Controlling Reverse Mapping

By default, the generator creates bidirectional mappings. You can disable reverse mapping:

@Mapper(UserEntity, reverse: false)
class UserModel {
  // Only generates model.toUserEntity()
  // No reverse entity.toUserModel() method
}

How It Works

The generator:

  1. Analyzes the @Mapper annotation to identify the target type
  2. Matches fields between source and target classes by name
  3. Generates extension methods with to{TargetName}() methods
  4. Handles optional and nullable parameters intelligently:
    • Required parameters must have matching fields in the source
    • Optional/nullable parameters are skipped if no matching field exists

Example with Optional Fields

@Mapper(ProfileEntity)
class ProfileModel {
  final String id;
  final String name;

  ProfileModel({required this.id, required this.name});
}

class ProfileEntity {
  final String id;
  final String name;
  final DateTime? createdAt; // Optional field

  ProfileEntity({
    required this.id,
    required this.name,
    this.createdAt,
  });
}

// Usage
final model = ProfileModel(id: '123', name: 'Alice');
final entity = model.toProfileEntity(); // createdAt will be null

Generated Code Example

For the basic example above, the generator produces:

// user_model.g.dart
part of 'user_model.dart';

extension UserModelToUserEntityMapper on UserModel {
  UserEntity toUserEntity() {
    return UserEntity(
      name,
      age,
    );
  }
}

extension UserEntityToUserModelMapper on UserEntity {
  UserModel toUserModel() {
    return UserModel(
      name: name,
      age: age,
    );
  }
}

Requirements

  • Dart SDK: ^3.10.4
  • dartz_plus: Compatible version
  • build_runner: ^2.10.4 or higher

Build Configuration

The generator uses build.yaml for configuration. The default configuration:

builders:
  mapper:
    import: "package:dartz_plus_generator/builder.dart"
    builder_factories: ["mapperBuilder"]
    build_extensions: { ".dart": [".g.dart"] }
    auto_apply: dependents
    build_to: cache
    applies_builders: ["source_gen|combining_builder"]

Error Handling

The generator will throw helpful errors at build time if:

  • @Mapper is applied to a non-class element
  • Target type is not a class
  • Target class doesn't have a default (unnamed) constructor
  • Required parameters in the target constructor don't have matching fields in the source

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License.

Libraries

annotations
builder