graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

Bug: enumValues with external imports creates invalid re-export syntax and name mismatches between plugins

Open ItaiYosephi opened this issue 2 months ago • 5 comments

Which packages are impacted by your issue?

@graphql-codegen/cli, @graphql-codegen/typescript-operations, @graphql-codegen/typescript

Describe the bug

Description

When using the enumValues configuration to import an external enum with a different name than what appears in the GraphQL schema, the generated code has two issues:

  1. Invalid re-export syntax: The codegen generates invalid TypeScript/JavaScript when it tries to re-export an import alias
  2. Name mismatch: The typescript and typescript-operations plugins use different names for the same enum

Current Behavior

Given this configuration:

config: {
  enumValues: {
    LicenseSKU: '../shared-generated-enums#LicenseSku',
  }
}

Where the GraphQL schema has:

enum LicenseSKU {
  BASIC
  ADVANCED
  # ...
}

The codegen generates:

// At the top of the file
import { LicenseSku as LicenseSKU } from '@wiz-sec/tenant-shared/graphqlTypes';

// In type definitions from typescript-operations plugin
export type SomeQuery = {
  license: {
    sku: LicenseSku; // ❌ This type doesn't exist - it expects the imported name
  }
}

// At the bottom of the file  
export { LicenseSKU }; // 

Expected Behavior

When using enumValues with an external import, the codegen should use the schema name consistently: Both typescript and typescript-operations plugins should reference the enum by the same name

Suggested Solution

The enum should be aliased internally to match what would be generated if enumValues were not provided. in our example, the import should have been:

import { LicenseSku as LicenseSku } from './shared';
// or just
import { LicenseSku  } from './shared';

Workaround

Currently we have to add a manual alias using the add plugin:

{
add: {
   content: `export const TenantLicenseSku = TenantLicenseSKU; export type TenantLicenseSku = TenantLicenseSKU;`,
},
}

Environment

  • @graphql-codegen/cli: ^5.0.7
  • @graphql-codegen/typescript: ^4.1.6
  • @graphql-codegen/typescript-operations: (latest)
  • Node version: 22.x
  • OS: macOS

Your Example Website or App

https://codesandbox.io/p/sandbox/github/dotansimha/graphql-code-generator-issue-sandbox-template

Steps to Reproduce the Bug or Issue

just open types.ts, and see that import:

import { LicenseSku as LicenseSKU } from './shared';

and LicenseQuery expects LicenseSku

export type LicenseQuery = {
  __typename?: 'Query';
  license: { __typename?: 'License'; sku: LicenseSku // wrong! };
};

Expected behavior

When using enumValues with an external import, the codegen should use the schema name consistently: Both typescript and typescript-operations plugins should reference the enum by the same name

Screenshots or Videos

No response

Platform

  • OS: [e.g. macOS, Windows, Linux]
  • NodeJS: [e.g. 18.5.0]
  • graphql version: [e.g. 16.3.0]
  • @graphql-codegen/* version(s): [e.g. 2.6.2]

Codegen Config File

No response

Additional context

No response

ItaiYosephi avatar Oct 23 '25 12:10 ItaiYosephi

Hello! We are looking to improve client types in the upcoming major version: https://github.com/dotansimha/graphql-code-generator/issues/10479 This looks like it'd be solved by that. Let me know what you think!

eddeee888 avatar Nov 04 '25 07:11 eddeee888

Hi @eddeee888! Thank you for directing me to the improvements planned for the next major version. I appreciate the ongoing efforts to enhance client types. In our monorepo setup, we have two distinct schemas and several shared enums (and types...) that are used across both schemas. Our aim is to generate these shared enums in a dedicated package within the monorepo, ensuring that any application using either schema 1 or schema 2 can utilize these enums consistently. Currently, ⁠importSchemaTypesFrom: './types.generated.ts' doesn't fully support sharing enums across schemas. While ⁠enumValues can map GraphQL enums to TypeScript enums, it requires manual configuration, which is not ideal. If ⁠enumValues remains compatible with ⁠importSchemaTypesFrom: true, that would suffice, but addressing the bug I reported is still crucial. Ideally, having a seamless way to ensure all shared enums are used from the shared package would be even better. I hope this clarifies our challenges. Any insights on how the upcoming changes might address these would be greatly appreciated! Thank you!

ItaiYosephi avatar Nov 04 '25 09:11 ItaiYosephi

In our monorepo setup, we have two distinct schemas and several shared enums (and types...) that are used across both schemas. Our aim is to generate these shared enums in a dedicated package within the monorepo, ensuring that any application using either schema 1 or schema 2 can utilize these enums consistently.

This is interesting! I usually don't recommend sharing enum from two different schema as they may evolve independently. Would generating types into 2 shared packages, one for each schema work for you?

Note that when we move to the new major version, the "shared" generated types of a schema will be influenced by the document of each schema i.e. we cannot really share types between schema. Another way to think about it is just because the values look the same between schemas, it doesn't mean they should be shared,

eddeee888 avatar Nov 06 '25 12:11 eddeee888

@eddeee888 The reason we share those enum is that they always need to be the same for our client app and backoffice app. doesn't make sense to duplicate them.

  1. In the next major version, the old setup will still be available? we actually need to generate all types of the schema for various things.
  2. Are you planning on fixing the underlying Issue?

ItaiYosephi avatar Nov 12 '25 07:11 ItaiYosephi

Hi @ItaiYosephi ,

Could you help me understand the following:

  • Do client apps and backoffice apps use two separate GraphQL backends?
  • Could you please share your codegen config?

In the next major version, the old setup will still be available? we actually need to generate all types of the schema for various things.

The old setup will change for client use case. However, you can generate schema types for using typescript. Could you let me know what your use cases are?

Are you planning on fixing the underlying Issue?

Yes, I'll capture this to fix in the major version. It probably won't be an issue as it'd be in the same plugin (i.e. naming convention will sync up)

eddeee888 avatar Nov 15 '25 00:11 eddeee888

Do client apps and backoffice apps use two separate GraphQL backends? yes

Could you please share your codegen config? nothing special about it, we just have 3 configs, 1 for each app, and one for the shared enums

The old setup will change for client use case. However, you can generate schema types for using typescript. Could you let me know what your use cases are? we use the full schema to created a typed version for Apollo InMemoryCache.typePolicies. I;m sure we have other usages too

ItaiYosephi avatar Dec 15 '25 11:12 ItaiYosephi

nothing special about it, we just have 3 configs, 1 for each app, and one for the shared enums

I'm keen to understand if they'd be generating code from the same schema or a different one. With the new version, only used enums will be generated, so there'd be less sharing types between multiple generations

eddeee888 avatar Dec 16 '25 12:12 eddeee888