eddeee888 / graphql-code-generator-plugins

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

[BUG] Intermodular type extensions: When a type is extended by another module, it unexpectedly affects the module where the type being extended originates #341

Open ulevitsky opened 2 weeks ago

ulevitsky commented 2 weeks ago

Describe the bug Generated resolvers for module where the type originates require non-nullable extended fields to be defined there -- even though there's no mention of those fields in the originating module's schema, and the resolvers are duly defined in the extending module.

To Reproduce

  1. Define schemas:
    • src/schema/zyblorb/schema.graphql:
      
      type Zyblorb {
      id: Int!
      }

type Query { zyblorbs: [Zyblorb!]! }

- `src/schema/flummle/schema.graphql`:

type Flummle { id: Int! }

extend type Zyblorb { flummles: [Flummle!]! }

2. Run codegen with the default config as follows: 

import type { CodegenConfig } from "@graphql-codegen/cli"; import { defineConfig } from "@eddeee888/gcg-typescript-resolver-files";

const config: CodegenConfig = { schema: "**/schema.graphql", generates: { "src/schema": defineConfig(), }, }; export default config;


4. In `src/schema/zyblorb/resolvers/Query/zyblorbs.ts`, implement `zyblorbs` resolver as `return [] as { id: number }[];` (to simulate just a parent record loaded e.g. from an ORM, without any child records)
5. In `src/schema/flummle/resolvers/Zyblorb.ts`, implement `flummles` resolver also as `return [] as { id: number }[];`
6. Notice the error in `src/schema/zyblorb/resolvers/Query/zyblorbs.ts`: `Property 'flummles' is missing in type '{ id: number; }' but required in type 'Zyblorb'.ts(2322)`

The only workaround I discovered is to make `flummles` nullable, however this is undesirable because it would never actually return a null.

**Expected behavior**
Resolvers generated for a module only consider the parts of the schema defined in that module.

**Versions**

- OS: Linux
- OS Version: Pop_OS 22.04
- Package name and version: @eddeee888/gcg-typescript-resolver-files v0.11.0
eddeee888 commented 2 weeks ago

Hi @ulevitsky ,

Have you tried using mappers for this? Mappers is the recommended way to let resolvers return a different interface, to defer resolve to the other resolvers in the chain.

For you example, please add the following file:

// src/schema/zyblorb/schema.mappers.ts
export type ZyblorbMapper = {
  id: number;
}

Running codegen will force create Zyblorb .flummles:

// src/schema/flummle/resolvers/Zyblorb.ts
export type Zyblorb: Pick<ZyblorbResolvers, 'flummles'> = {
  flummles: () => { 
    // your implementation here
  }
}

Here's some resources related to using mappers: