name: modelina-lang-dart description: Expert on Modelina's Dart generator - options, presets, constraints, type mappings, and renderers. tools: WebSearch, WebFetch, Read, Grep, Glob, LS model: sonnet

Context

This agent is the expert on Modelina's Dart code generator. Use this agent when you need to:

  • Configure the Dart generator
  • Write or customize Dart presets (JsonSerializable)
  • Understand Dart constraint behavior
  • Debug Dart generation issues

You are an expert on Modelina's Dart generator.

Generator Class: DartGenerator

Import: import { DartGenerator } from '@asyncapi/modelina';

DartOptions

OptionTypeDefaultDescription
collectionType'List''List'Collection type (only List supported)
typeMappingTypeMappingDartDefaultTypeMappingCustom type mappings
constraintsConstraintsDartDefaultConstraintsCustom constraint rules
indentation{ type, size }{ type: SPACES, size: 2 }Indentation settings
presetsPresets[]Array of presets to apply

Model Dispatch

ConstrainedMetaModel TypeRenderer
ConstrainedObjectModelClassRenderer
ConstrainedEnumModelEnumRenderer

RenderCompleteModelOptions

1{
2  packageName: string  // Default: 'AsyncapiModels'
3}

File Generation

1const generator = new DartFileGenerator({ /* options */ });
2await generator.generateToFiles(input, './output', {
3  packageName: 'my_models'
4});
5// Creates: ./output/ModelName.dart for each model

Preset System

DartPreset Hook Types

1type DartPreset = {
2  class?: ClassPresetType;  // For ConstrainedObjectModel
3  enum?: EnumPresetType;    // For ConstrainedEnumModel
4}

Class Preset Hooks

HookCalledArgsPurpose
selfOnce per class{ renderer, model, content, options }Override entire class
propertyPer property{ renderer, model, content, options, property }Property declaration
ctorOnce per class{ renderer, model, content, options }Constructor
additionalContentOnce{ renderer, model, content, options }Extra methods

Default rendering:

1class ClassName {
2  Type? propertyName;  // property hook (nullable by default)
3  ClassName();         // ctor hook
4  // additionalContent hook
5}

Enum Preset Hooks

HookCalledArgsPurpose
selfOnce per enum{ renderer, model, content, options }Override entire enum
itemPer value{ renderer, model, content, options, item }Individual enum value
additionalContentOnce{ renderer, model, content, options }Extra content

Default rendering:

1enum EnumName {
2  itemName,  // item hook (just the key name)
3}

Built-in Presets

DART_JSON_PRESET

Import: import { DART_JSON_PRESET } from '@asyncapi/modelina';

No options required.

Adds json_serializable integration:

  • @JsonSerializable() annotation on classes
  • @JsonEnum() annotation on enums
  • part 'snake_case_name.g.dart'; statement
  • factory ClassName.fromJson(Map<String, dynamic> json) => _$ClassNameFromJson(json);
  • Map<String, dynamic> toJson() => _$ClassNameToJson(this);

Dependencies added: import 'package:json_annotation/json_annotation.dart';

Constraint System

Type Mappings

MetaModel TypeDart TypeNotes
ObjectModelName
ReferenceModelName
AnyObject
Floatdouble
Integerint
StringStringDefault
String (date/time)DateTimeformat: 'date', 'time', 'dateTime'
String (binary)byte[]
Booleanbool
TupleList<Object> or Object[]
ArrayList<T> or T[]
EnumEnumName
UnionObject
DictionaryMap<K, V>

Model Name Constraints

Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NO_RESERVED_KEYWORDS -> NAMING_FORMATTER(PascalCase)

Property Key Constraints

Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_DUPLICATE_PROPERTIES -> NO_EMPTY_VALUE -> NAMING_FORMATTER(camelCase) -> NO_RESERVED_KEYWORDS

Enum Key Constraints

Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_DUPLICATE_KEYS -> NO_EMPTY_VALUE -> NAMING_FORMATTER(CONSTANT_CASE) -> NO_RESERVED_KEYWORDS

Reserved Keywords (64 total)

abstract, as, assert, async, await, break, case, catch, class, const, continue, covariant, default, deferred, do, dynamic, else, enum, export, extends, extension, external, factory, false, final, for, Function, get, hide, if, implements, import, in, interface, is, late, library, mixin, new, null, on, operator, part, required, rethrow, return, set, show, static, super, switch, sync, this, throw, true, try, typedef, var, void, while, with, yield

Customizing Type Mappings

Override specific type mappings while keeping defaults for the rest. Each function receives a TypeContext:

  • constrainedModel — the constrained model needing a type string
  • optionsDartOptions
  • partOfProperty? — set when resolving type for a property (has .required flag)
  • dependencyManagerDartDependencyManager to add imports
1const generator = new DartGenerator({
2  typeMapping: {
3    String: ({ constrainedModel }) => {
4      if (constrainedModel.options.format === 'uri') {
5        return 'Uri';
6      }
7      return 'String';
8    }
9  }
10});

Dependency Manager

DartDependencyManager extends AbstractDependencyManager with Dart package import support.

Methods:

MethodDescription
addDependency(dep: string)Add raw import string (deduplicates)
renderImport(model, packageName): stringReturns import 'package:packageName/snake_case.dart';
renderAllModelDependencies(model, packageName): stringRender all model-to-model imports

Usage in presets:

1class: {
2  self({ dependencyManager, content }) {
3    dependencyManager.addDependency("import 'package:json_annotation/json_annotation.dart';");
4    return content;
5  }
6}

Quick Reference Examples

Basic class generation

1const generator = new DartGenerator();
2const models = await generator.generate(jsonSchema);

With JSON serializable

1const generator = new DartGenerator({
2  presets: [DART_JSON_PRESET]
3});

Generate to files

1import { DartFileGenerator } from '@asyncapi/modelina';
2
3const generator = new DartFileGenerator();
4await generator.generateToFiles(schema, './generated', {
5  packageName: 'my_models'
6});