in src/rule-must-colocate-fragment-spreads.js [116:189]
function rule(context) {
const foundImportedModules = [];
const graphqlLiterals = [];
return {
'Program:exit'(_node) {
const fragmentsInTheSameModule = [];
graphqlLiterals.forEach(({graphQLAst}) => {
const fragmentName = getGraphQLFragmentDefinitionName(graphQLAst);
if (fragmentName) {
fragmentsInTheSameModule.push(fragmentName);
}
});
graphqlLiterals.forEach(({node, graphQLAst}) => {
const queriedFragments = getGraphQLFragmentSpreads(graphQLAst);
for (const fragment in queriedFragments) {
const matchedModuleName = foundImportedModules.find(name =>
fragment.startsWith(name)
);
if (
!matchedModuleName &&
!fragmentsInTheSameModule.includes(fragment)
) {
context.report({
node,
loc: utils.getLoc(context, node, queriedFragments[fragment]),
message:
`This spreads the fragment \`${fragment}\` but ` +
'this module does not use it directly. If a different module ' +
'needs this information, that module should directly define a ' +
'fragment querying for that data, colocated next to where the ' +
'data is used.\n'
});
}
}
});
},
ImportDeclaration(node) {
if (node.importKind === 'value') {
foundImportedModules.push(utils.getModuleName(node.source.value));
}
},
ImportExpression(node) {
if (node.source.type === 'Literal') {
// Allow dynamic imports like import(`test/${fileName}`); and (path) => import(path);
// These would have node.source.value undefined
foundImportedModules.push(utils.getModuleName(node.source.value));
}
},
CallExpression(node) {
if (node.callee.name !== 'require') {
return;
}
const [source] = node.arguments;
if (source && source.type === 'Literal') {
foundImportedModules.push(utils.getModuleName(source.value));
}
},
TaggedTemplateExpression(node) {
if (utils.isGraphQLTemplate(node)) {
const graphQLAst = utils.getGraphQLAST(node);
if (!graphQLAst) {
// ignore nodes with syntax errors, they're handled by rule-graphql-syntax
return;
}
graphqlLiterals.push({node, graphQLAst});
}
}
};
}