Repository: depcheck/depcheck
Pull request #726 (2022-06-03 17:24:57)

Add support for graphql imports
This scans graphql documents for imports using the format supported by `graphql-tag` and some other graphql tools.

Fixes https://github.com/depcheck/depcheck/issues/722



Patch:
diff --git a/src/component.json b/src/component.json
index c313655..4158694 100644
--- a/src/component.json
+++ b/src/component.json
@@ -4,6 +4,7 @@
     "coffee",
     "es6",
     "es7",
+    "graphql",
     "jsx",
     "sass",
     "typescript",
diff --git a/src/constants.js b/src/constants.js
index 0093997..694e308 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -52,6 +52,7 @@ export const defaultOptions = {
     '**/*.coffee': availableParsers.coffee,
     '**/*.litcoffee': availableParsers.coffee,
     '**/*.coffee.md': availableParsers.coffee,
+    '**/*.graphql': availableParsers.graphql,
     '**/*.ts': availableParsers.typescript,
     '**/*.tsx': availableParsers.typescript,
     '**/*.sass': availableParsers.sass,
diff --git a/src/parser/graphql.js b/src/parser/graphql.js
new file mode 100644
index 0000000..5237390
--- /dev/null
+++ b/src/parser/graphql.js
@@ -0,0 +1,23 @@
+const { readFileSync } = require('fs');
+const requirePackageName = require('require-package-name');
+const JSON5 = require('json5');
+
+export default function graphqlParser(filePath) {
+  const foundDeps = [];
+  const content = readFileSync(filePath, { encoding: 'utf8' });
+  const lines = content.split(/\r\n|\r|\n/);
+  lines.some((line) => {
+    if (line[0] === '#' && line.slice(1).split(' ')[0] === 'import') {
+      const importFileExpr = line.slice(1).split(' ')[1];
+      if (importFileExpr) {
+        // Need to support single and double quotes, so use JSON5
+        const importFile = JSON5.parse(importFileExpr);
+        if (importFile && typeof importFile === 'string') {
+          foundDeps.push(importFile);
+        }
+      }
+    }
+    return line.length !== 0 && line[0] !== '#';
+  });
+  return foundDeps.map((p) => requirePackageName(p)).filter(Boolean);
+}


Test patch:
diff --git a/test/fake_modules/graphql/package.json b/test/fake_modules/graphql/package.json
new file mode 100644
index 0000000..e345638
--- /dev/null
+++ b/test/fake_modules/graphql/package.json
@@ -0,0 +1,9 @@
+{
+  "name": "graphql-depcheck-test",
+  "version": "1.0.0",
+  "dependencies": {
+    "unused": "*",
+    "@scope/ok": "*",
+    "ok": "*"
+  }
+}
diff --git a/test/fake_modules/graphql/test.graphql b/test/fake_modules/graphql/test.graphql
new file mode 100644
index 0000000..572dc54
--- /dev/null
+++ b/test/fake_modules/graphql/test.graphql
@@ -0,0 +1,5 @@
+#import "./foo.graphql"
+#import "ok/test.graphql"
+#import "@scope/ok/test.graphql"
+#import "@scope/missing/missing.graphql"
+#import "missing/missing.graphql"
diff --git a/test/spec.js b/test/spec.js
index 8ee47aa..1e651ac 100755
--- a/test/spec.js
+++ b/test/spec.js
@@ -868,4 +868,24 @@ export default [
     },
     expectedErrorCode: -1,
   },
+  {
+    name: 'find dependencies in graphql files',
+    module: 'graphql',
+    options: {},
+    expected: {
+      dependencies: ['unused'],
+      devDependencies: [],
+      missing: {
+        '@scope/missing': ['test.graphql'],
+        missing: ['test.graphql'],
+      },
+      using: {
+        '@scope/missing': ['test.graphql'],
+        '@scope/ok': ['test.graphql'],
+        missing: ['test.graphql'],
+        ok: ['test.graphql'],
+      },
+    },
+    expectedErrorCode: -1,
+  },
 ];