diff --git a/packages/presets/near-operation-file/src/index.ts b/packages/presets/near-operation-file/src/index.ts index 8d669ded9..956f7d469 100644 --- a/packages/presets/near-operation-file/src/index.ts +++ b/packages/presets/near-operation-file/src/index.ts @@ -325,7 +325,16 @@ export const preset: Types.OutputPreset = { const artifacts: Array = []; for (const [filename, record] of filePathsMap.entries()) { + const fragmentNames = new Set(); let fragmentImportsArr = record.fragmentImports; + const externalFragments = record.externalFragments.filter(fragment => { + if (fragmentNames.has(fragment.name)) { + return false; + } + + fragmentNames.add(fragment.name); + return true; + }); if (importAllFragmentsFrom) { fragmentImportsArr = record.fragmentImports.map>(t => { @@ -377,7 +386,7 @@ export const preset: Types.OutputPreset = { // are exported from operations file exportFragmentSpreadSubTypes: true, namespacedImportName: importTypesNamespace, - externalFragments: record.externalFragments, + externalFragments, fragmentImports: fragmentImportsArr, }; diff --git a/packages/presets/near-operation-file/tests/near-operation-file.spec.ts b/packages/presets/near-operation-file/tests/near-operation-file.spec.ts index 577e4c988..c17bd7d2a 100644 --- a/packages/presets/near-operation-file/tests/near-operation-file.spec.ts +++ b/packages/presets/near-operation-file/tests/near-operation-file.spec.ts @@ -85,6 +85,53 @@ describe('near-operation-file preset', () => { ]; describe('Issues', () => { + it('dedupes repeated external fragments when multiple documents are merged into the same output file', async () => { + const result = await executePreset({ + baseOutputDir: './src/', + config: {}, + presetConfig: { + cwd: '/some/deep/path', + baseTypesPath: 'types.ts', + fileName: 'types', + }, + schemaAst: schemaNode, + schema: getCachedDocumentNodeFromSchema(schemaNode), + documents: [ + { + location: '/some/deep/path/src/graphql/query-a.graphql', + document: parse(/* GraphQL */ ` + query QueryA { + user { + ...UserFields + } + } + `), + }, + { + location: '/some/deep/path/src/graphql/query-b.graphql', + document: parse(/* GraphQL */ ` + query QueryB { + user { + ...UserFields + } + } + `), + }, + { + location: '/some/deep/path/src/graphql/user-fragment.graphql', + document: fragmentAst, + }, + ], + plugins: [], + pluginMap: {}, + }); + + expect(result).toHaveLength(1); + expect(result[0].filename).toBe('/some/deep/path/src/graphql/types.generated.ts'); + expect(result[0].config.externalFragments).toHaveLength(1); + expect(result[0].config.externalFragments[0].name).toBe('UserFields'); + }); + it('#5002 - error when inline fragment does not specify the name of the type', async () => { const testSchema = parse(/* GraphQL */ ` scalar Date