1 | import { GraphQLError } from "../../error/GraphQLError.mjs";
|
2 | export function NoFragmentCyclesRule(context) {
|
3 |
|
4 |
|
5 | var visitedFrags = Object.create(null);
|
6 |
|
7 | var spreadPath = [];
|
8 |
|
9 | var spreadPathIndexByName = Object.create(null);
|
10 | return {
|
11 | OperationDefinition: function OperationDefinition() {
|
12 | return false;
|
13 | },
|
14 | FragmentDefinition: function FragmentDefinition(node) {
|
15 | detectCycleRecursive(node);
|
16 | return false;
|
17 | }
|
18 | };
|
19 |
|
20 |
|
21 |
|
22 | function detectCycleRecursive(fragment) {
|
23 | if (visitedFrags[fragment.name.value]) {
|
24 | return;
|
25 | }
|
26 |
|
27 | var fragmentName = fragment.name.value;
|
28 | visitedFrags[fragmentName] = true;
|
29 | var spreadNodes = context.getFragmentSpreads(fragment.selectionSet);
|
30 |
|
31 | if (spreadNodes.length === 0) {
|
32 | return;
|
33 | }
|
34 |
|
35 | spreadPathIndexByName[fragmentName] = spreadPath.length;
|
36 |
|
37 | for (var _i2 = 0; _i2 < spreadNodes.length; _i2++) {
|
38 | var spreadNode = spreadNodes[_i2];
|
39 | var spreadName = spreadNode.name.value;
|
40 | var cycleIndex = spreadPathIndexByName[spreadName];
|
41 | spreadPath.push(spreadNode);
|
42 |
|
43 | if (cycleIndex === undefined) {
|
44 | var spreadFragment = context.getFragment(spreadName);
|
45 |
|
46 | if (spreadFragment) {
|
47 | detectCycleRecursive(spreadFragment);
|
48 | }
|
49 | } else {
|
50 | var cyclePath = spreadPath.slice(cycleIndex);
|
51 | var viaPath = cyclePath.slice(0, -1).map(function (s) {
|
52 | return '"' + s.name.value + '"';
|
53 | }).join(', ');
|
54 | context.reportError(new GraphQLError("Cannot spread fragment \"".concat(spreadName, "\" within itself") + (viaPath !== '' ? " via ".concat(viaPath, ".") : '.'), cyclePath));
|
55 | }
|
56 |
|
57 | spreadPath.pop();
|
58 | }
|
59 |
|
60 | spreadPathIndexByName[fragmentName] = undefined;
|
61 | }
|
62 | }
|