-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.js
117 lines (104 loc) · 3.18 KB
/
utils.js
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
function getUniqueFunc() {
var names = {};
return function unique(defs) {
return defs.filter(function (def) {
if (def.kind !== 'FragmentDefinition') return true;
var name = def.name.value;
if (names[name]) {
return false;
} else {
names[name] = true;
return true;
}
});
};
}
// Collect any fragment/type references from a node, adding them to the refs Set
function collectFragmentReferences(node, refs) {
if (node.kind === 'FragmentSpread') {
refs.add(node.name.value);
} else if (node.kind === 'VariableDefinition') {
var type = node.type;
if (type.kind === 'NamedType') {
refs.add(type.name.value);
}
}
if (node.selectionSet) {
node.selectionSet.selections.forEach(function (selection) {
collectFragmentReferences(selection, refs);
});
}
if (node.variableDefinitions) {
node.variableDefinitions.forEach(function (def) {
collectFragmentReferences(def, refs);
});
}
if (node.definitions) {
node.definitions.forEach(function (def) {
collectFragmentReferences(def, refs);
});
}
}
function extractReferences(doc) {
var definitionRefs = {};
doc.definitions.forEach(function (def) {
if (def.name) {
var refs = new Set();
collectFragmentReferences(def, refs);
definitionRefs[def.name.value] = refs;
}
});
return definitionRefs;
}
function findOperation(doc, name) {
for (var i = 0; i < doc.definitions.length; i++) {
var element = doc.definitions[i];
if (element.name && element.name.value == name) {
return element;
}
}
}
function oneQuery(doc, operationName, definitionRefs) {
// Copy the DocumentNode, but clear out the definitions
var newDoc = {
kind: doc.kind,
definitions: [findOperation(doc, operationName)],
};
if (doc.hasOwnProperty('loc')) {
newDoc.loc = doc.loc;
}
// Now, for the operation we're running, find any fragments referenced by
// it or the fragments it references
var opRefs = definitionRefs[operationName] || new Set();
var allRefs = new Set();
var newRefs = new Set();
// IE 11 doesn't support "new Set(iterable)", so we add the members of opRefs to newRefs one by one
opRefs.forEach(function (refName) {
newRefs.add(refName);
});
while (newRefs.size > 0) {
var prevRefs = newRefs;
newRefs = new Set();
prevRefs.forEach(function (refName) {
if (!allRefs.has(refName)) {
allRefs.add(refName);
var childRefs = definitionRefs[refName] || new Set();
childRefs.forEach(function (childRef) {
newRefs.add(childRef);
});
}
});
}
allRefs.forEach(function (refName) {
var op = findOperation(doc, refName);
if (op) {
newDoc.definitions.push(op);
}
});
return newDoc;
}
module.exports = {
oneQuery,
getUniqueFunc,
extractReferences,
};