@graphql-eslint/eslint-plugin
Version:
GraphQL plugin for ESLint
84 lines (81 loc) • 2.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.rule = void 0;
const utils_js_1 = require("../utils.js");
const path_1 = require("path");
const graphql_1 = require("graphql");
const RULE_ID = 'no-one-place-fragments';
exports.rule = {
meta: {
type: 'suggestion',
docs: {
category: 'Operations',
description: 'Disallow fragments that are used only in one place.',
url: `https://github.com/B2o5T/graphql-eslint/blob/master/docs/rules/${RULE_ID}.md`,
examples: [
{
title: 'Incorrect',
code: /* GraphQL */ `
fragment UserFields on User {
id
}
{
user {
...UserFields
}
}
`,
},
{
title: 'Correct',
code: /* GraphQL */ `
fragment UserFields on User {
id
}
{
user {
...UserFields
friends {
...UserFields
}
}
}
`,
},
],
requiresSiblings: true,
},
messages: {
[RULE_ID]: 'Fragment `{{fragmentName}}` used only once. Inline him in "{{filePath}}".',
},
schema: [],
},
create(context) {
const operations = (0, utils_js_1.requireSiblingsOperations)(RULE_ID, context);
const allDocuments = [...operations.getOperations(), ...operations.getFragments()];
const usedFragmentsMap = Object.create(null);
for (const { document, filePath } of allDocuments) {
const relativeFilePath = (0, path_1.relative)(utils_js_1.CWD, filePath);
(0, graphql_1.visit)(document, {
FragmentSpread({ name }) {
const spreadName = name.value;
usedFragmentsMap[spreadName] || (usedFragmentsMap[spreadName] = []);
usedFragmentsMap[spreadName].push(relativeFilePath);
},
});
}
return {
'FragmentDefinition > Name'(node) {
const fragmentName = node.value;
const fragmentUsage = usedFragmentsMap[fragmentName];
if (fragmentUsage.length === 1) {
context.report({
node,
messageId: RULE_ID,
data: { fragmentName, filePath: fragmentUsage[0] },
});
}
},
};
},
};