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

Cannot make a custom ID Scalar #936

Closed
reconbot opened this issue Jun 19, 2021 · 4 comments
Closed

Cannot make a custom ID Scalar #936

reconbot opened this issue Jun 19, 2021 · 4 comments
Labels
needs/upstream An upstream component needs to be updated first type/question

Comments

@reconbot
Copy link
Contributor

I'm trying to make a custom scalar to replace the ID to allow for a new ID format. I've simplified the implementation for this issue. This Scalar should strip the MYID_ from the beginning of input IDs and add it to the data of the output IDs. However it does nothing.

import { Kind } from 'graphql'
import { scalarType } from 'nexus'

export const ID = scalarType({
  name: 'ID',
  asNexusMethod:'id',
  description: 'My id type',
  parseValue(value) {
    // decode string if needed
    return value.replace(/$MYID_/,'')
  },

  serialize(value) {
    // encode value
    return `MYID_${value}`
  },

  parseLiteral(ast) {
    if (ast.kind !== Kind.STRING) {
      return null
    }
    return ast.value
  },
})

I tried renaming asNexusMethod to myID and using that instead. Still does nothing. If I change the name then I'm able to get the desired behavior. However, I need to allow for the new ID without updating every single client so I can't change the name of ID. Any advice?

@Sytten Sytten added needs/clarification Unable to answer question/feature without more info type/question labels Jul 26, 2021
@Sytten
Copy link
Collaborator

Sytten commented Jul 26, 2021

What do you mean by Still does nothing? Did you check the generated TS file to make sure the method is there?
Generally overriding a core scalar is tricky, but I believe it should be possible.
I don't think you need an asNexusMethod here since nexus already provides one, you basically only want to override the resolver for that scalar.

@reconbot
Copy link
Contributor Author

reconbot commented Jul 26, 2021

I meant using a custom method to make the ID graphql type didn't make the custom scalar work.

@tgriesser
Copy link
Member

Just tried adding this, but it looks to be a limitation upstream in graphql-js:

graphql/graphql-js#917

If you want to be able to customize a builtin scalar globally, it looks like you need to patch the methods directly on the instance:

import { graphql, GraphQLID } from 'graphql'
import { makeSchema, queryField } from 'nexus'

it('can replace known scalars', async () => {
  GraphQLID.parseValue = function parseValue(value) {
    // decode string if needed
    return value.replace(/$MYID_/, '')
  }
  GraphQLID.serialize = function serialize(value) {
    // encode value
    return `MYID_${value}`
  }
  const schema = makeSchema({
    types: [
      queryField('id', () => ({
        type: 'ID',
        resolve() {
          return `Test`
        },
      })),
    ],
    outputs: false
  })
  expect(
    await graphql({
      schema,
      source: `{ id }`,
    })
  ).toEqual({ data: { id: 'MYID_Test' } })
})

@Sytten
Copy link
Collaborator

Sytten commented Jul 26, 2021

I think it is possible to override the scalar in the resolvers of the given server, I know I was able to do that in apollo. Maybe look that way?

@Sytten Sytten added needs/upstream An upstream component needs to be updated first and removed needs/clarification Unable to answer question/feature without more info labels Jul 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs/upstream An upstream component needs to be updated first type/question
Projects
None yet
Development

No branches or pull requests

3 participants