micimize / graphql-to-dart Goto Github PK
View Code? Open in Web Editor NEWgenerate dart classes and respective JsonSerializable transcoders
generate dart classes and respective JsonSerializable transcoders
Hey, I updated flutter and in turn updated this package but it couldn't be installed.
> @graphql-codegen/[email protected] prepack
> bob-update-version
sh: bob-update-version: command not found
npm ERR! premature close
npm ERR! A complete log of this run can be found in:
If you create the gql right into the class (similar to apollo-angular), you would not need to import the gql files during runtime and also just bake the fragments into each document.
Hey I'm having issues with a union type, the operation class is using addAll that does not exist in the schema type's class which does not appear in the union template. Was this intentional? If you could explain some direction I can do the fix if needed. As well there's a syntax error when not constructor inputs exists you get
UnionItem({
}): super(
);
Looking at the example it seems to work with the union since there's an interface they're both implementing, maybe it doesn't work when the union doesn't have an interface.
You can reproduce the error with the example with gql:
query Search($text: String) {
search(text:$text){
...on Starship{
id
}
}
}
I assume this is meant to be used with graphql-flutter package ?
It would be awesome to see an example hooked up with flutter if you have time.
final testInput = CreateTestInput(fkID: '123', color: 'red');
print('${createTestInput.toJson()}');
// This prints { fkID: 123, color: red, otherAttr: null, id: null, ...}
This becomes a problem when trying to use this library with https://github.com/zino-app/graphql-flutter because in most cases you don't want to explicitly null things out.
Workaround:
final newItemResult = await client.mutate(MutationOptions(
documentNode: gql(mutationString),
variables: { 'input': createTestInput.toJson()
..removeWhere((_, dynamic val) => val == null) // remove the null items
}));
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
# without typename we can't really tell which fragments to parse
__typename
name
... on Droid {
primaryFunction
}
... on Human {
appearsIn
...info
...relationships
}
}
}
generates the HeroForEpisode{ Human, Droid }InlineFragment
models,
but the top level model is just
class HeroForEpisodeHero extends Character with HelloMixin {
static final String typeName = "Character";
@JsonKey(name: r'name', required: true, disallowNullValue: true)
String get name => fields.name;
set name(String name) => fields.name = name;
HeroForEpisodeHero({
@required String name,
}) : super(
name: name,
);
//...
I've handled regular field merging
{
f: friends {
name
}
f: friends {
id
}
}
#=>
{
f: friends {
name
id
}
}
But nested field fragment merging is a nightmare. I'm not going to do it anytime soon.
Basically, figuring out that ...info
generates Relationships
which contains the field friends
which gets merged into friends
in the top level query is just a horrible thing to deal with in the current design.
fragment home on Human {
home: homePlanet
planet: homePlanet
}
fragment dimensions on Human {
height
mass
}
fragment relationships on Human {
friends {
name
}
starships {
name
length
}
}
fragment info on Human {
...dimensions
...home
}
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
# without typename we can't really tell which fragments to parse
__typename
name
... on Droid {
primaryFunction
}
... on Human {
friends {
name
id
}
appearsIn
...info
...relationships
}
}
}
Use an Option type.
It's a good substitute for non nullable types.
I recommend using Dartz's one, this is a good library.
Code looks like
// full api: https://www.crossdart.info/p/dartz/0.6.1/src/option.dart.html
// Declare a maybe-null type
Option<int> count = option(data["count"] != null, data["count"]);
// use it
var text = count.fold(
() => "no count yet",
(_count) => "$_count counted ",
);
var timesTwo = totalCount.getOrElse(()=>0) * 2;
if (count.isNone()) {
print("it's null");
} else {
// safely "unwrap"
int _count = count.getOrElse(()=>null);
}
// deeper into functional programming
item.lat.flatMap(
(lat) => item.lng.map(
(lng) => Coords(latitude: lat, longitude: lng),
),
).forEach((coords) {
// will run if isSome()
print(coords);
});
On the document that's using the fragment, the generated dart creates the get/set methods howeveer they throw an error. For example...
'SendMomentMessageCreateMomentMessage.readReceipts=' ('void Function(List)') isn't a valid override of 'MessageModel.readReceipts=' ('void Function(List)').
Maybe the selection set classes that are generated from fragments template should all be mixins that are implemented on the documents that use them.
Example scenario:
_fragment.gql
fragment MyFragment on Model {
myField {
id
}
}
GetModel.gql
query GetModel {
models {
...MyFragment
myField {
createdAt
}
}
}
Hi @micimize !
This template looks awesome!
We recently released a new version of the codegen, with a new API and a better plugins support.
I think it will be much easier for you to implement this template now :)
I get an error when compiling the Dart file with command:
flutter packages pub run build_runner build
Error:
[WARNING] json_serializable on lib/serializers/graphql.dart:
This element has an undefined type. It may causes issues when generated code.
package:myplace/serializers/graphql.dart:15554:10
╷
15554 │ I18n i18n;
│ ^^^^
╵
Error seems due to the following Schema information with Scalar type
scalar I18n
By example, the Schema I'm using is not managing date field properly and those date field are managed as String.
I would like to overload type of some fields with configuration.
By Exemple:
From Schema:
creationDate String
I would like to transform to
creationDate DateTime
Hi,
There's a problem with aliases. Query like this:
route: geoRoute(locations: $locations) {
...RouteFragment
}
targetRoute: geoRoute(locations: $locationsAll) {
...RouteFragment
}
... is generated to this code:
SimulatorRoutesQuery({
@required SimulatorRouteFragmentRoute route,
@required SimulatorRouteFragmentTargetRoute targetRoute,
}): super(
geoRoute: route,
geoRoute: targetRoute,
)
(2 geoRoute passed to super)
Hello,
It works nice already, but would be better if output will also contain document, so there's no need to load file.
const HeroForEpisodeDoc = """query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
__typename
name
... on Droid {
primaryFunction
}
... on Human {
height
homePlanet
}
}
}""";
Hi. thank you for the work on this project. I am new to Dart/Flutter, and evaluating for my graphql heavy project. For web, I use apollo and typescript. Hope your package will help me to with similar experience on marshaling the API response.
I am mainly trying to see how the generator uses documents
. Along with type serializer, are there any helpers for query/mutations? Not sure it needed as I am yet to look at graphql_flutter.
When I try to generate the code with example:gql-gen
, I get his error
yarn run v1.15.2
$ cd example/ && gql-gen
✔ Parse configuration
❯ Generate outputs
❯ Generate lib/starwars_graphql_serializers
.dart
✔ Load GraphQL schemas
✔ Load GraphQL documents
✖ Generate
→ Cannot read property 'includes' of un
…
Found 1 error
✖ lib/starwars_graphql_serializers.dart
TypeError: Cannot read property 'includes'
of undefined
Only change I made was
plugins:
'graphql-to-dart'
instead of the local file path.
when I remove
documents:
- './lib/gql/HeroForEpisode.gql'
it generates the file.
versions:
"graphql-code-generator": "^0.18.2",
"graphql-to-dart": "^0.3.2",
some schemas/types (such as @fvisticot's) have underscore prefaced _fields
, which cannot be exposed as constructor fields without some kind of special handling.
This will need to be configurable: sometimes we'll want to drop them, sometimes rename.
How to fixe this issue ?
If we model the schema types completely, and treat selection sets only as projections, we can avoid the trade off created with mergedLeftWith / <<
covariance (rejection of the Liskov substitution principle)
MyFragment(baseField: 'bar', alias: 'bar') as MyBaseType << MyBaseType(baseField: 'biz');
# compiles, valid conceptually, not type safe
Merging using base types would exclude aliases and methods right now, but if we assume idempotent getters and methods within the same query on the server (a
and b
in { a, b: a }
and { a: foo(), b: foo() }
should always return the same thing) and implement the methods as getters against an internal map on object types:
/// ```graphql
/// type Task {
/// method(arg: Int): String!
/// }
/// ```
class _TaskFields {
/// https://pub.dev/packages/tuple
Map<Tuple<int>, String> methodResults;
_TaskFields({ this.methodResults });
method(int arg) => methodResults[Tuple(arg)];
}
// ...
/// ```graphql
/// task {
/// method(1)
/// }
/// ```
class TaskSelectionSet {
get method => fields.method(1);
}
Hi,
we again run into problems with the required fields. Lets consider the following minimal example:
type Query {
getBooks(): [Book!]
}
type Book {
name: String!
category : Category!
}
type Category{
name: String!
books: [Book!]!
}
If i want to query now for books -> category -> ... -> books
and some point the category or the books array has to be null which breaks the parsing.
In my opinion the root cause if the problem is that two different concepts are mixed up
This also leads to problems if non nullable fields are not selected, the parsing fails which should also not be the case. As far as I understand it's the idea of graphql to select only the fields you need, which does not mean that the fields you are not selecting can't be not nullable.
A possible solution would be to make the required: true, disallowNullValue: true
configurable or to remove it completely. I would go the for the later.
I can already tell that we're going to need/want more "value-based" equivalence helpers
https://stackoverflow.com/questions/47523725/dart-map-to-class
If a fromJson() constructor is added to the classes, it would increase operability with https://github.com/zino-app/graphql-flutter :
final customer = Customer.fromJson(myQueryResult.data);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.