diff --git a/src/utilities/__tests__/separateOperations-test.js b/src/utilities/__tests__/separateOperations-test.js index 4240705396..3130966fdd 100644 --- a/src/utilities/__tests__/separateOperations-test.js +++ b/src/utilities/__tests__/separateOperations-test.js @@ -161,4 +161,53 @@ describe('separateOperations', () => { } `); }); + + it('only includes fragments that are used', () => { + const ast = parse(` + fragment One on T { + oneField + ...Three + } + + fragment Two on T { + twoField + } + + fragment Three on T { + threeField + } + + query One { + ...Two + } + + query Ones { + ...One + } + + query Twos { + ...One + ...Two + } + `); + + const separatedASTs = separateOperations(ast); + + expect(separatedASTs).to.have.all.keys('One', 'Ones', 'Twos'); + + expect(print(separatedASTs.Ones)).to.equal(dedent` + fragment One on T { + oneField + ...Three + } + + fragment Three on T { + threeField + } + + query Ones { + ...One + } + `); + }); }); diff --git a/src/utilities/separateOperations.js b/src/utilities/separateOperations.js index f7be8f5cb9..3c39457ecd 100644 --- a/src/utilities/separateOperations.js +++ b/src/utilities/separateOperations.js @@ -20,14 +20,14 @@ export function separateOperations( // Populate metadata and build a dependency graph. visit(documentAST, { OperationDefinition(node) { - fromName = opName(node); + fromName = opSuffix(opName(node)); operations.push(node); }, FragmentDefinition(node) { - fromName = node.name.value; + fromName = fragSuffix(node.name.value); }, FragmentSpread(node) { - const toName = node.name.value; + const toName = fragSuffix(node.name.value); let dependents = depGraph[fromName]; if (dependents === undefined) { dependents = depGraph[fromName] = Object.create(null); @@ -42,7 +42,11 @@ export function separateOperations( for (const operation of operations) { const operationName = opName(operation); const dependencies = Object.create(null); - collectTransitiveDependencies(dependencies, depGraph, operationName); + collectTransitiveDependencies( + dependencies, + depGraph, + opSuffix(operationName), + ); // The list of definition nodes to be included for this operation, sorted // to retain the same order as the original document. @@ -52,7 +56,7 @@ export function separateOperations( (node) => node === operation || (node.kind === Kind.FRAGMENT_DEFINITION && - dependencies[node.name.value]), + dependencies[fragSuffix(node.name.value)]), ), }; } @@ -67,6 +71,16 @@ function opName(operation: OperationDefinitionNode): string { return operation.name ? operation.name.value : ''; } +// Adds a suffix to differentiate operations +function opSuffix(operationName: string): string { + return `${operationName}${Kind.OPERATION_DEFINITION}`; +} + +// Adds a suffix to differentiate fragments +function fragSuffix(fragmentName: string): string { + return `${fragmentName}${Kind.FRAGMENT_DEFINITION}`; +} + // From a dependency graph, collects a list of transitive dependencies by // recursing through a dependency graph. function collectTransitiveDependencies(