Giter Site home page Giter Site logo

graphql_codegen's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

graphql_codegen's Issues

Multiple graphql schema

Does this library supports multiple schema?
I have a case in which the app uses two gql schemas (e.g. test1.schema.graphql, test2.schema.graphql) for two different endpoints.

Is there way to change the naming?

I want to know if it's possible to change the naming of the generated class, mainly the $ sign.

Because I want to re-use those classes not only for the graphql api call, for example those enums. But most generators will fail with a property whose name has a $.

How can i change the generation output folder?

I would like to customize the output folder for the generated files and could not find a configuration option so far. In my case the destination folder would be /lib/generated/graphql/.
Is there this possibility or a workaround for this?

Export fragment document

I am using graphql_flutter and there we can use dart client.writeFragment(fragmentRequest, data); but we need the fragment document.

Is it possible to export the document?

Mutate only provided fields and ignore fields with a NULL value

Behaviour:
If I want to update an existing object in a backend, it should only update the provided field and input values and ignore the NULL values. But also the NULL values will be applied too.

Examples:
Mutation:

mutation UpdatePlace($id: ID!, $input: update_places_input!) {
  update_places_item(id: $id, data: $input) {
    id
    status
    name
  }
}

Variables:

{
  "id": "7de55d8d-5ec5-4188-8a38-54e6938f60c1",
  "input": {
    "city": {
      "id": "617a9e1c-3cc5-499f-bbc0-68a904b8a97c"
    }
  }
}

Execution works with the Altair Client well. But not in Dart:

   final updatePlace = await _placeService.updateOnePlace(
     placeInput: Input$update_places_input(
       id: '7de55d8d-5ec5-4188-8a38-54e6938f60c1',
       status: 'published',
       name: 'Ein aktualisierter Standort2kk4',
       map_location: <String, dynamic>{
         'type': 'Point',
         //longtiude, latitude
         'coordinates': [10.055311, 53.564489]
       },
       city: Input$update_cities_input(
         id: '7de55d8d-5ec5-4188-8a38-54e6938f60c1',
       ),
     ),
   );
  final GraphQLClient _client;

  @override
  Future<Mutation$UpdatePlace$update_places_item?> updateOnePlace({
    required Input$update_places_input placeInput,
  }) async {
      final options = Options$Mutation$UpdatePlace(
        variables: Variables$Mutation$UpdatePlace(
          input: placeInput,
          id: placeInput.id!,
        ),
      );
      final result = await _client.mutate$UpdatePlace(options);
      if (result.hasException) {
        throw Exception(result.exception.toString());
      }
      return result.parsedData?.update_places_item;
    } 
  }

Expectation
Ignore the null values in fields and inputs and update only the provided values

Not provided optional values are returned as `null` in mutation

First of all thanks for this great library. I am migrating my Graphql code from the ferry package right now and the generated code here is a lot more straightforward and reusable.

I have the following mutation:

mutation CreateEmailInvites($invites: [invites_insert_input!]!) {
  insert_invites(objects: $invites) {
    returning {
      id
    }
  }
}

and using it with the generated client code for the graphql package like so:

_client.watchMutationCreateEmailInvites(
            GQLWatchOptionsMutationCreateEmailInvites(
              eagerlyFetchResults: true,
              variables: VariablesMutationCreateEmailInvites(
                invites: inviteInputs
                    .map(
                      (invite) => InputinvitesInsertInput(
                        inviteCode: invite.inviteCode,
                        email: invite.email,
                        inviterId: invite.inviterId,
                        name: invite.name,
                      ),
                    )
                    .toList(),
              ),
            ),
          )

Now the issue is that the Invites model in my graphql API has additional optional values that I am not passing along, but instead of omitting them the generated payload in the final request sets them to null:

{
  "operationName": null,
  "variables": {
    "invites": [
      {
        "created_at": null,
        "email":  "[email protected]",
        "id": null,
        "invite_code": "VIMtrBLA40",
        "invitee_id": null,
        "inviter_id": "886f91c3-4162-4391-a187-7cad9c9b666d",
        "name": "Johannes",
        "profile": null,
        "status": null
      }
    ]
  },
  "query": "mutation CreateEmailInvites($invites: [invites_insert_input!]!) {\n  insert_invites(objects: $invites) {\n    returning {\n      id\n      __typename\n    }\n    __typename\n  }\n  __typename\n}"
}

My graphql server rejects this request as null values are not allowed on these fields.

How can one send a partial insert or update request without including other fields as null values? Thanks a lot for your help.

Build fails with FormatException

Hi,

I am running the build command but somehow it keeps complaining about something. The error I get is:

FormatException: Invalid UTF-8 byte (at offset 0)
[SEVERE] graphql_codegen:graphql_codegen on lib/api/graphql/otp.graphql:

The file contents are (saved as txt to make github happy):
otp.txt

No generation for graphql_flutter client

It's the first time i'm using this package, somehow it doesn't generate the flutter widgets.
changing clients in build.yaml does generate outputs but they look the same.

build.yaml

targets:
  $default:
    builders:
      graphql_codegen:
        options:
          clients:
            - graphql
            - graphql_flutter

get_all_pokemons.graphql

query AllPokemons {
  pokemon_v2_pokemonspecies(order_by: {id: asc}) {
    name
    id
  }
}

get_all_pokemons.graphql.dart

import 'package:json_annotation/json_annotation.dart';
part 'get_all_pokemons.graphql.g.dart';

@JsonSerializable()
class QueryAllPokemons extends JsonSerializable {
  QueryAllPokemons(this.pokemon_v2_pokemonspecies);

  @override
  factory QueryAllPokemons.fromJson(Map<String, dynamic> json) =>
      _$QueryAllPokemonsFromJson(json);

  final List<QueryAllPokemons$fpokemon_v2_pokemonspecies>
      pokemon_v2_pokemonspecies;

  @override
  Map<String, dynamic> toJson() => _$QueryAllPokemonsToJson(this);
}

@JsonSerializable()
class QueryAllPokemons$fpokemon_v2_pokemonspecies extends JsonSerializable {
  QueryAllPokemons$fpokemon_v2_pokemonspecies(this.name, this.id);

  @override
  factory QueryAllPokemons$fpokemon_v2_pokemonspecies.fromJson(
          Map<String, dynamic> json) =>
      _$QueryAllPokemons$fpokemon_v2_pokemonspeciesFromJson(json);

  final String name;

  final int id;

  @override
  Map<String, dynamic> toJson() =>
      _$QueryAllPokemons$fpokemon_v2_pokemonspeciesToJson(this);
}

get_all_pokemons.graphql.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'get_all_pokemons.graphql.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

QueryAllPokemons _$QueryAllPokemonsFromJson(Map<String, dynamic> json) =>
    QueryAllPokemons(
      (json['pokemon_v2_pokemonspecies'] as List<dynamic>)
          .map((e) => QueryAllPokemons$fpokemon_v2_pokemonspecies.fromJson(
              e as Map<String, dynamic>))
          .toList(),
    );

Map<String, dynamic> _$QueryAllPokemonsToJson(QueryAllPokemons instance) =>
    <String, dynamic>{
      'pokemon_v2_pokemonspecies': instance.pokemon_v2_pokemonspecies,
    };

QueryAllPokemons$fpokemon_v2_pokemonspecies
    _$QueryAllPokemons$fpokemon_v2_pokemonspeciesFromJson(
            Map<String, dynamic> json) =>
        QueryAllPokemons$fpokemon_v2_pokemonspecies(
          json['name'] as String,
          json['id'] as int,
        );

Map<String, dynamic> _$QueryAllPokemons$fpokemon_v2_pokemonspeciesToJson(
        QueryAllPokemons$fpokemon_v2_pokemonspecies instance) =>
    <String, dynamic>{
      'name': instance.name,
      'id': instance.id,
    };

pubspec.yaml

name: pokedex
description: A new Flutter project.

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
  sdk: '>=2.18.0-109.0.dev <3.0.0'

dependencies:
  flutter:
    sdk: flutter


  cupertino_icons: ^1.0.2
  graphql_flutter: ^5.1.0
  json_annotation: ^4.5.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^2.0.0
  build_runner: ^2.1.10
  json_serializable: ^6.2.0
  graphql_codegen: ^0.0.1-alpha.1

flutter:

  uses-material-design: true

build_runner build output:

[INFO] Generating build script...
[INFO] Generating build script completed, took 284ms

[INFO] Initializing inputs
[INFO] Reading cached asset graph...
[INFO] Reading cached asset graph completed, took 48ms

[INFO] Checking for updates since last build...
[INFO] Checking for updates since last build completed, took 550ms

[INFO] Running build...
[INFO] Running build completed, took 14ms

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 29ms

[INFO] Succeeded after 51ms with 0 outputs (0 actions)

Use Freezed with unions

I know it would be a big chunk of work, but are there any thoughts about integrating freezed when dealing with unions, allowing the interface to be more exhaustive.

call from json from a object instance

The actual code generation generates only a factory method to create an object from the JSON.

I would like to ask if adding an object method to fill an instance from a JSON could be cool to have, it should be enabled code like the following one

Future<T> query<T extends JsonSerializable>({required QueryOptions query}) async {
    var response = await _client.query(query);
    if (response.hasException) {
      throw Exception(response.exception);
    }
    var result = newObject<T>();
    return result.fromJson(response.data!);
}

Path generation is broken with a custom outputDirectory [0.10.0-beta.3]

Hello,

It seems that there is a problem when generating certain imports with the latest beta version. [0.10.0-beta.3]

The generator created this :
import '../../../../../../repositories/my_schema/schema.graphql.dart';

But the correct one is this :
import '../../../../../../../repositories/kp_commodities/generated/schema.graphql.dart';

My config file :

graphql_codegen:
        options:
          outputDirectory: '__generated__'
          scopes:
            - lib/**/my_schema/**
          clients:
            - graphql
            - graphql_flutter
          namingSeparator: ''

Don't hesitate to reach me if you need more informations.

How can I handle List of Scalar

Thanks for the great library. I'm trying to migrate our use case from Artemis. May I know how to handle List of objects and Nullable case of the scalar?

For example, in my schema.graphql, I have a scalar of date. And in some cases, we need to use [date]!. Given the following build.yaml config, the generation outputs errors.

date:
    type: DateTime
    fromJsonFunctionName: fromGraphQLDateNullableToDartDateTimeNullable
    toJsonFunctionName: fromDartDateTimeNullableToGraphQLDateNullable
    import: package:app/data/model/scalar/graphql_scalar.dart

Errors from build_runner:
image

query on graphql client return an incomplete value

I really sorry if I'm writing another issue here, I'm testing some of my ideas and I'm using this library to generate the graphql query compatible with graphql client.

However, I'm not able to run a complex issue in the Github API, in particular, I'm running the following query but I got some null errors during the iteration over the response object.

These are two tests that make the same jobs, but only one works, more on the stack trace here

    test('run a query', () async {
      var rawClient = await makeRawClient(token: token!);
      var query = QueryOptions(document: gql(commitQuery), variables: {
        "owner": "vincenzopalazzo",
        "repo": "octokit.dart",
      });
      var response = await rawClient.query(query);
      var edges = response.data!["repository"]!["refs"]!["edges"]!;
      expect(edges.length, 1);
      edges.forEach((element) {
        expect(element["node"], isNotNull);
      });
    });

    test('run a query and decode the result in a Object', () async {
      var response = await client!.query(
          query: GQLOptionsQueryLastCommits(
              variables: VariablesQueryLastCommits(
                  owner: "vincenzopalazzo", repo: "octokit.dart")));
      var query = QueryLastCommits.fromJson(response);
      expect(query.repository!.refs!.edges!.length, 1);
      query.repository!.refs!.edges!.forEach((element) {
        expect(element!.node, isNotNull);
      });
    });

In this case, the following test assert fails

query.repository!.refs!.edges!.forEach((element) {
        expect(element!.node, isNotNull);
      });

graphql sdl with schema generates nothing

Given this graphql sdl:

type Mutation {
	user: UserMutation!
}

type Query {
	users: [User!]!
}

type User {
	id: String!
	name: String!
}

type UserMutation {
	doStuff: Int!
}

schema {
	query: Query
	mutation: Mutation
}

the generated file is:

const possibleTypesMap = {};

Any ideas what I'm doing wrong? This is a standard output from async-graphql (rust) and works fine in the playground.

Have auto-generated files pass dart analyzer cleanly

The official dart extension for vscode (and maybe other IDEs?) will only do auto-completion as you type for dart types that are included in the dart analyzer. If they are excluded from the dart analyzer, if you do type the full/correct type name, then it does recognize it still. However, since the auto-generated type names can be quite long, it's more productive to have these auto-completed. And currently if you do not exclude the auto-generated code from the analyzer, it adds lots of warnings to the IDE's list of problems (which I strive to keep at zero).

For the auto-generated files to pass the analyzer without adding warnings, the following could be generated at the top of each auto-generated file:

// ignore_for_file: constant_identifier_names, unnecessary_const
// ignore_for_file: unnecessary_this, annotate_overrides

(The code gen could be adjusted to fix the root cause of all but the first one of these; changing the identifier name pattern would be a breaking change and I personally like the auto-generated constants as they are (all upper separated by underscores)).

What do you think?

(P.S. thanks for adding client codegen for subscriptions, and for the query parseFn! those are working beautifully!!)

Generator always generates exact types instead of interfaces

In this example, a Condition is an interface. There are many implementations for it. Like AndCondition, OrCondition, TimeCondition, etc.

On top of that, AndCondition has left and right fields that are also Conditions.

Unfortunately, the generator currently generates FragmentAndCondition$left and FragmentAndCondition$right classes as you can see in the picture. However, I'd like it to use FragmentCondition classes instead here.

Is this currently possible?

image

fragment Condition on Condition{
type
}

fragment AndCondition on AndCondition{
...Condition
left {
...Condition
}
right {
...Condition
}
}

Dont Know How to use FetchMore Function for Posts with codegen

I have AllPosts query ,with Generated GQLFetchMoreQueryAllPosts function , I Get an UnImplemented Error: Please provide a parser function to support result parsing.
Without codegen i use like below

    fetchMore!(
        FetchMoreOptions(
           variables: {'endCursor': endCursor},
           updateQuery: (prev, moreRes) {
           final posts = [
              ...prev!['posts']['nodes']
                as List<dynamic>,
              ...moreRes!['posts']['nodes']
                as List<dynamic>
           ];
           moreRes['posts']['nodes'] = posts;
           return moreRes;
           },
        ),
      ),

build option to not add __typename to top-level selection set for subscriptions

First, I'm impressed and excited by this package! This is the only dart package I've come across that can actually successfully generate code from a GraphQL schema generated by Hasura -- these schemas are a bit more complex (supporting lots of operators, search conditions, methods for paging, etc) and it tripped up other dart gql code generators I've tried. Nicely done!

Also, even though it's not documented to work, it looks like it will actually parse and generate code for subscriptions! (not the client part yet, but that's OK). That was another happy surprise!

Hasura only supports one top-level field for subscriptions (for queries/mutations multiple top-level fields are fully supported without issue). In the Hasura schema, this top-level field would correspond to a table or view in the source database.

If you had some GraphQL like:

fragment Friend on ...

subscription ListenToFriends($user_id: String!) {
  user_friends(where: {user_id: {_eq: $user_id}}) {
    ...Friend
  }
}

Then with addTypename: true in build.yaml this will result in generated code with a SelectionSetNode that contains two FieldNodes -- one for user_friends and then another for __typename:

FieldNode(
            name: NameNode(value: '__typename'),
            alias: null,
            arguments: [],
            directives: [],
            selectionSet: null)

The other __typename fields that are automatically added are perfectly OK, if I manually remove this top-level __typename filed node from the generated DocumentNode, then the subscription is able to execute successfully. If the generated code is unmodified, then when the subscription is run, Hasura responds with this error message instead:

[{extensions: {path: $, code: validation-failed}, message: subscriptions must select one top level field}]

I don't know if this may be a problem common to other GraphQL server/subscription implementations. Arguably Hasura should recognize that __typename is not really trying to subscribe to a second field set, and I'll raise the issue there for consideration there.

I wanted to see if it made sense here to add another build.yaml option, something like omitTopLevelSubscriptionTypename: true (off by default?), that would tell the code generator to not add __typename just on the top-level of a subscription, so that the auto-generated code out of the box would work with Hasura subscriptions. Or perhaps this field might never be needed at the top-level for a subscription and could always be omitted potentially? What do you think?

Unable to compile for windows

Hi there!

Im trying to compare artemis with this package however when I tried to run with my own graphQL schema Ive noticed that the generated files have the wrong import for their json_serializeable counterparts.

For example:

image

The error generated basically says that the part directive should be the file name alone with no reference to the containing folder.

I know its a problem with the outputDirectory option because it can alter the import directive.

Note: when the outputDirectory isnt set it creates an even worse import:

image

I dont know your package well but basically the fix would be to remove all folders/to/this/file in the part directive and let json_serializeable do its thing.

Current Behaviour

bad imports seen above, compiled on windows

Expected behaviour

Import should be simply the file name

part "lib/./example.graphql.g.dart" -> part "example.graphql.g.dart"

Choosing output directory path for generated files

Motivation :

  • Generating files with graphql_codegen is easy & great as it finds where is located our schema.graphql without having to indicate it

What is less great is that all the generated Dart files get mixed up with our "original" .graphql files

Solution :

It would be nicer if the generated Dart files -> were generated in a sub-folder named gen or generated_graphql

Or being able to choose the output directory

[Question] How to mock QueryResult for unit test ?

Hi and thanks for the package !

I making some unit test for the graphql client and I would like to know how to mock the QueryResult when perform a query method. Let me explain why I'm block on this:

My test:

    test(
      'should checkEmailVerified',
      () async {
        // arrange
        when(() => graphqlClient.queryGetEmailVerified())
            .thenAnswer((_) async => {}); // HERE the return should be a `QueryResult<QueryGetEmailVerified>`
        // act
        final result = await datasource.checkEmailVerified();

        // assert
      },
    );

The source code:

  @override
  Future<bool> checkEmailVerified() async {
    try {
      final result = await graphQLClient.queryGetEmailVerified();
      if (result.parsedData != null) {
          return Future.value(result.parsedData?.me.emailVerified);
      }
  }

I can't find any good example to create the class mock to send to the thenAnswer. Can someone help me on that ?
I want to change the response data for example.

I can't do that for example, because the BaseOptions is private:

final tResult = QueryResult<QueryGetEmailVerified>(
          source: QueryResultSource.network,
          options: BaseOptions<QueryGetEmailVerified>() // HERE fail because private
        );

Generator not generates type objects, only enums and input

The generator finds graphql file, .g files are generated, but only contains enums and input types.
I tried debug the generator. I see types in graphql parsed as ObjectTypeDefinitionNode but ContextVisitor not implements visitObjectTypeDefinitionNode() for that.

Képernyőfotó 2022-05-24 - 14 45 03

Képernyőfotó 2022-05-24 - 14 44 23

Generating cache access methods for graphql client

I love using this library with the graphql package for safe type access.

When accessing and writing to the cache though I am largely left to working with untyped maps again. It would be great to generate the readQuery, writeQuery, readFragment and writeFragment with this package!

I would be happy to help on a PR if @budde377 also thinks this would be a valuable addition?

Undefined Class & Undefined Method

Undefined class 'GQLOptionsQueryposts'.
Try changing the name to the name of an existing class, or creating a class with the name 'GQLOptionsQueryposts'.

The method 'GQLOptionsQueryposts' isn't defined for the type 'GQLFQueryposts'.
Try correcting the name to the name of an existing method, or defining a method named 'GQLOptionsQueryposts'.

Any Help !! Not Sure What it is : (

Feature Request: Make output dir relative to project root

Id like to have nested folders
graphql

  • queries
    • authentication
      • login.graphql
  • schema.graphql

With the current method, the folders dont marry up.

With an output folder of ../lib/generated_models a folder is generated in the graphql folder instead of its correct placement of the lib/generated_models

This limits the ability to create folders for this tool.

Expected Behaviour

Make folder resolution relative to the package itself, not each graphql file.

Reserved key in Graphql type breaks code generation

I have experienced an edge case issue with this library while using it with the Graphql backend-as-a-service Hasura.

Hasura generates as part of other types the following input type:

input jsonb_cast_exp {
  String: String_comparison_exp
}

The key String is very unfortunate naming. It breaks the code generation as it declares this name as a class member:

@JsonSerializable(explicitToJson: true, includeIfNull: false)
class Input$jsonb_cast_exp {
  Input$jsonb_cast_exp({this.String});

  @override
  factory Input$jsonb_cast_exp.fromJson(Map<String, dynamic> json) =>
      _$Input$jsonb_cast_expFromJson(json);

  final Input$String_comparison_exp? String;

  Map<String, dynamic> toJson() => _$Input$jsonb_cast_expToJson(this);
  int get hashCode {
    final l$String = String;
    return Object.hashAll([l$String]);
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (!(other is Input$jsonb_cast_exp) || runtimeType != other.runtimeType)
      return false;
    final l$String = String;
    final lOther$String = other.String;
    if (l$String != lOther$String) return false;
    return true;
  }
}

As String is not defined as a type, but as a member in the context of this class the compiler complains.

I am not sure if this issue is in the scope of this library, but would there be a way to solve this when one cannot change the type in the backend? In my case I have filed an issue with Hasura, but I am not sure they will make the changes.

Repo's example lacking clarity about Mutations & Subscriptions

Hello,

Great package.
Could you update the example + README.md in the repo and on pub.dev to include examples on how to build and use a Mutation and a Subscription as well? (Calling them, and also displaying the data) It only has a simple Query, and GraphQL related packages should definitely include at least an example for each type in my opinion.
Right now this package's documentation seems very light considering how big it is.

Best regards, and thanks for your commitment,
Tiffaa

Incorrect slashes in the fragment import path

Thanks for the great package! Everything works as expected except for one thing.

Slashes in the generated files are turned in the wrong direction, which causes a compilation error.
Most likely the current implementation of the path joining is platform dependent (I am using Windows).

image

CopyWith method generated on fields in fragments expect functions rather than values themselves

Suppose a schema and fragments as given below

type Tournament {
	event: String!
	match: Match
}

type Match {
	homeTeam: Score
	awayTeam: Score
}

type Score {
	teamName: String!
	value: Int!
}
fragment Tournament on Tournament {
	event
	match {
		homeTeam {
			...Score
		}
		awayTeam {
			...Score
		}
	}
}

fragment Score on Score {
	teamName
	value
}

The code generated creates a class called FragmentTournament$match whose copywith is as given below

extension UtilityExtensionFragmentTournament$match on FragmentTournament$match {
  FragmentTournament$match copyWith(
          {FragmentTournament$match$homeTeam? Function()? homeTeam,
          FragmentTournament$match$awayTeam? Function()? awayTeam,
          String? $__typename}) =>
      FragmentTournament$match(
          homeTeam: homeTeam == null ? this.homeTeam : homeTeam(),
          awayTeam: awayTeam == null ? this.awayTeam : awayTeam(),
          $__typename: $__typename == null ? this.$__typename : $__typename);
}

It's expected to take in the values rather than functions that return those values, as is the norm in copyWith methods

Push permission

Unable to create a branch and push it, could you allow it, please?

image

Facing a codegen error on a basic project

I restructured and moved the person.graphql inside lib folder. Now I face an error:

➜  testing flutter clean && flutter pub get && flutter pub run build_runner build
╔════════════════════════════════════════════════════════════════════════════╗
║ A new version of Flutter is available!                                     ║
║                                                                            ║
║ To update to the latest version, run "flutter upgrade".                    ║
╚════════════════════════════════════════════════════════════════════════════╝


Cleaning Xcode workspace...                                         4.6s
Deleting .dart_tool...                                               3ms
Deleting .packages...                                                0ms
Deleting Generated.xcconfig...                                       0ms
Deleting flutter_export_environment.sh...                            0ms
Deleting .flutter-plugins-dependencies...                            0ms
Deleting .flutter-plugins...                                         0ms
Running "flutter pub get" in testing...                             3.3s
[INFO] Generating build script...
[INFO] Generating build script completed, took 424ms

[INFO] Precompiling build script......
[INFO] Precompiling build script... completed, took 5.7s

[INFO] Initializing inputs
[INFO] Building new asset graph...
[INFO] Building new asset graph completed, took 581ms

[INFO] Checking for unexpected pre-existing outputs....
[INFO] Checking for unexpected pre-existing outputs. completed, took 1ms

[INFO] Running build...
[SEVERE] graphql_codegen:graphql_codegen on lib/person.graphql:

Invalid GraphQL: Failed to find operation type for OperationType.query
[INFO] Generating SDK summary...
[INFO] 3.1s elapsed, 1/3 actions completed.
[INFO] Generating SDK summary completed, took 3.1s

[INFO] 4.2s elapsed, 1/3 actions completed.
[INFO] 5.3s elapsed, 1/3 actions completed.
[INFO] 7.8s elapsed, 1/3 actions completed.
[INFO] 11.6s elapsed, 1/3 actions completed.
[INFO] Running build completed, took 12.4s

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 38ms

[SEVERE] Failed after 12.4s
pub finished with exit code 1

This is actually the same error I faced in my original project due to which I decided to make a test project.

Originally posted by @gamer496 in #80 (comment)

Generator can't read outer variable in fragment

Generator fails when I try to generate this graphql (the commented out field)

Bad state: Failed to generate type.

schema {
    query: Query
}

type Competition {
    "Country code of the competition."
    countryCode: String
    "Relative URL for the country flag of the competition."
    flagUrl: String
    "Unique ID of the competition."
    id: Int!
    "Localized name."
    name(locale: Locale = en_US): String
}


type Query {
    competitions(
        "Filter competitions by date. If not provided, the default value is current date."
        date: DateTime,
        "If it's true, retrieve competitions with live matches only."
        live: Boolean = false
    ): [Competition!]!
}

type Team {
    "Number of goals on the current match."
    goals: Int
    "Unique ID of the team."
    id: Int!
    "Relative URL to the jersey image of current team."
    jerseyUrl: String
    "Lineup and bench players of the team on the current match."
    lineup: [Person!]!
    "Localized name."
    name(locale: Locale = en_US): String
    "Localized TLA name."
    tlaName(locale: Locale = en_US): String
}

enum Locale {
    da_DK
    de_DE
    el_GR
    en_US
    es_ES
    fr_FR
    it_IT
    nl_NL
    pl_PL
    pt_BR
    tr_TR
}

"A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date-time format."
scalar DateTime

query MainPage($date: DateTime!, $locale: Locale!, $live: Boolean!) {
    competitions(date: $date, live: $live) {
        id
        flagUrl
        name(locale: $locale)

        ...basicTeamInfo
    }
}

fragment basicTeamInfo on Team {
    id
    goals
    #name(locale: $locale)
    jerseyUrl
}

How can we remove the unset field (null) from request body before sending the request?

For example,

I have a query function:

  // get users

  Future<List<User>> getUsers({VariablesQueryUsers? variables}) async {
    final _result =
        await client.queryUsers(OptionsQueryUsers(variables: variables));

    if (_result.hasException) throw _result.exception!;

    final _users = QueryUsers.fromJson(_result.data!).users;

    return _users
        .map(
          (_user) => User.fromJson(_user.toJson()),
        )
        .toList();
  }

VariablesQueryUsers:

class VariablesQueryUsers extends JsonSerializable {
  VariablesQueryUsers(
      {this.where,
      this.orderBy,
      this.cursor,
      this.take,
      this.skip,
      this.distinct});
...

and these fields can be optional, thus all set to null.

when sending request with this:

_repository
        .getUsers(
          variables: VariablesQueryUsers(
            orderBy: [
              InputUserOrderByWithRelationInput(
                createdAt: EnumSortOrder.desc,
              )
            ],
            take: 10,
          ),
        )

Here I only set the orderBy and take, the request body contains all other fields that contain null, which throw the error as my backend doesn't support that. Maybe I missed something, but I am wondering if I can transform the request body before sending it.

Screenshot 2022-04-02 at 20 31 03

Generator not generating .g files

Version: graphql_codegen: 0.10.0-beta.5

Generator finds .graphql files but fails to generate .g files which are referenced in schema.graphql.dart with part 'schema.graphql.g.dart';

build.yaml

targets:
  $default:
    builders:
      graphql_codegen:
        options:
          outputDirectory: '__generated__'
          namingSeparator: ''
          addTypename: true
          scalars:
            DateTime:
              type: DateTime
            JSON:
              type: Map<String, dynamic>
            Upload:
              type: String
          clients:
            - graphql

generated files
Screenshot 2022-07-13 at 14 29 45
Screenshot 2022-07-13 at 14 30 11
)

Import all fields from type to fragment

Hello,

thanks for the great package! I am wondering if it's possible to generate automatically:

type Person {
  id: ID!
  firstName: String!
}

to this:

fragment FPerson on Person {
  __typename
  // all fields from Person here:
  id
  firstName
}

The problem is I have something like:

query getAllPersons {
  listPersons: [Person!]!
  getPerson(id: ID!): Person!
}

In that case I don't have a unified "Person" class in the generated classes.

codegen: build error

I'm trying to generate the dart data model from the graphql schema and I'm received the following error

➜  octokit.dart git:(main) make gen
dart run build_runner build
[INFO] Generating build script completed, took 788ms
[WARNING] ../../.pub-cache/hosted/pub.dartlang.org/graphql_codegen_config-0.1.2/lib/config.g.dart:31:28: Error: Method not found: '$enumDecode'.
              ?.map((e) => $enumDecode(_$GraphQLCodegenConfigClientEnumMap, e))
                           ^^^^^^^^^^^
../../.pub-cache/hosted/pub.dartlang.org/graphql_codegen_config-0.1.2/lib/config.g.dart:32:24: Error: The argument type 'Set<dynamic>' can't be assigned to the parameter type 'Set<GraphQLCodegenConfigClient>'.
 - 'Set' is from 'dart:core'.
 - 'GraphQLCodegenConfigClient' is from 'package:graphql_codegen_config/config.dart' ('../../.pub-cache/hosted/pub.dartlang.org/graphql_codegen_config-0.1.2/lib/config.dart').
              .toSet() ??
                       ^
[INFO] Precompiling build script... completed, took 1.3s
[SEVERE] Failed to precompile build script .dart_tool/build/entrypoint/build.dart.
This is likely caused by a misconfigured builder definition.

make: *** [Makefile:16: gen] Error 78

It looks like not related to my source code, but I can be wrong here, the full stack trace is here and in this repository there is the minimal reproducible example.

In addition, this is my build.yaml

targets:
  $default:
    builders:
      graphql_codegen:
        options:
          clients:
            - graphql

Docs do not reflect generated class names

When generating for a query like in the docs:

# person.graphql

query FetchPerson($id: ID!) {
  fetch_person(id: $id) {
    name: full_name
  }
}

the example states the generated widget is named Query$FetchPerson while it is named Query$FetchPersonWidget instead. This led for me to nearly throw out this package, since it "did not work".

But it DOES works great, once one finds out this.

Why extend `JsonSerializable`?

Hi, I've noticed that all classes that have the @JsonSerializable() metadata (whether they are part of the repository or generated) extend JsonSerializable. Why is that? As far as I know, this is only adding a few weird properties to every object, like fieldRename. It's not a requirement of json_serializable.

Mutation question

Hello,

first of all thanks for the great package! It's priceless!

I have the following schema:

type Query {
	listProducts(limit: Int, nextToken: String): ProductsConnection!
}

type Product {
	id: ID!
	title: String!
	content: String!
}

type ProductsConnection {
	items: [Product!]
	nextToken: String
}

type Mutation {
	createProduct(input: CreateProductInput!): Product!
}

input CreateProductInput {
	title: String!
	content: String!
}

How to build and pass the "CreateProductInput" to the mutation request?
It's fine with the atomic types (int, String etc.). Can't get it working with Input objects.

Thanks!

Error received: Null check operator used on a null value

When running "flutter pub run build_runner build" I'm receiving the following error:

`[INFO] Generating build script...ild
[INFO] Generating build script completed, took 595ms

[INFO] Initializing inputs
[INFO] Reading cached asset graph...
[INFO] Reading cached asset graph completed, took 80ms

[INFO] Checking for updates since last build...
[INFO] Checking for updates since last build completed, took 375ms

[INFO] Running build...
[SEVERE] graphql_codegen:graphql_codegen on lib/GraphQL/getFriends.graphql:

Null check operator used on a null value
[SEVERE] graphql_codegen:graphql_codegen on lib/GraphQL/schema.graphql:

Null check operator used on a null value
[INFO] Running build completed, took 153ms

[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 39ms

[SEVERE] Failed after 208ms
pub finished with exit code 1
`

For Reference here is my Schema
""" The @deferdirective may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with@deferdirective will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response.@includeand@Skiptake precedence over@defer`.
"""
directive @defer(
"""
If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to.
"""
label: String

"""
Deferred when true.
"""
if: Boolean
) on FRAGMENT_SPREAD | INLINE_FRAGMENT

"""
The @stream directive may be provided for a field of List type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. @include and @skip take precedence over @stream.
"""
directive @stream(
"""
If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to.
"""
label: String

"""
The initial elements that shall be send down to the consumer.
"""
initialCount: Int!

"""
Streamed when true.
"""
if: Boolean!
) on FIELD

"""
Delegates a resolver to a remote schema.
"""
directive @DeleGate(
"""
The path to the field on the remote schema.
"""
path: String

"""
The name of the schema to which this field shall be delegated to.
"""
schema: Name!
) on FIELD_DEFINITION

directive @computed(
"""
Specifies the fields on which a computed field is dependent on.
"""
dependantOn: [Name!]
) on FIELD_DEFINITION

"""
Annotates the original name of a type.
"""
directive @source(
"""
The original name of the annotated type.
"""
name: Name!

"""
The name of the schema to which this type belongs to.
"""
schema: Name!
) repeatable on ENUM | OBJECT | INTERFACE | UNION | INPUT_OBJECT | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE

type Query {
posts: [Post!]!
postById(input: GetPostByIdInput!): GetPostByIdPayload!
communities: [Community!]!
communityById(input: GetCommunityByIdInput!): Community!
users: [User]
userById(input: GetUserByIdInput): GetUserByIdPayload
relationsById(input: GetRelationsByIdInput): [Relationship]
friends(input: GetFriendsInput): [Relationship]
pendingFriendRequests(input: GetPendingFriendRequestsInput): [Relationship]
declinedFriendRequests(input: GetDeclinedFriendRequestsInput): [Relationship]
blockedFriendRequests(input: GetBlockedFriendRequestsInput): [Relationship]
listOfJoinedCommunitiesFromSessions(
input: GetListOfJoinedCommunitiesFromSessionsInput!
): [Uuid!]!
messageById(input: GetMessageByIdInput!): [Message!]!
messageByAuthor(input: GetMessageByAuthorInput!): [Message!]!
messageByRecipient(input: GetMessageByRecipientInput!): [Message!]!
messageByAuthorAndRecipient(
input: GetMessageByAuthorAndRecipientInput!
): [Message!]!
lobbiesByCommunity(input: GetLobbiesByCommunityInput!): [Lobby!]!
}

type Mutation {
addPost(input: AddPostInput!): AddPostPayload!
deletePost(input: DeletePostInput!): DeletePostPayload!
updatePost(input: UpdatePostInput!): UpdatePostPayload!
addCommunity(input: AddCommunityInput!): AddCommunityPayload!
removeCommunity(input: RemoveCommunityInput!): RemoveCommunityPayload!
updateCommunityName(
input: UpdateCommunityNameInput!
): UpdateCommunityNamePayload!
addUserToCommunity(
input: AddUserToCommunityInput!
): AddUserToCommunityPayload!
inviteUserToCommunity(
input: InviteUserToCommunityInput!
): InviteUserToCommunityPayload!
removeUserFromCommunity(
input: RemoveUserFromCommunityInput!
): RemoveUserFromCommunityPayload!
banUserFromCommunity(
input: BanUserFromCommunityInput!
): BanUserFromCommunityPayload!
addUser(input: AddUserInput): AddUserPayload
removeUser(input: RemoveUserInput): RemoveUserPayload
createRelation(input: CreateRelationInput): CreateRelationPayload
acceptRelation(input: AcceptRelationInput): AcceptRelationPayload
declineRelation(input: AcceptRelationInput): AcceptRelationPayload
blockRelation(input: BlockRelationInput): BlockRelationPayload
addNewMessage(input: AddNewMessageInput!): AddNewMessagePayload!
}

type AddPostPayload {
post: Post!
}

type DeletePostPayload {
isDeleted: Boolean!
}

type GetPostByIdPayload {
post: [Post!]!
}

type Post {
id: Int
body: String
createdAt: DateTime
postedFromUserID: Uuid
countUpVoted: Int
countDownVotes: Int
countTotalEngagment: Int
}

type UpdatePostPayload {
post: Post!
}

input AddPostInput {
post: PostInput!
user: UserInput!
}

input DeletePostInput {
post: PostInput!
}

input GetPostByIdInput {
id: Uuid!
}

input PostInput {
id: Int
body: String
createdAt: DateTime
postedFromUserID: Uuid
countUpVoted: Int
countDownVotes: Int
countTotalEngagment: Int
}

input UpdatePostInput {
post: PostInput!
}

input UserInput {
guid: Uuid!
displayName: String
firstName: String
lastName: String
email: String
}

input communities_UserInput {
id: Int!
status: Int
communityId: Int!
guid: Uuid!
displayName: String!
firstName: String!
lastName: String!
email: String!
}

type AddCommunityPayload {
community: Community!
}

type AddUserToCommunityPayload {
user: User!
}

type BanUserFromCommunityPayload {
user: User!
}

type Community {
id: Int!
guid: Uuid!
communityName: String!
dateCreated: DateTime!
userCount: Int!
users: [User!]!
avatar: String!
}

type InviteUserToCommunityPayload {
user: User!
}

type RemoveCommunityPayload {
guid: Uuid!
}

type RemoveUserFromCommunityPayload {
user: User!
}

type UpdateCommunityNamePayload {
guid: Uuid!
}

type User {
id: Int!
status: Int
communityId: Int!
guid: Uuid!
displayName: String!
firstName: String!
lastName: String!
email: String!
}

type users_User {
id: Int!
guid: Uuid!
displayName: String
firstName: String
lastName: String
email: String
}

input AddCommunityInput {
guid: Uuid!
name: String!
userCount: Int
avatar: String
}

input AddUserToCommunityInput {
user: communities_UserInput!
community: Uuid!
}

input BanUserFromCommunityInput {
user: communities_UserInput!
community: Uuid!
}

input GetCommunityByIdInput {
guid: Uuid!
}

input InviteUserToCommunityInput {
user: communities_UserInput!
community: Uuid!
}

input RemoveCommunityInput {
guid: Uuid!
}

input RemoveUserFromCommunityInput {
user: communities_UserInput!
community: Uuid!
}

input UpdateCommunityNameInput {
guid: Uuid!
name: String!
}

type AcceptRelationPayload {
isAccepted: Boolean!
}

type AddUserPayload {
user: users_User
}

type BlockRelationPayload {
isBlocked: Boolean!
}

type CreateRelationPayload {
isCreated: Boolean!
}

type GetUserByIdPayload {
user: users_User
}

type Relationship {
id: Int!
user1Id: Uuid!
user2Id: Uuid!
status: Int!
lastActionUser: Uuid!
}

type RemoveUserPayload {
guid: Uuid!
}

input AcceptRelationInput {
user1Guid: Uuid!
user2Guid: Uuid!
}

input AddUserInput {
guid: Uuid!
displayName: String
email: String
firstName: String
lastName: String
}

input BlockRelationInput {
user1Guid: Uuid!
user2Guid: Uuid!
}

input CreateRelationInput {
user1Guid: Uuid!
user2Guid: Uuid!
status: Int!
lastActionUser: Uuid!
}

input GetBlockedFriendRequestsInput {
guid: Uuid!
}

input GetDeclinedFriendRequestsInput {
guid: Uuid!
}

input GetFriendsInput {
guid: Uuid!
}

input GetPendingFriendRequestsInput {
guid: Uuid!
}

input GetRelationsByIdInput {
guid: Uuid!
}

input GetUserByIdInput {
guid: Uuid!
}

input RemoveUserInput {
guid: Uuid!
}

type AddNewMessagePayload {
message: Message!
}

type Lobby {
id: Int!
lobbyGuid: Uuid!
communityGuid: Uuid!
name: String
dateCreated: DateTime!
maxConnectionsAllowed: Int!
currentConnectionCount: Int!
isPrivate: Boolean!
avatar: String
}

type Message {
id: Int
authorGuid: Uuid!
recipientGuid: Uuid!
msgBody: String!
timeStamp: DateTime!
read: Boolean
sent: Boolean
}

input AddNewMessageInput {
authorGuid: Uuid!
recipientGuid: Uuid!
msgBody: String!
timeStamp: DateTime!
}

input GetListOfJoinedCommunitiesFromSessionsInput {
guid: Uuid!
}

input GetLobbiesByCommunityInput {
communityGuid: Uuid!
}

input GetMessageByAuthorAndRecipientInput {
authorGuid: Uuid!
recipientGuid: Uuid!
}

input GetMessageByAuthorInput {
guid: Uuid!
}

input GetMessageByIdInput {
id: Int!
}

input GetMessageByRecipientInput {
guid: Uuid!
}

"""
The name scalar represents a valid GraphQL name as specified in the spec and can be used to refer to fields or types.
"""
scalar Name

scalar Uuid

"""
The DateTime scalar represents an ISO-8601 compliant date time type.
"""
scalar DateTime
**Also here is my query used for testing**query {
friends(input: {guid: "63f8720e-b193-4828-9174-a57bde0e5717"}) {
user1Id
user2Id
lastActionUser
}
}`

codegen: build generates nothing

I creating a sample test project.
Dependencies

dependencies:
  flutter:
    sdk: flutter


  
  cupertino_icons: ^1.0.2
  graphql_flutter: ^5.1.0
  json_annotation: ^4.5.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  
  flutter_lints: ^1.0.0
  build_runner: ^2.1.11
  graphql_codegen: ^0.8.0
  json_serializable: ^6.2.0

I also created schema.graphql and person.graphql similar to example on pub.dev

Then I try to generate types:
flutter clean && flutter pub get && flutter pub run build_runner build
This runs successfully but does not generate anything. Am I doing something wrong?

Remove dependency to json_serializable

The json_serializable dependency adds a runtime dependency to json_annotations. We can home-roll our serialisation methods which would remove the dependency and simplify setup. Consider if this is the right approach.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.