-
-
Notifications
You must be signed in to change notification settings - Fork 100
/
parser.ts
69 lines (60 loc) · 2.29 KB
/
parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { parseGraphQLSDL } from '@graphql-tools/utils';
import { ASTNode, GraphQLError, TypeInfo, Source } from 'graphql';
import { Linter } from 'eslint';
import { convertToESTree } from './estree-parser';
import { GraphQLESLintParseResult, ParserOptions, ParserServices } from './types';
import { extractTokens } from './utils';
import { getSchema } from './schema';
import { getSiblingOperations } from './sibling-operations';
import { loadGraphqlConfig } from './graphql-config';
import { getReachableTypes, getUsedFields } from './graphql-ast';
export function parse(code: string, options?: ParserOptions): Linter.ESLintParseResult['ast'] {
return parseForESLint(code, options).ast;
}
export function parseForESLint(code: string, options: ParserOptions = {}): GraphQLESLintParseResult {
const gqlConfig = loadGraphqlConfig(options);
const schema = getSchema(options, gqlConfig);
const parserServices: ParserServices = {
hasTypeInfo: schema !== null,
schema,
siblingOperations: getSiblingOperations(options, gqlConfig),
reachableTypes: getReachableTypes,
usedFields: getUsedFields,
};
try {
const filePath = options.filePath || '';
const graphqlAst = parseGraphQLSDL(filePath, code, {
...options.graphQLParserOptions,
noLocation: false,
});
const { rootTree, comments } = convertToESTree(graphqlAst.document as ASTNode, schema ? new TypeInfo(schema) : null);
const tokens = extractTokens(new Source(code, filePath));
return {
services: parserServices,
parserServices,
ast: {
type: 'Program',
body: [rootTree as any],
sourceType: 'script',
comments,
loc: rootTree.loc,
range: rootTree.range as [number, number],
tokens,
},
};
} catch (e) {
// In case of GraphQL parser error, we report it to ESLint as a parser error that matches the requirements
// of ESLint. This will make sure to display it correctly in IDEs and lint results.
if (e instanceof GraphQLError) {
const eslintError = {
index: e.positions[0],
lineNumber: e.locations[0].line,
column: e.locations[0].column,
message: `[graphql-eslint]: ${e.message}`,
};
throw eslintError;
}
e.message = `[graphql-eslint]: ${e.message}`;
throw e;
}
}