1 | import {
|
2 | validate,
|
3 | specifiedRules,
|
4 | NoUnusedFragmentsRule,
|
5 | KnownDirectivesRule,
|
6 | GraphQLError,
|
7 | FieldNode,
|
8 | ValidationContext,
|
9 | GraphQLSchema,
|
10 | DocumentNode,
|
11 | OperationDefinitionNode
|
12 | } from 'graphql';
|
13 |
|
14 | import { ToolError, logError } from 'apollo-codegen-core/lib/errors';
|
15 |
|
16 | export function validateQueryDocument(schema: GraphQLSchema, document: DocumentNode) {
|
17 | const specifiedRulesToBeRemoved = [NoUnusedFragmentsRule, KnownDirectivesRule];
|
18 |
|
19 | const rules = [
|
20 | NoAnonymousQueries,
|
21 | NoTypenameAlias,
|
22 | ...specifiedRules.filter(rule => !specifiedRulesToBeRemoved.includes(rule))
|
23 | ];
|
24 |
|
25 | const validationErrors = validate(schema, document, rules);
|
26 | if (validationErrors && validationErrors.length > 0) {
|
27 | for (const error of validationErrors) {
|
28 | logError(error);
|
29 | }
|
30 | throw new ToolError('Validation of GraphQL query document failed');
|
31 | }
|
32 | }
|
33 |
|
34 | export function NoAnonymousQueries(context: ValidationContext) {
|
35 | return {
|
36 | OperationDefinition(node: OperationDefinitionNode) {
|
37 | if (!node.name) {
|
38 | context.reportError(new GraphQLError('Apollo does not support anonymous operations', [node]));
|
39 | }
|
40 | return false;
|
41 | }
|
42 | };
|
43 | }
|
44 |
|
45 | export function NoTypenameAlias(context: ValidationContext) {
|
46 | return {
|
47 | Field(node: FieldNode) {
|
48 | const aliasName = node.alias && node.alias.value;
|
49 | if (aliasName == '__typename') {
|
50 | context.reportError(
|
51 | new GraphQLError(
|
52 | 'Apollo needs to be able to insert __typename when needed, please do not use it as an alias',
|
53 | [node]
|
54 | )
|
55 | );
|
56 | }
|
57 | }
|
58 | };
|
59 | }
|