diff --git a/.changeset/wide-cities-grin.md b/.changeset/wide-cities-grin.md new file mode 100644 index 0000000..d9bf64c --- /dev/null +++ b/.changeset/wide-cities-grin.md @@ -0,0 +1,5 @@ +--- +'@0no-co/graphqlsp': minor +--- + +Improves field-usage tracking, we bail when the identifier is passed into a function, this bail is intended so we don't have to traverse the whole codebase tracing down usage. diff --git a/packages/graphqlsp/src/fieldUsage.ts b/packages/graphqlsp/src/fieldUsage.ts index 2b5b138..f83e8b4 100644 --- a/packages/graphqlsp/src/fieldUsage.ts +++ b/packages/graphqlsp/src/fieldUsage.ts @@ -283,6 +283,35 @@ const crawlScope = ( if (allFields.find(x => x.startsWith(joined + '.'))) { pathParts.push(foundRef.text); } + + // When we encounter an external function where we use this identifier + // we'll mark all of the sub-fields as used as we consider this a bail + // scenario. + if (ts.isCallExpression(foundRef.parent)) { + const callExpression = foundRef.parent; + return callExpression.arguments.flatMap(arg => { + let parts = [...pathParts]; + let reference = arg; + + while (ts.isPropertyAccessExpression(reference)) { + const joined = [...parts, reference.name.text].join('.'); + if (allFields.find(x => x.startsWith(joined + '.'))) { + parts.push(reference.name.text); + } + reference = reference.expression; + } + + if (ts.isIdentifier(reference)) { + const joined = [...parts, reference.getText()].join('.'); + if (allFields.find(x => x.startsWith(joined + '.'))) { + parts.push(reference.getText()); + } + } + + const joined = parts.join('.'); + return allFields.filter(x => x.startsWith(joined + '.')); + }); + } } else if ( ts.isPropertyAccessExpression(foundRef) && foundRef.name.text === 'at' &&