dotansimha / graphql-code-generator

A tool for generating code based on a GraphQL schema and GraphQL operations (query/mutation/subscription), with flexible support for custom plugins.
https://the-guild.dev/graphql/codegen/
MIT License
10.86k stars 1.33k forks source link

`Field(s) ... are not used.` on fields that are used. #10122

Open adriangalilea opened 3 months ago

adriangalilea commented 3 months ago

Which packages are impacted by your issue?

@graphql-codegen/core

Describe the bug

I want to preface this by saying that I won't provide a repro URL, I don't have the time to so, feel free to close it.

However I crated this mockup code in order to illustrate what the issue is:

async function getBookAvailability(bookIds: string[]): Promise<Record<string, BookAvailability[]>> {
  // Simulate an external API call to get real-time availability data
  // This data couldn't be part of the main GraphQL query as it's dynamic and from a different system
  return bookIds.reduce((acc, id) => {
    acc[id] = [
      { branchId: 'b1', branchName: 'Downtown', availableCopies: Math.floor(Math.random() * 5) },
      { branchId: 'b2', branchName: 'Suburb', availableCopies: Math.floor(Math.random() * 5) },
    ];
    return acc;
  }, {} as Record<string, BookAvailability[]>);
}

export async function getLibraryCatalogSection(sectionId: string) {
  const getCatalogSectionQuery = graphql(`
    query GetCatalogSection($sectionId: ID!) {
      catalogSection(id: $sectionId) {
        id
        name
        description
        books {
          id
          title
          author {
            id
            name
            birthYear
            deathYear
            nationality
          }
          publishYear
          genres
          isbn
          pageCount
          language
          publisher {
            id
            name
            foundedYear
          }
          reviews {
            id
            rating
            reviewText
            userNickname
          }
          coverImage {
            url
            altText
          }
        }
        subSections {
          id
          name
        }
        lastUpdated
        curatorNotes
      }
    }
  `);

  const result = await executeQuery(getCatalogSectionQuery, { sectionId });

  if (!result.catalogSection) return null;

  const bookIds = result.catalogSection.books.map(book => book.id);
  const availabilityData = await getBookAvailability(bookIds);

  const enrichedBooks = result.catalogSection.books.map(book => ({
    ...book,
    availability: availabilityData[book.id] || []
  }));

  return {
    ...result.catalogSection,
    books: enrichedBooks,
  };
}

When I have a query inside of a function where some of the fields are used but the rest are simply returned, I get tons of Field(s) ... are not used. warnings for the fields that are returned to use externally but are not used internally.

It happens for all the fields that I don't access inside the function.

I can't tsignore anything inside graphql(...) so I have no idea how to fix it.

Codegen Config File

import type { CodegenConfig } from "@graphql-codegen/cli";
import dotenv from "dotenv";

const config: CodegenConfig = {
  schema: process.env.GRAPHQL_ENDPOINT,
  documents: ["db/operations/**/*.tsx", "db/operations/**/*.ts"],
  ignoreNoDocuments: true,
  generates: {
    "./db/generated-graphql/": {
      preset: "client",
      presetConfig: {
        fragmentMasking: { unmaskFunctionName: "getFragmentData" },
      },
      config: {
        documentMode: "string",
      },
    },
    "./db/generated-graphql/types.ts": {
      plugins: ["typescript", "typescript-operations"],
      config: {
        enumsAsTypes: false,
        skipTypename: true,
        skipUnusedFragments: true,
      },
    },
    "./db/schema.graphql": {
      plugins: ["schema-ast"],
      config: {
        includeDirectives: true,
      },
    },
  },
};

export default config;
adriangalilea commented 3 months ago

Inconvenient solution: if I create the query elsewhere and import it the issue disappears.

bmulholland commented 2 months ago

I'm having a similar problem, but in Vue. Here's an example -- about as bare-bones as one can get for the fragments approach.

<script setup lang="ts">
import { computed } from "vue"
import { gql, useFragment, type FragmentType } from "~typedgql"

const conversationFragment = gql(/* GraphQL */ `
  fragment ConversationHeader_ConversationFragment on Conversation {
    subject
  }
`)

const props = defineProps<{
  conversation: FragmentType<typeof conversationFragment>
}>()

const conversation = computed(() => useFragment(conversationFragment, props.conversation))
</script>

<template>
  <h2>{{ conversation.subject }}</h2>
</template>
Screenshot 2024-09-02 at 10 48 31
bmulholland commented 2 months ago

I managed to find out more about it, and it's likely a separate problem, filed here: https://github.com/dotansimha/graphql-code-generator/issues/10127

eddeee888 commented 2 months ago

Hi, could you please let me know which tool or language server is showing this error? AFAIK, codegen doesn't have any IDE integration, nor reports anything to GraphQL Language Server, so this could come from a different tool.

bmulholland commented 2 months ago

@eddeee888 it comes from @0no-co/graphqlsp, which is recommended in the docs.

eddeee888 commented 1 month ago

If it's from @0no-co/graphqlsp, could you please try raising this issue on their GitHub repo? https://github.com/0no-co/GraphQLSP 🙂

bmulholland commented 1 month ago

Well, it depends. In the case of the issue I branched off this one, there's no issue on that project as it's designed. It works together with a suite of tools that competes with codegen. But the way this (codegen) project requires code be written is incompatible with how the LSP works. Unless the LSP explicitly adds support for codegen, which I suspect would take some level of official coordination at a minimum, there's no bug over there.

eddeee888 commented 1 month ago

Would it be possible to get a minimal reproducible repo? It'll help speed up the debugging process 🙂

AFAIK, the LSP in question works at a different level to Codegen: LSP does code analysis on TypeScript sources to report unused field errors, whereas Codegen generates types from GraphQL sources.

You can see the error message being reported by the LSP here. There are similar issues related to this error message here: https://github.com/0no-co/GraphQLSP/issues?q=is%3Aissue+%22unused%22

I would highly recommend opening an issue in https://github.com/0no-co/GraphQLSP, unless there's a reproducible repo to help confirm the issue.