eddeee888 / graphql-code-generator-plugins

List of GraphQL Code Generator plugins that complements the official plugins.
MIT License
44 stars 10 forks source link

How to make this work with File scalar in graphql-yoga? #230

Closed taybin closed 2 months ago

taybin commented 4 months ago

My project requires working with multi-part uploads and I would like to use graphql-yoga's scalar File feature. I don't see how I can suppress the creation of a File resolver with this plugin though scalarOverrides and instead use the built-in File type that graphql-yoga is passing in.

Am I missing something or is this not possible at this point in time?

taybin commented 4 months ago

I think the fix is to add File to isNativeNamedType().

eddeee888 commented 4 months ago

Hi @taybin 👋

Thanks for raising this issue. It's interesting that GraphQL Yoga handles its own File scalar. I don't believe this is something that's supported out-of-the-box by other servers (e.g. Apollo Server) though, so I don't think we could add it to isNativeNamedType 🙂.


The only workaround I could think of right now is not great 😓 :

  1. remove the File from the resolver object
  2. do not remove the generated File.ts as it'd keep getting generated
import { resolvers } from "./schema/resolvers.generated";

delete resolvers.File;

const yoga = createYoga({
  schema: createSchema({ typeDefs, resolvers }),
});

I'm working on improving resolverGeneration soon, which can be used to tell the preset not to generate certain types, like the File scalar in your use case

eddeee888 commented 3 months ago

Hi @taybin , could you please try out this alpha version?

yarn add -D @eddeee888/gcg-typescript-resolver-files@pr240-run411-1

And the new definteConfig for your use case may look like this:

defineConfig({
  resolverGeneration: {
    query: '*',
    mutation: '*',
    subscription: '*',
    scalar: '!*.File', // Generate: all Scalar resolvers in all modules, except for the scalar named `File`
    object: '*',
    union: '',
    interface: '',
  },
})

Here's the WIP PR: https://github.com/eddeee888/graphql-code-generator-plugins/pull/240 I'll follow up with more documentation, examples and use cases soon

taybin commented 3 months ago

Will do, thanks!

taybin commented 3 months ago

@eddeee888 Can you explain what the object, union, and interface settings do? I don't get the link between those and resolvers.

eddeee888 commented 3 months ago

Sure! Maybe the name resolverGeneration is misleading (something we can change before v1). This is the option that tells preset what files to generate (maybe fileGeneration is a better name).


Given this schema:

# src/schema/base/schema.graphql
interface Error  {
  # ...
}

# src/schema/user/schema.graphql
type User {
  # ...
}

# src/schema/book/schema.graphql
type BookError implements Error {
  # ...
}

union BookResult = BookOk | BookError

Then, object option will be responsible for:

interface option be be resonspible for:

union option will be responsible for:

'*' will generate every file of the relevant type. '' won't generate any files.


(*) Normalized name is important (and will be documented ) as we use can use wildcard to choose what we want to generate.

Example: some graphs have a standard to wrap results in wrappers e.g. object types ending with Ok or Error. These usually don't have logic in them but are generated anyways by the preset. resolverGeneration allows us to avoid generating these wrapper types:

resolverGeneration: {
  // ... other config
  object: ['!*Ok', '!*Error']
}

Right now, the default resolverGeneration option is recommended which generates all files except for unions and interfaces i.e.

resolverGeneration: {
  query: '*',
  mutation: '*',
  subscription: '*',
  scalar: '*',
  object: '*',
  union: '',
  interface: '',
},
taybin commented 3 months ago

This suppresses the File resolver generation. I haven't tested it yet, but:

      scalarsOverrides: {
        File: {
          type: 'File',
        },
      },

seems to be how to get the appropriate type generated for graphql-yoga.

taybin commented 3 months ago

Oh, last bit of feedback, typescript didn't know the new type for resolverGeneration. Not sure if you've set that up yet or not.

eddeee888 commented 3 months ago

Thanks @taybin !

Once this is released, I'll look into adding File-related config into GraphQL Yoga guides.

For types, I can see options being recommended if an object is used:

Screenshot 2024-03-23 at 8 45 12 am

I cannot find an easy way to type the expected values of each option though as it's a globby pattern for our GraphQL types. If you know how, let me know!

eddeee888 commented 2 months ago

Hi @taybin ,

This is now available in v0.8. Thank you for collaborating with me!