typescript-operations plugin duplicates fragment type when document is matched twice
originally reported as: https://github.com/dotansimha/graphql-code-generator/issues/10170
Which packages are impacted by your issue?
@graphql-codegen/near-operation-file-preset
Describe the bug
When typescript-operations plugin is used with @graphql-codegen/near-operation-file-preset and the documents config has overlapping patterns meaning a file is matched by more than a single pattern the generated file contains multiple type exports with conflicting name.
Your Example Website or App
https://stackblitz.com/edit/github-kq5wbr?file=codegen.ts,src%2Ffragment.generated.ts
Steps to Reproduce the Bug or Issue
- Go to
src/fragment.generated.tsand seeMyExampleFragmentis duplicated - Go to
codegen.ts - Comment out
'src/fragment.graphql',from the documents config - Run
yarn generate - See that
src/fragment.generated.tshas no duplication
Expected behavior
There is no duplication regardless of overlapping documents configuration
Screenshots or Videos
No response
Platform
- OS: macOs
- NodeJS: 20.10.0
graphqlversion: 16.9.0@graphql-codegen/*version(s): 4.0.1@graphql-codegen/near-operation-file-preset: 3.0.0
Codegen Config File
import { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: 'schema.graphql',
documents: [
'document.graphql',
'src/*.graphql',
// Enforce duplication, fragment is already matched by the rule above
// comment out the next line to prevent duplication
'src/fragment.graphql',
],
generates: {
'types.ts': {
plugins: ['typescript'],
},
src: {
preset: 'near-operation-file',
plugins: ['typescript-operations'],
presetConfig: {
baseTypesPath: '../types.ts',
},
},
},
};
export default config;
Additional context
Symptoms
The generated file:
import * as Types from '../types';
export type MyExampleFragment = { __typename?: 'User', id: string, username: string };
export type MyExampleFragment = { __typename?: 'User', id: string, username: string };
Research
Documents here https://github.com/dotansimha/graphql-code-generator/blob/a23505180ac2f275a55ece27162ec9bfcdc52e03/packages/plugins/typescript/operations/src/index.ts#L14
carry the duplicated fragment SDL
[
{
rawSDL: 'fragment MyExample on User {\n' +
' id\n' +
' username\n' +
'}fragment MyExample on User {\n' +
' id\n' +
' username\n' +
'}',
document: { kind: 'Document', definitions: [Array] },
location: '...'
}
]
without the preset they are 2 documents:
[
{
location: '...',
document: { kind: 'Document', definitions: [Array] },
rawSDL: 'fragment MyExample on User {\n id\n username\n}',
hash: '...'
},
{
location: '....',
document: { kind: 'Document', definitions: [] },
rawSDL: 'fragment MyExample on User {\n id\n username\n}',
hash: '...'
}
]
I added a failing test in https://github.com/ertrzyiks/graphql-code-generator-community/commit/eb448b2d4a04ce8d257b05ab5b3b8af29da39235
It's interesting that it breaks only if patterns are different. When the test is defined with the same path duplicated it works properly:
documents: [
path.join(__dirname, 'fixtures/issue-new-pattern.ts'),
path.join(__dirname, 'fixtures/issue-new-pattern.ts'),
]
There must be some deduplication in place on the pattern level, but it fails to deduplicate when patterns are different:
documents: [
path.join(__dirname, 'fixtures/issue-new-pattern.ts'),
path.join(__dirname, 'fixtures/issue-*-pattern.ts'), // <- notice the * in the pattern
]