Skip to content

Release 3.0.0: per-operation result types - #12

Merged
ifmelate merged 30 commits into
masterfrom
feat/3.0
Oct 21, 2026
Merged

ifmelate merged 30 commits into
masterfrom
feat/3.0

Conversation

@ifmelate

Copy link
Copy Markdown
Owner

Release 3.0.0: result classes follow the selections of each operation.

  • result_types: operation (new default): one class per selection with only the selected fields, aliases, merged selections, @skip/@include nullability
  • Interfaces and unions become sealed classes (<Base>_On<Type>, <Base>_Other)
  • Fragments become interfaces in fragments.dart, with <Fragment>Data, documents and read<F>Fragment / write<F>Fragment
  • Every class has fromJson, toJson, deep ==/hashCode and a typed copyWith; write<Op> takes the typed result
  • types.dart in operation mode: hand-written immutable input classes, no json_serializable
  • New checks: reserved __ aliases (BLD107), duplicate top-level names across operations (BLD108)
  • Removed the APIs deprecated in 2.x
  • result_types: schema keeps the 2.x output

Migration: MIGRATION.md. Details: CHANGELOG.md.

Remove GraphQLCodeGenerator.generateCode, the unused OperationAnalyzer,
SchemaAnalyzer and TypeGenerator helpers marked deprecated in 2.x, and
imports left unused by the removal.
…ypes

With result_types: operation, types.dart no longer declares classes for
object types, interfaces and unions, and input classes are written without
json_serializable: const constructor, final fields, fromJson/toJson (null
fields left out unless include_null_inputs), deep ==/hashCode and a typed
copyWith that can set null. Schema result types keep the 2.x output.
Tests asserting object, interface and union classes or json_serializable
annotations now run with result_types: schema, so they keep covering it.
The builder test checks that operation result types write no result
classes and no part directive.
types.dart with result_types: operation, alone, in strict, legacy,
include_null_inputs, unknown_enum_fallback and scalar_mapping setups:
toJson, fromJson round trip, deep equality, copyWith setting null, enums
and escaped names. Existing checks keep schema result types.
With result_types: operation, operation files declare classes with
exactly the selected fields: sealed classes with per-type subclasses
and _Other for interfaces and unions, fragment interfaces, fromJson,
toJson, ==, hashCode and a typed copyWith. write<Op> takes the typed
result. Schema mode keeps the 2.x output.
# Conflicts:
#	test/comprehensive_graphql_test.dart
#	test/generated_code_compiles_test.dart
#	test/operation_types_test.dart
An alias named __typename on another field clashed with the typename field the generator adds. The document validator now reports aliases starting with "__" as reserved, and with validate_documents: false the operation classes builder throws a BLD107 CodegenException for an aliased __typename.
Fragments such as "fragment FullType on __Type" are only spread inside __schema / __type selections, which stay raw JSON maps. They no longer fail the build with BLD107; fragments.dart leaves them out and is not written when no other fragment is left.
fragments.dart gets an extension <Fragment>FragmentExtension on GraphQLClient per fragment. read<Fragment>Fragment returns the <Fragment>Data class (null when not cached); write<Fragment>Fragment takes the fragment interface, so objects returned by any operation spreading the fragment can be written. On object types __typename defaults to the type condition; on interfaces and unions it is required on read and taken from data.typename on write.
topLevelDeclarations lists the public top-level names of generated code, before or after dart format. generateFragmentsFile uses it to report constants and extensions declared twice (fragments userBits and UserBits both declare userBitsFragment) instead of writing a file that does not compile.
Operation A_B field c and operation A path b.c both generate class A_B_C, which broke index.dart. The builder keeps the names each operation file declares (loaded from the output directory once, updated as files are generated) and fails with BLD108 naming both operations, their documents and the shared names. Clashes with fragments.dart (operation UserBitsFragment vs fragment UserBits) are reported too. Entries of operations no longer defined in their document are ignored.
Describe result classes, sealed classes for interfaces and unions, fragment interfaces, typed cache helpers and immutable inputs; add result_types to the options; keep schema mode as a short section; require Dart 3 and ^3.0.0.
@ifmelate
ifmelate merged commit 15e0cd4 into master Oct 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant