Skip to content

Commit

Permalink
Strip duplicate fragments from AST
Browse files Browse the repository at this point in the history
While duplicate fragments will result in “warnings”, generating a document with duplicate fragments results in an invalid GraphQL document. This was recently introduced when fragment interpolation became the defacto way to insert fragments.

See upstream issue [here](apollographql#27). This is not intended to go upstream (yet).
  • Loading branch information
jnwng committed Dec 7, 2016
1 parent 31de61a commit f1da831
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
13 changes: 10 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ function resetCaches() {
// check all fragment definitions, checking for name->source uniqueness
var printFragmentWarnings = true;
function checkFragments(ast) {
for (var i = 0; i < ast.definitions.length; i++) {
var fragmentDefinition = ast.definitions[i];
const astFragmentMap = {};
ast.definitions = ast.definitions.filter(fragmentDefinition => {
if (fragmentDefinition.kind === 'FragmentDefinition') {
var fragmentName = fragmentDefinition.name.value;
var sourceKey = cacheKeyFromLoc(fragmentDefinition.loc);
Expand All @@ -51,7 +51,14 @@ function checkFragments(ast) {
fragmentSourceMap[fragmentName][sourceKey] = true;
}
}
}

if (!astFragmentMap[sourceKey]) {
astFragmentMap[sourceKey] = true;
return true;
} else {
return false;
}
});
}

function disableFragmentWarnings() {
Expand Down
14 changes: 14 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,20 @@ const assert = require('chai').assert;
});
});

describe('fragment de-duplication', () => {
beforeEach(() => {
gqlRequire.resetCaches();
});

it('strips duplicate fragments from the document', () => {
const frag1 = gql`fragment TestDuplicate on Bar { field }`;
const query1 = gql`{ bar { fieldOne ...TestDuplicate } } ${frag1} ${frag1}`;

assert.equal(query1.definitions.length, 2);
assert.equal(query1.definitions[1].kind, 'FragmentDefinition')
});
});

// How to make this work?
// it.only('can reference a fragment passed as a document via shorthand', () => {
// const ast = gql`
Expand Down

0 comments on commit f1da831

Please sign in to comment.