smart_mapper 0.2.0 copy "smart_mapper: ^0.2.0" to clipboard
smart_mapper: ^0.2.0 copied to clipboard

Compile-time Clean Architecture mapping annotations for DTOs, local models, and domain entities.

smart_mapper #

Focused object mapping for Clean Architecture boundaries. It generates small, plain Dart mappers between Remote DTOs, Local Models, and Domain Entities.

Setup #

Add runtime annotations and generator:

dependencies:
  smart_mapper: ^0.2.0

dev_dependencies:
  build_runner: ^2.16.0
  smart_mapper_generator: ^0.2.0

Define an abstract mapper. Same-name, assignable properties map automatically. Declare renames and converters explicitly:

import 'package:smart_mapper/smart_mapper.dart';

part 'user_mapper.g.dart';

@SmartMapper()
abstract class UserMapper {
  @MapField(
    target: 'name',
    source: 'fullName',
    using: 'normalizeName',
  )
  User map(UserResponse source);

  UserBox toLocal(UserResponse source);

  User fromLocal(UserBox source);
}

String normalizeName(String value) => value.trim();

Generate code:

dart run build_runner build

Use generated factory:

final mapper = createUserMapper();
final user = mapper.map(response);

Generated implementation stays intentionally boring: constructor calls, property reads, and explicit converter calls.

Strict validation #

Every direct assignment is checked with analyzer's type system. Invalid boundaries fail during generation instead of producing broken Dart:

Cannot assign String? to DateTime for Homework.dueDate.

Use a top-level converter when source and target types differ:

@MapField(target: 'createdAt', source: 'createdAt', using: 'parseDate')
Profile fromRemote(ProfileDto source);

DateTime parseDate(String value) => DateTime.parse(value);

Constructor controls #

@MapConstructor('fromDto')
@MapIgnore('id')
@MapDefault(target: 'status', value: 'active')
Profile fromRemote(ProfileDto source);

MapDefault accepts constant null, bool, numbers, strings, lists, sets, and maps.

Nested collections and ObjectBox ToMany #

Declare item mapping methods beside parent mapping methods:

@SmartMapper()
abstract class ScheduleMapper {
  Schedule fromRemote(ScheduleDto source);
  ScheduleItem itemFromRemote(ScheduleItemDto source);

  @MapRelation(
    target: 'monday',
    source: 'monday',
    using: 'itemToLocal',
  )
  ScheduleBox toLocal(Schedule source);
  ScheduleItemBox itemToLocal(ScheduleItem source);

  Schedule fromLocal(ScheduleBox source);
  ScheduleItem itemFromLocal(ScheduleItemBox source);
}

List, Set, and Iterable collections use matching item mappers. ObjectBox relations require @MapRelation; no relation is mutated implicitly. A target ToMany<TargetItem> field is populated after construction:

final target = ScheduleBox(group: source.group);
target.monday.addAll(source.monday.map(itemToLocal));
return target;

Missing or ambiguous item mapper methods fail during generation.

ObjectBox ToOne is also supported. Nullable targets remain nullable, with converter calls guarded against null.

Scope #

Version 0.2.0 supports synchronous methods with exactly one required positional source parameter and target types with an unnamed generative or factory constructor. Named constructors, nested List/Set/Iterable, nullable collections/items, and ObjectBox ToMany/ToOne relations are supported. Async and update-in-place mapping remain outside current scope.

0
likes
150
points
117
downloads

Documentation

API reference

Publisher

verified publisherpinz.dev

Weekly Downloads

Compile-time Clean Architecture mapping annotations for DTOs, local models, and domain entities.

Repository (GitHub)
View/report issues

Topics

#code-generation #clean-architecture #mapper #objectbox

License

MIT (license)

More

Packages that depend on smart_mapper