Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.

fix(lsp): surface unused fragment definition leaves (#299)

Changed files
+27 -5
.changeset
packages
example-tada
graphqlsp
+5
.changeset/wise-coins-look.md
···
+
---
+
'@0no-co/graphqlsp': patch
+
---
+
+
Correctly identify unused fields on a fragment-definition, these have no parent to group by so we display them as unused leaves
+1
packages/example-tada/src/Pokemon.tsx
···
export const Fields = { Pokemon: graphql(`
fragment Pok on Pokemon {
resistant
+
types
}`)
}
+21 -5
packages/graphqlsp/src/fieldUsage.ts
···
const unused = allPaths.filter(x => !allAccess.includes(x));
const aggregatedUnusedFields = new Set<string>();
const unusedChildren: { [key: string]: Set<string> } = {};
+
const unusedFragmentLeaf = new Set<string>();
unused.forEach(unusedField => {
const split = unusedField.split('.');
split.pop();
const parentField = split.join('.');
const loc = fieldToLoc.get(parentField);
-
if (!loc) return;
-
aggregatedUnusedFields.add(parentField);
-
if (unusedChildren[parentField]) {
-
unusedChildren[parentField].add(unusedField);
+
if (loc) {
+
aggregatedUnusedFields.add(parentField);
+
if (unusedChildren[parentField]) {
+
unusedChildren[parentField].add(unusedField);
+
} else {
+
unusedChildren[parentField] = new Set([unusedField]);
+
}
} else {
-
unusedChildren[parentField] = new Set([unusedField]);
+
unusedFragmentLeaf.add(unusedField);
}
});
···
messageText: `Field(s) ${[...unusedFields]
.map(x => `'${x}'`)
.join(', ')} are not used.`,
+
});
+
});
+
+
unusedFragmentLeaf.forEach(field => {
+
const loc = fieldToLoc.get(field)!;
+
diagnostics.push({
+
file: source,
+
length: loc.length,
+
start: node.getStart() + loc.start + 1,
+
category: ts.DiagnosticCategory.Warning,
+
code: UNUSED_FIELD_CODE,
+
messageText: `Field ${field} is not used.`,
});
});
});