Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong usage of Fragment passed code generation process #340

Open
kikuchy opened this issue Mar 1, 2024 · 2 comments
Open

Wrong usage of Fragment passed code generation process #340

kikuchy opened this issue Mar 1, 2024 · 2 comments
Labels
enhancement New feature or request planned

Comments

@kikuchy
Copy link

kikuchy commented Mar 1, 2024

Thank you for really useful package! Our team is using this heavily.

We found one problem, the Fragment based on wrong type will pass the code generation process.

Env:

  graphql_codegen: ^0.13.11
  build_runner: ^2.4.8

Code:

type Query {
    foo(id: ID!): FooCore!
    bar(id: ID!): BarCore!
}


type BarCore {
    something: Something!
}

type FooCore {
    something: Something!
}

type Something {
    id: ID!
}

query FooQuery {
    foo(id: "1") {
        ...Share
    }

    bar(id: "1") {
        # ⭐ It should be error but code generation will not be error
        ...Share
    }
}

fragment Share on FooCore {
    something {
        id
    }
}

Command line:

➜  graphql_codegen_trouble2 flutter pub run build_runner build
Deprecated. Use `dart run` instead.
[INFO] Generating build script completed, took 222ms
[INFO] Reading cached asset graph completed, took 63ms
[INFO] Checking for updates since last build completed, took 684ms
[INFO] Running build completed, took 257ms
[INFO] Caching finalized dependency graph completed, took 34ms
[INFO] Succeeded after 295ms with 1 outputs (1 actions)

Output:

Part of `Query$FooQuery`

foo is typed as Fragment$Share, bar is typed as Query$FooQuery$bar.

class Query$FooQuery {
  Query$FooQuery({
    required this.foo,
    required this.bar,
    this.$__typename = 'Query',
  });

  factory Query$FooQuery.fromJson(Map<String, dynamic> json) {
    final l$foo = json['foo'];
    final l$bar = json['bar'];
    final l$$__typename = json['__typename'];
    return Query$FooQuery(
      foo: Fragment$Share.fromJson((l$foo as Map<String, dynamic>)),
      bar: Query$FooQuery$bar.fromJson((l$bar as Map<String, dynamic>)),
      $__typename: (l$$__typename as String),
    );
  }

  final Fragment$Share foo;

  final Query$FooQuery$bar bar;

  final String $__typename;

  Map<String, dynamic> toJson() {
    final _resultData = <String, dynamic>{};
    final l$foo = foo;
    _resultData['foo'] = l$foo.toJson();
    final l$bar = bar;
    _resultData['bar'] = l$bar.toJson();
    final l$$__typename = $__typename;
    _resultData['__typename'] = l$$__typename;
    return _resultData;
  }

  @override
  int get hashCode {
    final l$foo = foo;
    final l$bar = bar;
    final l$$__typename = $__typename;
    return Object.hashAll([
      l$foo,
      l$bar,
      l$$__typename,
    ]);
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (!(other is Query$FooQuery) || runtimeType != other.runtimeType) {
      return false;
    }
    final l$foo = foo;
    final lOther$foo = other.foo;
    if (l$foo != lOther$foo) {
      return false;
    }
    final l$bar = bar;
    final lOther$bar = other.bar;
    if (l$bar != lOther$bar) {
      return false;
    }
    final l$$__typename = $__typename;
    final lOther$$__typename = other.$__typename;
    if (l$$__typename != lOther$$__typename) {
      return false;
    }
    return true;
  }
}
Part of `Query$FooQuery$bar`

Has complete fileds.

class Fragment$Share {
  Fragment$Share({
    required this.something,
    this.$__typename = 'FooCore',
  });

  factory Fragment$Share.fromJson(Map<String, dynamic> json) {
    final l$something = json['something'];
    final l$$__typename = json['__typename'];
    return Fragment$Share(
      something: Fragment$Share$something.fromJson(
          (l$something as Map<String, dynamic>)),
      $__typename: (l$$__typename as String),
    );
  }

  final Fragment$Share$something something;

  final String $__typename;

  Map<String, dynamic> toJson() {
    final _resultData = <String, dynamic>{};
    final l$something = something;
    _resultData['something'] = l$something.toJson();
    final l$$__typename = $__typename;
    _resultData['__typename'] = l$$__typename;
    return _resultData;
  }

  @override
  int get hashCode {
    final l$something = something;
    final l$$__typename = $__typename;
    return Object.hashAll([
      l$something,
      l$$__typename,
    ]);
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (!(other is Fragment$Share) || runtimeType != other.runtimeType) {
      return false;
    }
    final l$something = something;
    final lOther$something = other.something;
    if (l$something != lOther$something) {
      return false;
    }
    final l$$__typename = $__typename;
    final lOther$$__typename = other.$__typename;
    if (l$$__typename != lOther$$__typename) {
      return false;
    }
    return true;
  }
}
Part of `Query$FooQuery$bar`

No fields.

class Query$FooQuery$bar {
  Query$FooQuery$bar({this.$__typename = 'BarCore'});

  factory Query$FooQuery$bar.fromJson(Map<String, dynamic> json) {
    final l$$__typename = json['__typename'];
    return Query$FooQuery$bar($__typename: (l$$__typename as String));
  }

  final String $__typename;

  Map<String, dynamic> toJson() {
    final _resultData = <String, dynamic>{};
    final l$$__typename = $__typename;
    _resultData['__typename'] = l$$__typename;
    return _resultData;
  }

  @override
  int get hashCode {
    final l$$__typename = $__typename;
    return Object.hashAll([l$$__typename]);
  }

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

It looks expanding Share in bar I marked with ⭐ should be error, but It success code generation.
(IntelliJ's Graphql plugin shows error
スクリーンショット 2024-03-01 22 12 16
)

It doesn't stop our work, but it caused a little trouble.
We hope this behavior will fix!

Copy link

github-actions bot commented Mar 1, 2024

👋 @kikuchy
Thank you for raising an issue. I will investigate the issue and get back to you as soon as possible.
Please make sure you have provided enough context.

This library is created and maintained by me, @budde377. Please consider supporting my work and ensure our survival by donating here.

@budde377 budde377 added the enhancement New feature or request label Mar 5, 2024
@budde377
Copy link
Contributor

budde377 commented Mar 5, 2024

Thanks for reporting. I agree throwing an error here is useful and right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request planned
Projects
None yet
Development

No branches or pull requests

2 participants