GithubHelp home page GithubHelp logo

urql-custom-scalars-exchange's People

Contributors

ciclentfort avatar clentfort avatar fehnomenal avatar larrifax avatar pantajoe avatar

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

Watchers

 avatar  avatar  avatar  avatar  avatar

urql-custom-scalars-exchange's Issues

Scalar array-types are not handled properly

This may be a result of #3.

Our case is like the following.

scalar Interval

type ThingWithInterval {
  interval: Interval
}

Interval is mapped to a corresponding type, like so:

type Interval {
  start: number;
  end: number;
}

From server to client (using Apollo), we serialize the Interval like so:

serialize(value: Interval) {
    return [value.start, value.end];
},

Then we deserialize the serialized-Interval using this custom scalars exchange like so:

Interval(v) {
   console.log("Interval input: ", v);
   return new Interval(v[0], v[1]);
}

The code runs the deserializer twice: once for each number in the serialized array-version of Interval.

For example, let us say the serialized Interval the client got was [100, 200]. Then the output from the console.log in the deserializer would be:

Interval input: 100
Interval input: 200

Instead, we would expect the deserializer should run on the entire array. Then, the output from the console.log would be:

Interval input: [100,200]

Handle not only queries but also mutations?

What I want is to set up not only how I want to process custom scalars, let say, parsing timestamps to Date in a centralized manner.
But I would also be happy to make Timestamp as an input field to get transformed from Javascript Date into milliseconds hence the Timestamp that backend expects.

Something like

scalarExchange({
          schema: (schema as unknown) as IntrospectionQuery,
          requestScalars: { // This is how to deserialize it back to original answer that server expects
            Timestamp: (input: Date) => {
              return input.getTime()
            },
            Date: (input: Date) => {
              return format(input, 'YYYY-MM-DD')
            },
            DateTime: (input: Date) => {
              return input // this one can be omited as Urql will run .toString() on this one anyway
            },
          }
          responseScalars: { // This is how to handle them when they come FROM server
            Timestamp: (input: number) => {
              return new Date(input)
            },
            Date: (input: string) => {
              return Date(input)
            },
            DateTime: (input: string) => {
              return Date(input)
            },
          },
        })

This one will make it super good to work with. Especially with graphql-codegen that gives the ability to specify scalar types in TypeScript, so if you map Date from GraphQL into Date on TS side and then, you can serialize it using this extension and be super happy with it when reading (when Fragments will be supported tho as they're not now (issue alongside)), but when you then try to send/write in using mutation some field of type Date and pass JS Date then you'll get a validation error as it will be converted to UTC string with time and timezone and not just YYYY-MM-DD causing you a headache :)

If this logic above will be implemented then it will be an amazing experience.

Please! :)

Is there a way to serialize outgoing data? Or is this exchange purely made for deserializing incoming data.

Just as the title suggests. Is there a way to serialize outgoing data?
The description shows that there is a scalars option that looks like this:

    scalars: {
        Json(value) {
            return JSON.parse(value);
        },
    },

Presumably, the name of the scalar is Json, the serialized form is the value and the parsed value is whatever that function returns. What if I now want to go backwards and, serialise a JS object into JSON before sending a request? Is this possible?

Doesn't handle nested Fragments

Many thanks for the repo! Still baffles me URQL and Apollo haven't got something like this natively...

A bug i've noticed is that this doesn't support nested Fragment's:
e.g.

query myQuery {
  object1 {
    fieldA,
    ...object1Fields
  }
}

fragment object1Fields on object1 {
  fieldB,
  object2 {
    ...object2Fields
  }
}

fragment object2Fields on object2 {
  fieldC,
}

fieldA and fieldB are mapped properly, but fieldC is ignored. Pulling the field out of the object2Fields fragment and putting it directly in to object1Fields does however work.
e.g.

query myQuery {
  object1 {
    fieldA,
    ...object1Fields
  }
}

fragment object1Fields on object1 {
  fieldB,
  object2 {
    fieldC
  }
}

Arrays of Custom Scalars not getting mapped

I have an array of dates that are being sent over as strings but are not getting mapped using the custom mapper function. For example I have a schema of

dates: [LocalDate!]!

that comes over as an array of strings but the mapping function for LocalDate is not run.

Here is my exchange setup.

import schema from '../../../introspection.json';

const scalarsExchange = customScalarsExchange({
  schema: (schema as unknown) as any,
  scalars: {
    LocalDate(value) {
      const date = new Date(value);
      console.log(date);
      return date;
    },
    LocalDateTime(value) {
      const date = new Date(value);
      console.log(date);
      return date;
    },
  },
});

From looking at the source it looks like there's maybe code to handle arrays in the mapScalars function but I'm not sure how to get the scalarMappings in makeVisitor/visitWithTypeInfo mapped correctly to make it work in mapScalars.

Would be happy to make a PR if pointed in the right direction, I'm just not sure what the correct solution is.

Doesn't work with fragments yet

Just a heads up after bumping into this. The implementation doesn't yet take into account the existence of GraphQL fragments.

How to specify parse and serialize methods?

Hi,

When using custom scalars, we need 2 methods, one to map value when data is received by the backend (parse), another method to serialize value, which is used to send the data to the backend.

How can I achieve with using custom scalar exchange? Docs do not specify anything about this and also couldn't find anything in closed/open issues.

Can someone help?

Set `@urql/core` and `graphql` as peer dependency

I think it will be better to have @url/core and graphql as peer dependencies. It will make sure the library and the rest of the project use the same versions. I ran into a problem with types when the main project used @urql/core:2.0.5 and your library @urql/core:2.0.0

Projectstatus

I am wondering whether this project is up for adoption. Several of the long-standing issues have been fixed in open PRs but haven't been addressed from maintainer-side and the project hasn't seen any activity on the default branch in 1.5 years.

@clentfort what is the status of this project and if it's unmaintained from your side, would you be open to have it adopted by a new group of maintainers? My employer uses this great exchange in several projects and we'd love to see it move forward again!

Support `urql@^4.0.0`

There were some breaking changes in 4.0.0 that make the interface incompatible, at least type-wise.

Works:
image

Doesn’t work:
image

Error:

Type 'import("<path>/node_modules/@urql/core/dist/urql-core-chunk").Exchange' is not assignable to type 'import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").Exchange'.
  Types of parameters 'input' and 'input' are incompatible.
    Type 'import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").ExchangeInput' is not assignable to type 'import("<path>/node_modules/@urql/core/dist/urql-core-chunk").ExchangeInput'.
      The types of 'client.operations$' are incompatible between these types.
        Type 'import("<path>/node_modules/wonka/dist/wonka").Source<import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").Operation<any, import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").AnyVariabl...' is not assignable to type 'import("<path>/node_modules/wonka/dist/wonka").Source<import("<path>/node_modules/@urql/core/dist/urql-core-chunk").Operation<any, import("<path>/node_modules/@urql/core/dist/urql-core-chunk").AnyVariables>>'.
          Type 'import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").Operation<any, import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").AnyVariables>' is not assignable to type 'import("<path>/node_modules/@urql/core/dist/urql-core-chunk").Operation<any, import("<path>/node_modules/@urql/core/dist/urql-core-chunk").AnyVariables>'.
            The types of 'context._instance' are incompatible between these types.
              Type 'import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").OperationInstance | undefined' is not assignable to type 'import("<path>/node_modules/@urql/core/dist/urql-core-chunk").OperationInstance | undefined'.
                Type 'OperationInstance' is not assignable to type 'OperationInstance | undefined'.
                  Type 'import("<path>/node_modules/urql/node_modules/@urql/core/dist/urql-core-chunk").OperationInstance' is not assignable to type 'import("<path>/node_modules/@urql/core/dist/urql-core-chunk").OperationInstance'.
                    Type 'OperationInstance' is not assignable to type '{ readonly _opaque: unique symbol; }'.
                      Types of property '_opaque' are incompatible.
                        Type 'typeof _opaque' is not assignable to type 'typeof _opaque'. Two different types with this name exist, but they are unrelated.ts(2322)

Upgrade to Urql 2

Upgrading the dependency is needed. Types are broken when upgrading to Urql 2.0 but I do not believe any changes to the library are necessary.

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.