codec_gen 0.10.0
codec_gen: ^0.10.0 copied to clipboard
Code generator for the codec package: reads @Codable / @CodecEnum annotations and generates type-safe JSON codec fields with $.path error locations, via build_runner.
Changelog #
0.10.0 #
Changed #
- Widen the generator compatibility window while keeping the public Dart SDK
floor at
^3.6.0:analyzer >=6.9.0 <14.0.0,args >=2.5.0 <3.0.0,build >=2.4.2 <5.0.0,source_gen >=2.0.0 <5.0.0,dart_style >=2.3.7 <4.0.0,build_runner >=2.4.15 <3.0.0, andbuild_test >=2.2.3 <4.0.0, with Dart 3-compatiblefile ^7.0.1andfrontend_server_client ^4.0.0build-tool floors. - Add analyzer/source_gen compatibility boundaries so generator logic can run across the Dart 3.6-compatible stack and modern analyzer 13/source_gen 4 stacks without changing annotation syntax or generated codec semantics.
- Add an
args >=2.5.0floor to avoid build_runner 2.x command-line API compilation failures when downstream projects resolve downgraded dependency graphs. - Keep downstream fixtures on Dart 3-compatible
fileandfrontend_server_clientlines so lowest-stack build_runner validation does not resolve pre-Dart-3 tool packages. - Expand the downstream compatibility matrix with a registry-driven
modern_build_stackfixture covering schema, enum value fields, and sealed union generation.
Fixed #
- Escape JSON Schema
$refand$defskeys/values in generated Dart code so schema-enabled generated files compile under build_runner.
Not yet supported #
- analyzer 14, build 5, source_gen 5, and build_runner 3 remain outside the supported window until their upstream constraints and generated output are explicitly validated.
0.9.1 #
Fixed #
- Restore the public Dart SDK lower bound to
^3.6.0so Dart 3.6+ users can resolvecodec_genagain. - Move the generator dependency window back to the Dart 3.6-compatible stack:
analyzer >=6.9.0 <8.0.0,build >=2.4.2 <2.5.0,source_gen ^2.0.0,dart_style >=2.3.7 <3.1.0,build_runner >=2.4.15 <2.5.0, andbuild_test ^2.2.3.
0.9.0 #
Changed #
- Raise the
codec_gengenerator Dart SDK lower bound from^3.11.0to^3.12.0as the next staged compatibility step. - Keep the direct
analyzerlower bound at^13.3.0; analyzer14.0.0is currently blocked bysource_gen 4.2.3andbuild 4.0.6, which both still declareanalyzer <14.0.0.
Release #
- Keep
codec_genversioning independent fromcodec; this release does not require a newer runtime API and keeps the runtime compatibility range broad.
No generator semantic changes.
0.8.0 #
Changed #
- Raise the
codec_gengenerator Dart SDK lower bound from^3.10.0to^3.11.0as the next staged compatibility step. - Raise the direct
analyzerlower bound from^13.0.0to^13.3.0, the analyzer 13 line that requires Dart^3.11.0. - Keep
source_genat^4.2.3andbuildat^4.0.6; both still declareanalyzer <14.0.0, so analyzer 14 belongs to a later staged release.
Release #
- Keep
codec_genversioning independent fromcodec; this release does not require a newer runtime API and keeps the runtime compatibility range broad.
No generator semantic changes.
0.7.0 #
Changed #
- Raise the
codec_gengenerator Dart SDK lower bound from^3.9.0to^3.10.0as the next staged compatibility step. - Raise the direct
dart_stylelower bound from^3.1.2to^3.1.9, the formatter line that supports Dart^3.10.0while depending onanalyzer ^13.0.0. - Keep the direct
analyzerlower bound at^13.0.0; analyzer13.3.0and14.0.0require Dart^3.11.0and belong to a later staged release.
Release #
- Keep
codec_genversioning independent fromcodec; this release does not require a newer runtime API and keeps the runtime compatibility range broad.
No generator semantic changes. Existing generated part files may be reformatted by the Dart 3.10-compatible formatter stack.
0.6.0 #
Changed #
- Raise the
codec_gengenerator Dart SDK lower bound from^3.6.0to^3.9.0, matching the currentsource_gen 4.2.3support window. - Raise the direct
analyzerlower bound to^13.0.0, the analyzer 13 line that still supports Dart^3.9.0. - Raise the direct
dart_stylelower bound from^3.0.0to^3.1.2, matching the formatter range required by the current generator stack. - Raise the
build_runnerdev lower bound to^2.15.0, matching the current build 4 / source_gen 4 validation stack. - Add
frontend_server_client: ^4.0.0to the test toolchain floor so lowest dependency validation does not select the pre-Dart-3 frontend client.
Release #
- Keep
codec_genversioning independent fromcodec; this release does not require a newer runtime API and keeps the runtime compatibility range broad.
No generator semantic changes. Existing generated part files may be reformatted by the Dart 3.9-compatible formatter stack.
0.5.0 #
Documentation #
- Add coding-agent guidance for generated model integration, including annotation selection, stable generated entry points, schema exposure, and downstream validation commands.
- Expand example navigation with source and regression-test mappings for aliases, enum wire values, generic models, JSON Schema, and discriminated union codegen.
Release #
- Add workspace release tooling to keep
codec_gen, its hostedcodecdependency constraint, example constraints, README snippets, and changelogs aligned before tag-driven publishing.
No generator output changes.
0.4.0 #
Added #
- Add automatic codegen support for Dart core types including
Uri,BigInt,Duration, andSet<T>. - Add decode-only field aliases with
@CodecField(aliases: [...]). - Add generic
@Codablecodec factories for models such asPage<T>. - Add generated JSON Schema output with
@Codable(createJsonSchema: true), including$defs/$ref, generic type substitution, enum wire values, typed defaults, and same-name definition conflict handling. - Add discriminated union codegen with
@CodecUnion/@CodecUnionCase, generating runtimeCodec.discriminated(...)codecs and optionaloneOfschemas.
Fixes #
- Preserve explicit
List/Maptype arguments when emitting default value literals, avoiding analyzer inference warnings in generated schema constants.
Documentation #
- Expand README coverage for generated output shape, generic models, discriminated unions, JSON Schema inference, and example regression coverage.
0.3.1 #
Fixes #
- Support safer
@CodecIgnore/@CodecField(ignore: true)handling for constructor parameters by failing generation for required ignored parameters that cannot be omitted safely. - Preserve valid optional ignored named parameters with defaults.
- Bump the
codecdependency and installation snippets to^0.3.1.
0.3.0 #
- Global
field_renamebuild option: setfield_renameinbuild.yaml(none/snake/kebab/pascal/camel/screamingSnake) to apply a project-wide default field-rename strategy.@Codable(fieldRename: ...)still overrides per class; an explicitFieldRename.noneopts a class back out of the global default. Requirescodec≥ 0.3.0 (Codable.fieldRenameis now nullable).
0.2.1 #
- Maintenance release: version alignment with
codec0.2.1. No changes to the generated code or public API.
0.2.0 #
Dependency Upgrades #
- analyzer 13 / build 4 / source_gen 4 / build_test 3: Migrated to the new
analyzer element model (
Element2/LibraryElement2and related interfaces), aligning with the Dart SDK 3.6+ toolchain. codecdependency bumped to^0.2.0: Matches the runtime exception system refactor (CodecExceptionas a standalone type,withFormatExceptions()combinator).
Added #
build.yamloptionexception_style(codec|format, defaultcodec): When set toformat, every top-level codec (_$xxxCodec) generated by this builder automatically has.withFormatExceptions()appended, sodecode/encodethrow Dart's built-inFormatExceptioninstead ofCodecException. This provides a zero-touch migration path for existing code that catcheson FormatException, with no changes required at call sites.
0.1.6 #
Added #
@CodecField(enumValueField:)supportsunknownEnumValue:: Declare a fallback enum value for unrecognised codes. The generated top-level helper emitsCodec.enumOf<E, V>(..., unknownFallback: E.xxx). When omitted the parameter is not emitted, keeping generated code and behaviour identical to 0.1.5 (fully backward-compatible). Runtime support is provided by codec 0.1.6.
Codegen-time validation (new error paths) #
unknownEnumValueset withoutenumValueField(including cases where the field is overridden bycodec:) throwsInvalidGenerationSourceErrorduringbuild_runner; it is never silently ignored.unknownEnumValuewhose enum type does not match the field's enum type throwsInvalidGenerationSourceError, preventing the generation of code that would not compile.
Tests #
- Added 3 generator golden tests:
enumValueField+unknownEnumValueproducingunknownFallback:, standaloneunknownEnumValuethrowing, and mismatched enum type throwing. Total codec_gen test suite: 64 cases.
Version #
- Generator code changed;
versionbumped 0.1.5 → 0.1.6, aligned with CHANGELOG and codec 0.1.6.
0.1.5 #
Added #
- Field-level
@CodecField(enumValueField: 'code'): Maps an enum field by the value of a named property on each enum instance. The enum does not need@CodecEnum(keeping core/domain layers free of codec imports and part files). Mirrors the existingdateTime:pattern — declarative field-level codec selection without writing a top-level codec or acodec: '...'string. Priority:codec>enumValueField>dateTime> inferred from type. - Generation:
CodableGeneratoremits a top-level helper codec_$<ClassName><FieldName>EnumCodec = Codec.enumOf<E, V>(...)referenced by the field. The top-levelfinalis constructed only once, avoiding inline reconstruction of the (non-const) mapping map on every encode/decode call. Helpers are named by class name + field name to prevent top-level name collisions when multiple@Codableclasses in the same file reference the same enum. naming.dartaddsupperFirst(used when assembling helper variable names).
Behaviour change (generated code format) #
- Codec part files are now formatted with an extra-wide page width
(
SharedPartBuilderpasses a customformatOutputusingDartFormatter(pageWidth: 1 << 16)). Structural blocks inside a codec part (Codec.object/ constructor / encode map / enum mapping map) already carry trailing commas that drive line breaks; individual reader calls are single-line expressions. Long type or field names caused reader calls to be soft-wrapped at 80 columns without a trailing comma, triggering the host project'srequire_trailing_commaslint. With the widened page width, soft wrapping no longer occurs and that lint is truly avoided at the source, without needingignore_for_filein the consumer'sbuild.yaml.
Codegen-time validation (new error paths) #
@CodecField(enumValueField:)applied to a non-enum field, an enum that has no such property, or a target property whose type is notint/String/double/numthrowsInvalidGenerationSourceErrorduringbuild_runner, never deferring the error to runtime.
Tests #
- Added 5 generator golden tests:
int/Stringvalue-field mapping with helper reference, helper name uniqueness when multiple@Codableclasses in the same file reference the same enum, non-enum field error, and illegal value-field type error.codable_generator_test.dart: 14 → 19 cases.
0.1.4 #
Behaviour change (generated code) #
- All field reader calls now emit explicit type arguments:
b.required<T>(...)/b.optional<T>(...)/b.optionalOr<T>(...)always include the type parameter; the Dart compiler's inference from constructor parameters is no longer relied upon. Rationale: the built-inCodec.anyisCodec<Object?>, andTitself carries nullability information. When assigned to anObject?-typed field, the compiler inferredT=Object(dropping nullability), causing a type mismatch against theCodec<Object?>argument and a compile error. Explicit type arguments permanently fix this inference ambiguity, and any future nullableTcodec will not hit the same issue. CodecResolver.resolveinterface change: return type changed fromString(a codec expression) to({String expr, String typeArg}). ThetypeArgfield carries the string representation ofTfor that codec; the generator injects it directly as the explicit type argument. In nestedList<T?>/Map<String, V?>scenariostypeArgandexprkeep element nullability in sync.
Tests #
- Impact: re-running
build_runner build --delete-conflicting-outputsregenerates all*.g.dartfiles;fvm flutter analyzeon the host project confirmed zero regressions. - New generator golden tests (
test/codable_generator_test.dart, 14 cases): usesbuild_test'sresolveSourcesto obtain aLibraryElement, then callsCodableGenerator.generateForAnnotatedElementdirectly and asserts on the output string. Locks down the explicit type argument shape for primitives /Object?/dynamic/ nestedList/Map/ enum / dateTime / custom codec / nullable+required combinations — sub-second feedback; regressions in generated code no longer require a fullbuild_runnerre-run + analyze to surface. build_test: ^2.2.0added todev_dependencies.
Historical debt #
pubspec.yamlversionfield backfilled from the stale0.1.0to0.1.4in one step, aligned with CHANGELOG. The same version drift existed in the codec runtimepubspec.yamlbut was not touched here (left as a separate cleanup task).
Build / workspace #
- Joined pub workspace: this package's
pubspec.yamladdsresolution: workspace; the root project lists this package underworkspace:. Test files'package:test/test.dartimports are now resolved by the root analyzer without false errors. - SDK lower bound raised:
^3.4.0→^3.6.0(required by pub workspace). - Removed sub-package
dependency_overrides: previously pinnedanalyzer 7.3.0/analyzer_plugin 0.12.0; workspace mode allows overrides only at the root, and the rootpubspec.yamlalready declared the same values, so removal has no effect. lintsdowngraded to^4.0.0: compatible with the root project'sflutter_lints ^4.0.0joint resolution..gitignoreappendsbuild/: sub-packageflutter testproduces hundreds of asset files that should not be committed.
0.1.3 #
Added #
DateTimeMode.millisUtc/DateTimeMode.secondsUtc: dispatches to the newCodec.dateTimeMillisUtc/Codec.dateTimeSecondsUtc. For backends that send millisecond (or second) timestamps where time-zone correctness matters — decodes to aDateTimewithisUtc=true, encodes back to a number; fully symmetric.
0.1.2 #
Added #
@CodecIgnore()shorthand annotation: equivalent to@CodecField(ignore: true); shorter and more prominent for single-field skip use cases.FieldRename.screamingSnake:userName→USER_NAME, for interoperability with Java/Spring backends that use SCREAMING_SNAKE_CASE for enums and constants.@CodecField(dateTime: DateTimeMode.local/utc/seconds): lets the newCodec.dateTimeUtc/Codec.dateTimeSecondsbe selected via annotation without writing acodec: 'Codec.dateTimeUtc'string reference.@CodecField(defaultValue: ...)supports constList/ constMap: nested literals are also supported via recursive parsing. Unsupported element or key/value types raise an explicit codegen error.
Fixes #
- Field-level
CodecField.includeIfNullimplemented: fulfils the semantics already documented in dartdoc. The generator buckets fields separately — fields that keepnullare emitted directly; fields that omitnulluse a Dart map literalifelement:if (v.x != null) 'x': codec.encode(v.x!). The class-levelomitNullscall is no longer emitted by codec_gen (retained for hand-written codecs).
0.1.1 #
Fixes #
- String literal escaping:
@CodecField(defaultValue:)and@CodecValuevalues containing'/\/$/\n\r\t/ Unicode characters no longer cause compile errors from raw string concatenation in the generated code. AddeddartStringLiteralutility function. FieldRename.snake/kebab/pascalconsecutive-uppercase word splitting:userID→user_id,URLPath→url_path,userIDValue→user_id_value. The original algorithm only detected lower→upper boundaries; it missed the boundary between a consecutive-uppercase run and a following lowercase letter (behaviour now aligned with Lodash / inflection and similar libraries; a purely consecutive-uppercase sequence with no embedded lowercase is still treated as a single word).@CodecEnumwith only partial@CodecValuecoverage rejected at codegen time: previously the generated mapping omitted values and only threwEncodeExceptionat runtime on encode; nowInvalidGenerationSourceErroris raised during generation, listing the unannotated values.
Tests #
- First unit tests (previously 0): 36 cases covering
renameFieldedge cases,lowerFirst,dartStringLiteralescaping order and Unicode, and full-coverage validation for@CodecEnum.
0.1.0 #
- Initial release:
@Codable/@CodecEnumannotations trigger codegen, generating top-level_$xxxCodecconst/final fields. - Automatic field-type resolution: primitives / nullable / default values /
List/Map<String, V>/ nested models (must carry@Codable) / enums (default inline.name;@CodecEnumuses a shared codec) / self-references (automatically usesCodec.lazy). - Field-level escape hatch
@CodecField(codec: 'xxx')for arbitrary complex scenarios. @Codable(includeIfNull: false)class-level control:toJsonautomatically appends.omitNulls.