juancastillo0 / leto

Dart GraphQL server libraries. Utilities, code generator, examples and reference implementation.
https://juancastillo0.github.io/leto/
MIT License
38 stars 6 forks source link

`List<Object?>` is not subtype of `List<Upload>` when accepting multiple `Upload`s in `Mutation` #15

Closed SleepySquash closed 9 months ago

SleepySquash commented 10 months ago

Thank you for the package, it's working great!

I've discovered that multiple Uploads currently throw a GraphQLError due to type cast error, caused by leto_generator.

Let's say we have:

@Mutation()
Future<Novel> uploadNovel(
  Ctx ctx, {
  required NovelId id,
  required List<Upload> uploads,
}) async {
    // ...
}

When running leto_generator, the following code is generated:

GraphQLObjectField<Novel, Object?, Object?> get uploadNovelGraphQLField =>
    _uploadNovelGraphQLField.value;
final _uploadNovelGraphQLField =
    HotReloadableDefinition<GraphQLObjectField<Novel, Object?, Object?>>(
        (setValue) => setValue(novelGraphQLType.nonNull().field<Object?>(
              'uploadNovel',
              resolve: (obj, ctx) {
                final args = ctx.args;

                return uploadNovel(ctx,
                    id: (args["id"] as NovelId),
                    uploads: (args["uploads"] as List<Upload>));
              },
            ))
              ..inputs.addAll([
                novelIdGraphQLType.nonNull().inputField('id'),
                Upload.graphQLType
                    .nonNull()
                    .list()
                    .nonNull()
                    .inputField('uploads')
              ]));

And the line:

uploads: (args["uploads"] as List<Upload>));

throws an error in runtime: List<Object?> is not subtype of List<Upload> in type cast.

If that line is changed to:

uploads: (args["uploads"] as List<Object?>).cast<Upload>());

or

uploads: (args["uploads"] as List<Object?>).map((e) => e as Upload).toList());

then everything works flawlessly, uploads are successful.

SleepySquash commented 10 months ago

Workaround I've discovered (until this is fixed):

GraphQLUploadType get objectGraphQLType => uploadGraphQLType;

...

@Mutation()
Future<Novel> uploadNovel(
  Ctx ctx, {
  required NovelId id,
  required List<Object?> uploads,
}) async {
    // use `uploads.cast<Upload>();`
}
juancastillo0 commented 10 months ago

Thanks for the issue! Could you try the latest leto_schema: ^0.0.1-dev.5?

SleepySquash commented 10 months ago

@juancastillo0, works perfectly, thanks 🎉