Coder Social home page Coder Social logo

Comments (7)

klavs avatar klavs commented on June 27, 2024

@vanelizarov is the underlying issue that some scalars may not be strings (over JSON)?

from gql.

vanelizarov avatar vanelizarov commented on June 27, 2024

@klavs yeah, that's the case. For example Uint which is actually int in Dart. It comes as number from server, but I cannot simply print() such property because of typecasting exception, of course other operations with these properties are unavailable for the same reason
Also it would be cool to map other scalars like Email (which is actually a plain string and comes from server as string) to Dart's String just for optimization sake 🙂

from gql.

klavs avatar klavs commented on June 27, 2024

Also it would be cool to map other scalars like Email (which is actually a plain string and comes from server as string) to Dart's String just for optimization sake

It could be added as an option, but I do not think it's good to optimize for performance here. All the custom scalars are wrapped to avoid unintentional assignments. If email: Email is treated as a String, developer is able to assign any String to email without any static warning. Wrapped types force developer to explicitly cast primitive types to scalars. I'm actually considering adding a wrapper to ID type, because ids are supposed to be opaque.

For example Uint which is actually int in Dart. It comes as number from server, but I cannot simply print() such property because of typecasting exception, of course other operations with these properties are unavailable for the same reason

Yes, such functionality should probably be added. For the reasons explained above, I think it would be first implemented as a map of custom scalar to JSON-compatible dart type (int, double, String, bool).

from gql.

vanelizarov avatar vanelizarov commented on June 27, 2024

It could be added as an option, but I do not think it's good to optimize for performance here. All the custom scalars are wrapped to avoid unintentional assignments. If email: Email is treated as a String, developer is able to assign any String to email without any static warning. Wrapped types force developer to explicitly cast primitive types to scalars. I'm actually considering adding a wrapper to ID type, because ids are supposed to be opaque.

Oh, now I understand, thanks for the explanation!

Yes, such functionality should probably be added. For the reasons explained above, I think it would be first implemented as a map of custom scalar to JSON-compatible dart type (int, double, String, bool).

So, can you please point me where to start working on such option? I'm interested in implementing it and making PR in case of success 🙂
All I've found for now is defaultTypeMap constant here and that it gets passed through typeRef() to code builder operations, but I cannot understand, how to pass down custom map from build.yaml and how to do it for all builders at once without copy-pasting this map for each builder

from gql.

klavs avatar klavs commented on June 27, 2024

It's going to be affecting many files. gql_build would be responsible of reading in the custom map and passing it to gq_code_builder. Every builder interested in schema types would receive the custom map and pass it down every function call till the accessor is reached.

Unfortunately, it would most likely not be implementable once without copy-pasting.

As you noticed, defaultTypeMap and typeRef were initial attempt to solve this problem, but I lowered it's priority and did not finish it.

from gql.

vanelizarov avatar vanelizarov commented on June 27, 2024

@klavs ok, I understand what you mean, thanks!

Finally I ended up with temp solution by copying gql_build and gql_code_builder to my project and changing some sources:

  1. Defined customScalarMap constant in gql_code_builder/lib/src/common.dart
const defaultTypeMap = <String, Reference>{
  // ...
};

const customTypeMap = <String, Reference>{
  "Uint": Reference("int"),
  "Time": Reference("String"),
  "Upload": Reference("File", "dart:io"),
  "Email": Reference("String"),
  // ...
};
  1. Added condition to check if current typeName exists in customTypeMap to gql_code_builder/lib/src/operation/data.dart for further checks to not add .value in getters/setters:
Method _buildGetter(
  DocumentNode schema,
  String schemaUrl,
  SelectionNode node,
  String prefix,
  String type,
) {
  if (node is FieldNode) {
    // ...
    final typeName = unwrappedTypeNode.name.value;

    TypeDefinitionNode fieldTypeDef;
    if (!customTypeMap.containsKey(typeName)) {
      fieldTypeDef = _getTypeDefinitionNode(
        schema,
        typeName,
      );
    }

    final typeMap = {
      ...defaultTypeMap,
      ...customTypeMap, // also added this one
      if (node.selectionSet != null)
        typeName: refer("$prefix\$$name")
      else if (fieldTypeDef != null)
        typeName: refer(typeName, schemaUrl)
    };
    // ...
}

Similarly did it for gql_code_builder/lib/src/operation/var.dart

Method _buildSetter(
  VariableDefinitionNode node,
  DocumentNode schema,
  String schemaUrl,
) {
  final unwrappedTypeNode = _unwrapTypeNode(node.type);
  final typeName = unwrappedTypeNode.name.value;

  TypeDefinitionNode argTypeDef;
  if (!customTypeMap.containsKey(typeName)) {
    argTypeDef = _getTypeDefinitionNode(
      schema,
      typeName,
    );
  }

  final typeMap = {
    ...defaultTypeMap,
    ...customTypeMap, // also added this one
    if (argTypeDef != null) typeName: refer(typeName, schemaUrl),
  };
  // ...
}

And for gql_code_builder/lib/src/schema/input.dart:

Method _buildSetter(
  InputValueDefinitionNode node,
  DocumentNode doc,
) {
  final unwrappedTypeNode = _unwrapTypeNode(node.type);
  final typeName = unwrappedTypeNode.name.value;

  TypeDefinitionNode argTypeDef;
  if (!customTypeMap.containsKey(typeName)) {
    argTypeDef = _getTypeDefinitionNode(
      doc,
      typeName,
    );
  }

  final typeMap = {
    ...defaultTypeMap,
    ...customTypeMap, // also added this one
    if (argTypeDef != null) typeName: refer(typeName),
  };
  // ...
}
  1. Changed pubspec.yaml imports in locally copied gql_build:
dependencies:
  # ...
  gql_code_builder:
    path: ../gql_code_builder

And in my project:

dev_dependencies:
  # ...
  gql_build:
    path: ../gql_build

I know that this solution doesn't quite correlate with what you wrote, but it works for me. Hope sometimes you will release "native" version of it 🙂

from gql.

smkhalsa avatar smkhalsa commented on June 27, 2024

@vanelizarov initial custom scalar support has been added, although docs still need to be updated.

You will need to provide a "type_overrides" yaml map in your build.yaml. Please note that you need to duplicate the type_overrides map for each builder that depends on the schema in your build.yaml.

      gql_build|data_builder:
        enabled: true
        options:
          schema: pokemon_explorer|lib/schema.graphql
          type_overrides:
            MyScalar:
              name: MyScalar
              import: "path/to/package"

from gql.

Related Issues (20)

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.