Skip to content

Commit 6b3175d

Browse files
committed
remove interface inheritance from validate directive combination rule
1 parent ae12676 commit 6b3175d

File tree

1 file changed

+9
-105
lines changed

1 file changed

+9
-105
lines changed

packages/graphql/src/schema/validation/custom-rules/valid-types/valid-directive-combination.ts

Lines changed: 9 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -17,127 +17,31 @@
1717
* limitations under the License.
1818
*/
1919

20-
import type {
21-
ASTVisitor,
22-
DirectiveNode,
23-
ASTNode,
24-
InterfaceTypeDefinitionNode,
25-
ObjectTypeDefinitionNode,
26-
EnumTypeDefinitionNode,
27-
EnumTypeExtensionNode,
28-
EnumValueDefinitionNode,
29-
FieldDefinitionNode,
30-
FieldNode,
31-
FragmentDefinitionNode,
32-
FragmentSpreadNode,
33-
InlineFragmentNode,
34-
InputObjectTypeDefinitionNode,
35-
InputObjectTypeExtensionNode,
36-
InputValueDefinitionNode,
37-
InterfaceTypeExtensionNode,
38-
ObjectTypeExtensionNode,
39-
OperationDefinitionNode,
40-
ScalarTypeDefinitionNode,
41-
ScalarTypeExtensionNode,
42-
SchemaDefinitionNode,
43-
SchemaExtensionNode,
44-
UnionTypeDefinitionNode,
45-
UnionTypeExtensionNode,
46-
VariableDefinitionNode,
47-
} from "graphql";
20+
import type { ASTVisitor, DirectiveNode, ASTNode } from "graphql";
4821
import { Kind, isTypeDefinitionNode, isTypeExtensionNode } from "graphql";
4922
import type { SDLValidationContext } from "graphql/validation/ValidationContext";
5023
import { invalidCombinations } from "../../utils/invalid-directive-combinations";
5124
import { assertValid, createGraphQLError, DocumentValidationError } from "../utils/document-validation-error";
52-
import {
53-
getInheritedTypeNames,
54-
hydrateInterfaceWithImplementedTypesMap,
55-
} from "../utils/interface-to-implementing-types";
5625
import { getPathToNode } from "../utils/path-parser";
5726

58-
type ASTNodeWithDirectives =
59-
| OperationDefinitionNode
60-
| VariableDefinitionNode
61-
| FieldNode
62-
| FragmentSpreadNode
63-
| InlineFragmentNode
64-
| FragmentDefinitionNode
65-
| SchemaDefinitionNode
66-
| ScalarTypeDefinitionNode
67-
| ObjectTypeDefinitionNode
68-
| FieldDefinitionNode
69-
| InputValueDefinitionNode
70-
| InterfaceTypeDefinitionNode
71-
| UnionTypeDefinitionNode
72-
| EnumTypeDefinitionNode
73-
| EnumValueDefinitionNode
74-
| InputObjectTypeDefinitionNode
75-
| SchemaExtensionNode
76-
| ScalarTypeExtensionNode
77-
| ObjectTypeExtensionNode
78-
| InterfaceTypeExtensionNode
79-
| UnionTypeExtensionNode
80-
| EnumTypeExtensionNode
81-
| InputObjectTypeExtensionNode;
8227
export function DirectiveCombinationValid(context: SDLValidationContext): ASTVisitor {
83-
const interfaceToImplementingTypes = new Map<string, Set<string>>();
84-
const typeToDirectivesPerFieldMap = new Map<string, Map<string, readonly DirectiveNode[]>>();
85-
const typeToDirectivesMap = new Map<string, readonly DirectiveNode[]>();
86-
const hydrateWithDirectives = function (
87-
node: ASTNodeWithDirectives,
88-
parentOfTraversedDef: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode | undefined
89-
) {
90-
if (node.kind === Kind.OBJECT_TYPE_DEFINITION || node.kind === Kind.INTERFACE_TYPE_DEFINITION) {
91-
typeToDirectivesMap.set(node.name.value, node.directives || []);
92-
}
93-
if (node.kind === Kind.FIELD_DEFINITION) {
94-
if (!parentOfTraversedDef) {
95-
return;
96-
}
97-
const seenFields =
98-
typeToDirectivesPerFieldMap.get(parentOfTraversedDef.name.value) ||
99-
new Map<string, readonly DirectiveNode[]>();
100-
seenFields.set(node.name.value, node.directives || []);
101-
typeToDirectivesPerFieldMap.set(parentOfTraversedDef.name.value, seenFields);
102-
}
103-
};
104-
const getDirectives = function (
105-
node: ASTNodeWithDirectives,
106-
parentOfTraversedDef: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode | undefined
107-
): DirectiveNode[] {
108-
const directivesToCheck: DirectiveNode[] = [...(node.directives || [])];
109-
if (node.kind === Kind.OBJECT_TYPE_DEFINITION || node.kind === Kind.INTERFACE_TYPE_DEFINITION) {
110-
return getInheritedTypeNames(node, interfaceToImplementingTypes).reduce((acc, i) => {
111-
const inheritedDirectives = typeToDirectivesMap.get(i) || [];
112-
return acc.concat(inheritedDirectives);
113-
}, directivesToCheck);
114-
}
115-
if (node.kind === Kind.FIELD_DEFINITION) {
116-
if (!parentOfTraversedDef) {
117-
return [];
118-
}
119-
return getInheritedTypeNames(parentOfTraversedDef, interfaceToImplementingTypes).reduce((acc, i) => {
120-
const inheritedDirectives = typeToDirectivesPerFieldMap.get(i)?.get(node.name.value) || [];
121-
return acc.concat(inheritedDirectives);
122-
}, directivesToCheck);
123-
}
124-
return directivesToCheck;
125-
};
126-
12728
return {
12829
enter(node: ASTNode, _key, _parent, path, ancestors) {
12930
if (!("directives" in node) || !node.directives) {
13031
return;
13132
}
132-
const [pathToNode, traversedDef, parentOfTraversedDef] = getPathToNode(path, ancestors);
33+
const [pathToNode, traversedDef] = getPathToNode(path, ancestors);
13334
const currentNodeErrorPath =
13435
isTypeDefinitionNode(node) || isTypeExtensionNode(node) ? [...pathToNode, node.name.value] : pathToNode;
13536

136-
hydrateInterfaceWithImplementedTypesMap(node, interfaceToImplementingTypes);
137-
hydrateWithDirectives(node, parentOfTraversedDef);
138-
const directivesToCheck = getDirectives(node, parentOfTraversedDef);
37+
if (node.directives.length < 2) {
38+
// no directive combination to check
39+
return;
40+
}
13941

140-
const { isValid, errorMsg, errorPath } = assertValid(() => assertValidDirectives(directivesToCheck));
42+
const { isValid, errorMsg, errorPath } = assertValid(() =>
43+
assertValidDirectives(node.directives as DirectiveNode[])
44+
);
14145
if (!isValid) {
14246
context.reportError(
14347
createGraphQLError({

0 commit comments

Comments
 (0)