Skip to content

Commit 7d75f61

Browse files
authored
Fixes for sibling operations and graphql-config (#190)
1 parent beb0086 commit 7d75f61

File tree

4 files changed

+55
-23
lines changed

4 files changed

+55
-23
lines changed

.changeset/six-fans-leave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-eslint/eslint-plugin': patch
3+
---
4+
5+
Better integration of siblings operations and graphql-config

packages/plugin/src/parser.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ import { GraphQLESLintParseResult, ParserOptions } from './types';
66
import { extractTokens } from './utils';
77
import { getSchema } from './schema';
88
import { getSiblingOperations } from './sibling-operations';
9+
import { loadConfigSync, GraphQLConfig } from 'graphql-config';
910

1011
export function parse(code: string, options?: ParserOptions): Linter.ESLintParseResult['ast'] {
1112
return parseForESLint(code, options).ast;
1213
}
1314

1415
export function parseForESLint(code: string, options?: ParserOptions): GraphQLESLintParseResult {
15-
const schema = getSchema(options);
16-
const operationsPaths = options.operations || [];
17-
const siblingOperations = getSiblingOperations(
18-
process.cwd(),
19-
Array.isArray(operationsPaths) ? operationsPaths : [operationsPaths]
20-
);
16+
const gqlConfig: GraphQLConfig | null = options?.skipGraphQLConfig
17+
? null
18+
: loadConfigSync({
19+
throwOnEmpty: false,
20+
throwOnMissing: false,
21+
});
22+
23+
const schema = getSchema(options, gqlConfig);
24+
const siblingOperations = getSiblingOperations(options, gqlConfig);
2125
const parserServices = {
2226
hasTypeInfo: schema !== null,
2327
schema,

packages/plugin/src/schema.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { JsonFileLoader } from '@graphql-tools/json-file-loader';
33
import { loadSchemaSync } from '@graphql-tools/load';
44
import { UrlLoader } from '@graphql-tools/url-loader';
55
import { buildSchema, GraphQLSchema } from 'graphql';
6-
import { loadConfigSync } from 'graphql-config';
6+
import { GraphQLConfig, loadConfigSync } from 'graphql-config';
77
import { dirname } from 'path';
88
import { ParserOptions } from './types';
99

1010
const schemaCache: Map<string, GraphQLSchema> = new Map();
1111

12-
export function getSchema(options: ParserOptions): GraphQLSchema | null {
12+
export function getSchema(options: ParserOptions, gqlConfig: GraphQLConfig): GraphQLSchema | null {
1313
let schema: GraphQLSchema | null = null;
1414

1515
// We first try to use graphql-config for loading the schema, based on the type of the file,
@@ -20,11 +20,6 @@ export function getSchema(options: ParserOptions): GraphQLSchema | null {
2020
if (schemaCache.has(fileDir)) {
2121
schema = schemaCache.get(fileDir);
2222
} else {
23-
const gqlConfig = loadConfigSync({
24-
throwOnEmpty: false,
25-
throwOnMissing: false,
26-
});
27-
2823
if (gqlConfig) {
2924
const projectForFile = gqlConfig.getProject(options.filePath);
3025

packages/plugin/src/sibling-operations.ts

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import {
1111
SelectionSetNode,
1212
visit,
1313
} from 'graphql';
14+
import { ParserOptions } from './types';
15+
import { GraphQLConfig } from 'graphql-config';
16+
import { dirname } from 'path';
1417

1518
export type SiblingOperations = {
1619
available: boolean;
@@ -47,8 +50,41 @@ function loadSiblings(baseDir: string, loadPaths: string[]): Source[] {
4750

4851
const operationsCache: Map<string, Source[]> = new Map();
4952

50-
export function getSiblingOperations(baseDir: string, loadPaths: string[]): SiblingOperations {
51-
if (loadPaths.length === 0) {
53+
export function getSiblingOperations(options: ParserOptions, gqlConfig: GraphQLConfig): SiblingOperations {
54+
let siblings: Source[] | null = null;
55+
56+
// We first try to use graphql-config for loading the operations paths, based on the type of the file,
57+
// We are using the directory of the file as the key for the schema caching, to avoid reloading of the schema.
58+
if (options && options.filePath && !options.skipGraphQLConfig) {
59+
const fileDir = dirname(options.filePath);
60+
61+
if (operationsCache.has(fileDir)) {
62+
siblings = operationsCache.get(fileDir);
63+
} else {
64+
if (gqlConfig) {
65+
const projectForFile = gqlConfig.getProject(options.filePath);
66+
67+
if (projectForFile) {
68+
siblings = projectForFile.getDocumentsSync();
69+
operationsCache.set(fileDir, siblings);
70+
}
71+
}
72+
}
73+
}
74+
75+
if (options && options.operations && !siblings) {
76+
const loadPaths = Array.isArray(options.operations) ? options.operations : [options.operations] || [];
77+
const loadKey = loadPaths.join(',');
78+
79+
if (!operationsCache.has(loadKey)) {
80+
siblings = loadSiblings(process.cwd(), loadPaths);
81+
operationsCache.set(loadKey, siblings);
82+
} else {
83+
siblings = operationsCache.get(loadKey);
84+
}
85+
}
86+
87+
if (!siblings || siblings.length === 0) {
5288
let printed = false;
5389

5490
const noopWarn = () => {
@@ -76,14 +112,6 @@ export function getSiblingOperations(baseDir: string, loadPaths: string[]): Sibl
76112
getUsedFragments: noopWarn,
77113
};
78114
}
79-
const loadKey = loadPaths.join(',');
80-
81-
if (!operationsCache.has(loadKey)) {
82-
const loadedSiblings = loadSiblings(baseDir, loadPaths);
83-
operationsCache.set(loadKey, loadedSiblings);
84-
}
85-
86-
const siblings = operationsCache.get(loadKey);
87115

88116
let fragmentsCache: FragmentDefinitionNode[] | null = null;
89117

0 commit comments

Comments
 (0)