Skip to content

3.4.0: add_id_fields, scalar functions, migrate from Artemis and graphql_codegen - #18

Merged
ifmelate merged 9 commits into
masterfrom
feat/migrate
Nov 6, 2026
Merged

ifmelate merged 9 commits into
masterfrom
feat/migrate

Conversation

@ifmelate

@ifmelate ifmelate commented Nov 6, 2026

Copy link
Copy Markdown
Owner

3.4.0: add_id_fields, and moving over from Artemis or graphql_codegen

add_id_fields: true

Selects id on every object type and interface with a scalar id, the way __typename is added, in the sent documents and the result classes (in unions, inside ... on Type).

Without id, package:graphql's normalized cache keeps an object only inside the result that returned it. Checked with a fake server that returns only the selected fields:

without the option with it
mutation rename { name }, then read another query of that user old name new name
read<Fragment>Fragment({'id': '2'}) for an object a query returned null the data

Documents stay valid:

  • A selection where another field is aliased id (directly, in an inline fragment or in a spread fragment) doesn't get id. If a fragment spread there would get id itself, the build fails with the new BLD109.
  • Types that share a union or interface with a type whose id has another type (ID! vs Int!) get no id.

Both rules depend only on the schema and the fragment definitions, so a fragment has the same fields in fragments.dart and in every operation. Rewritten documents were checked with graphql-js validate.

The README said a missing id could cause CacheMissException. That doesn't happen with package:graphql 5.2, so the README now describes what does go wrong.

scalar_mapping with from_json / to_json

Two top-level functions, the way Artemis and graphql_codegen configure scalars. types.dart wraps them in a <Scalar>FunctionsConverter. Works in both result modes, for _-prefixed scalars (Hasura's _text), for built-in scalars, and for functions with nullable types.

dart run flutter_graphql_codegen:migrate

Writes graphql_codegen.yaml from the Artemis or graphql_codegen options in build.yaml: schema, documents, output, scalars with their functions (Artemis coercers as defined in the parser file), enums, widgets and hooks. It lists what it can't carry over and stops on several schemas.

Checked on the Artemis graphbrainz and graphql_codegen example projects: both build with this generator, analyze clean, and their scalars go through their own functions both ways.

MIGRATION.md has "Coming from Artemis" and "Coming from graphql_codegen", with the names side by side. The names were checked against the code their examples generate.

Checks

  • dart test: 434 tests pass, including the compile-tagged ones.
  • dart analyze --fatal-infos: no issues.
  • dart format --set-exit-if-changed: no changes.
  • dart pub publish --dry-run: 0 warnings.

Like __typename, id goes into the sent documents and the result classes, for object types and interfaces with a scalar id field without required arguments; in unions into the ... on Type selections. Fragments from fragment_imports keep their own package's setting. Persisted document ids and prune_types see the added fields.
package:graphql 5 doesn't throw CacheMissException for an object without id; checked against a server that returns only the selected fields. What breaks is mutations not updating other queries and fragment reads returning null.
types.dart declares a <Scalar>FunctionsConverter that calls them, so the functions Artemis and graphql_codegen users already have work without writing a JsonConverter.
…egen options

Reads the builder options in build.yaml: schema, documents, output, scalars with their functions, enums, widgets and hooks; lists what can't be carried over and stops on several schemas. Checked on the Artemis graphbrainz and graphql_codegen examples.
Names side by side, checked against the code their examples generate.
An id alias anywhere on the object (inline fragments, spreads) keeps id off it, and a fragment that would get id there fails with BLD109. Types that share a union or interface with a type whose id has another type get no id, so sibling ... on selections agree. Imported fragments follow the option too, which keeps their classes and persisted ids in line with the sent documents.
_text gets a public TextFunctionsConverter, ID and the other built-in scalars get their converter declared, and functions with nullable types (Artemis' ...Nullable... coercers) work.
Takes the coercer pair the parser file defines (plain or ...Nullable...), uses a single graphql_codegen scope, turns .gql globs into .graphql, refuses a builder configured differently in two targets, and notes enum types without an import and extra scalar imports. Docs describe the add_id_fields rules and BLD109.
@ifmelate
ifmelate merged commit 7992f42 into master Nov 6, 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