1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var visitor_1 = require("graphql/language/visitor");
|
5 | var getFromAST_1 = require("./getFromAST");
|
6 | var filterInPlace_1 = require("./util/filterInPlace");
|
7 | var ts_invariant_1 = require("ts-invariant");
|
8 | var storeUtils_1 = require("./storeUtils");
|
9 | var TYPENAME_FIELD = {
|
10 | kind: 'Field',
|
11 | name: {
|
12 | kind: 'Name',
|
13 | value: '__typename',
|
14 | },
|
15 | };
|
16 | function isEmpty(op, fragments) {
|
17 | return op.selectionSet.selections.every(function (selection) {
|
18 | return selection.kind === 'FragmentSpread' &&
|
19 | isEmpty(fragments[selection.name.value], fragments);
|
20 | });
|
21 | }
|
22 | function nullIfDocIsEmpty(doc) {
|
23 | return isEmpty(getFromAST_1.getOperationDefinition(doc) || getFromAST_1.getFragmentDefinition(doc), getFromAST_1.createFragmentMap(getFromAST_1.getFragmentDefinitions(doc)))
|
24 | ? null
|
25 | : doc;
|
26 | }
|
27 | function getDirectiveMatcher(directives) {
|
28 | return function directiveMatcher(directive) {
|
29 | return directives.some(function (dir) {
|
30 | return (dir.name && dir.name === directive.name.value) ||
|
31 | (dir.test && dir.test(directive));
|
32 | });
|
33 | };
|
34 | }
|
35 | function removeDirectivesFromDocument(directives, doc) {
|
36 | var variablesInUse = Object.create(null);
|
37 | var variablesToRemove = [];
|
38 | var fragmentSpreadsInUse = Object.create(null);
|
39 | var fragmentSpreadsToRemove = [];
|
40 | var modifiedDoc = nullIfDocIsEmpty(visitor_1.visit(doc, {
|
41 | Variable: {
|
42 | enter: function (node, _key, parent) {
|
43 | if (parent.kind !== 'VariableDefinition') {
|
44 | variablesInUse[node.name.value] = true;
|
45 | }
|
46 | },
|
47 | },
|
48 | Field: {
|
49 | enter: function (node) {
|
50 | if (directives && node.directives) {
|
51 | var shouldRemoveField = directives.some(function (directive) { return directive.remove; });
|
52 | if (shouldRemoveField &&
|
53 | node.directives &&
|
54 | node.directives.some(getDirectiveMatcher(directives))) {
|
55 | if (node.arguments) {
|
56 | node.arguments.forEach(function (arg) {
|
57 | if (arg.value.kind === 'Variable') {
|
58 | variablesToRemove.push({
|
59 | name: arg.value.name.value,
|
60 | });
|
61 | }
|
62 | });
|
63 | }
|
64 | if (node.selectionSet) {
|
65 | getAllFragmentSpreadsFromSelectionSet(node.selectionSet).forEach(function (frag) {
|
66 | fragmentSpreadsToRemove.push({
|
67 | name: frag.name.value,
|
68 | });
|
69 | });
|
70 | }
|
71 | return null;
|
72 | }
|
73 | }
|
74 | },
|
75 | },
|
76 | FragmentSpread: {
|
77 | enter: function (node) {
|
78 | fragmentSpreadsInUse[node.name.value] = true;
|
79 | },
|
80 | },
|
81 | Directive: {
|
82 | enter: function (node) {
|
83 | if (getDirectiveMatcher(directives)(node)) {
|
84 | return null;
|
85 | }
|
86 | },
|
87 | },
|
88 | }));
|
89 | if (modifiedDoc &&
|
90 | filterInPlace_1.filterInPlace(variablesToRemove, function (v) { return !variablesInUse[v.name]; }).length) {
|
91 | modifiedDoc = removeArgumentsFromDocument(variablesToRemove, modifiedDoc);
|
92 | }
|
93 | if (modifiedDoc &&
|
94 | filterInPlace_1.filterInPlace(fragmentSpreadsToRemove, function (fs) { return !fragmentSpreadsInUse[fs.name]; })
|
95 | .length) {
|
96 | modifiedDoc = removeFragmentSpreadFromDocument(fragmentSpreadsToRemove, modifiedDoc);
|
97 | }
|
98 | return modifiedDoc;
|
99 | }
|
100 | exports.removeDirectivesFromDocument = removeDirectivesFromDocument;
|
101 | function addTypenameToDocument(doc) {
|
102 | return visitor_1.visit(getFromAST_1.checkDocument(doc), {
|
103 | SelectionSet: {
|
104 | enter: function (node, _key, parent) {
|
105 | if (parent &&
|
106 | parent.kind === 'OperationDefinition') {
|
107 | return;
|
108 | }
|
109 | var selections = node.selections;
|
110 | if (!selections) {
|
111 | return;
|
112 | }
|
113 | var skip = selections.some(function (selection) {
|
114 | return (storeUtils_1.isField(selection) &&
|
115 | (selection.name.value === '__typename' ||
|
116 | selection.name.value.lastIndexOf('__', 0) === 0));
|
117 | });
|
118 | if (skip) {
|
119 | return;
|
120 | }
|
121 | var field = parent;
|
122 | if (storeUtils_1.isField(field) &&
|
123 | field.directives &&
|
124 | field.directives.some(function (d) { return d.name.value === 'export'; })) {
|
125 | return;
|
126 | }
|
127 | return tslib_1.__assign(tslib_1.__assign({}, node), { selections: tslib_1.__spreadArrays(selections, [TYPENAME_FIELD]) });
|
128 | },
|
129 | },
|
130 | });
|
131 | }
|
132 | exports.addTypenameToDocument = addTypenameToDocument;
|
133 | var connectionRemoveConfig = {
|
134 | test: function (directive) {
|
135 | var willRemove = directive.name.value === 'connection';
|
136 | if (willRemove) {
|
137 | if (!directive.arguments ||
|
138 | !directive.arguments.some(function (arg) { return arg.name.value === 'key'; })) {
|
139 | ts_invariant_1.invariant.warn('Removing an @connection directive even though it does not have a key. ' +
|
140 | 'You may want to use the key parameter to specify a store key.');
|
141 | }
|
142 | }
|
143 | return willRemove;
|
144 | },
|
145 | };
|
146 | function removeConnectionDirectiveFromDocument(doc) {
|
147 | return removeDirectivesFromDocument([connectionRemoveConfig], getFromAST_1.checkDocument(doc));
|
148 | }
|
149 | exports.removeConnectionDirectiveFromDocument = removeConnectionDirectiveFromDocument;
|
150 | function hasDirectivesInSelectionSet(directives, selectionSet, nestedCheck) {
|
151 | if (nestedCheck === void 0) { nestedCheck = true; }
|
152 | return (selectionSet &&
|
153 | selectionSet.selections &&
|
154 | selectionSet.selections.some(function (selection) {
|
155 | return hasDirectivesInSelection(directives, selection, nestedCheck);
|
156 | }));
|
157 | }
|
158 | function hasDirectivesInSelection(directives, selection, nestedCheck) {
|
159 | if (nestedCheck === void 0) { nestedCheck = true; }
|
160 | if (!storeUtils_1.isField(selection)) {
|
161 | return true;
|
162 | }
|
163 | if (!selection.directives) {
|
164 | return false;
|
165 | }
|
166 | return (selection.directives.some(getDirectiveMatcher(directives)) ||
|
167 | (nestedCheck &&
|
168 | hasDirectivesInSelectionSet(directives, selection.selectionSet, nestedCheck)));
|
169 | }
|
170 | function getDirectivesFromDocument(directives, doc) {
|
171 | getFromAST_1.checkDocument(doc);
|
172 | var parentPath;
|
173 | return nullIfDocIsEmpty(visitor_1.visit(doc, {
|
174 | SelectionSet: {
|
175 | enter: function (node, _key, _parent, path) {
|
176 | var currentPath = path.join('-');
|
177 | if (!parentPath ||
|
178 | currentPath === parentPath ||
|
179 | !currentPath.startsWith(parentPath)) {
|
180 | if (node.selections) {
|
181 | var selectionsWithDirectives = node.selections.filter(function (selection) { return hasDirectivesInSelection(directives, selection); });
|
182 | if (hasDirectivesInSelectionSet(directives, node, false)) {
|
183 | parentPath = currentPath;
|
184 | }
|
185 | return tslib_1.__assign(tslib_1.__assign({}, node), { selections: selectionsWithDirectives });
|
186 | }
|
187 | else {
|
188 | return null;
|
189 | }
|
190 | }
|
191 | },
|
192 | },
|
193 | }));
|
194 | }
|
195 | exports.getDirectivesFromDocument = getDirectivesFromDocument;
|
196 | function getArgumentMatcher(config) {
|
197 | return function argumentMatcher(argument) {
|
198 | return config.some(function (aConfig) {
|
199 | return argument.value &&
|
200 | argument.value.kind === 'Variable' &&
|
201 | argument.value.name &&
|
202 | (aConfig.name === argument.value.name.value ||
|
203 | (aConfig.test && aConfig.test(argument)));
|
204 | });
|
205 | };
|
206 | }
|
207 | function removeArgumentsFromDocument(config, doc) {
|
208 | var argMatcher = getArgumentMatcher(config);
|
209 | return nullIfDocIsEmpty(visitor_1.visit(doc, {
|
210 | OperationDefinition: {
|
211 | enter: function (node) {
|
212 | return tslib_1.__assign(tslib_1.__assign({}, node), { variableDefinitions: node.variableDefinitions.filter(function (varDef) {
|
213 | return !config.some(function (arg) { return arg.name === varDef.variable.name.value; });
|
214 | }) });
|
215 | },
|
216 | },
|
217 | Field: {
|
218 | enter: function (node) {
|
219 | var shouldRemoveField = config.some(function (argConfig) { return argConfig.remove; });
|
220 | if (shouldRemoveField) {
|
221 | var argMatchCount_1 = 0;
|
222 | node.arguments.forEach(function (arg) {
|
223 | if (argMatcher(arg)) {
|
224 | argMatchCount_1 += 1;
|
225 | }
|
226 | });
|
227 | if (argMatchCount_1 === 1) {
|
228 | return null;
|
229 | }
|
230 | }
|
231 | },
|
232 | },
|
233 | Argument: {
|
234 | enter: function (node) {
|
235 | if (argMatcher(node)) {
|
236 | return null;
|
237 | }
|
238 | },
|
239 | },
|
240 | }));
|
241 | }
|
242 | exports.removeArgumentsFromDocument = removeArgumentsFromDocument;
|
243 | function removeFragmentSpreadFromDocument(config, doc) {
|
244 | function enter(node) {
|
245 | if (config.some(function (def) { return def.name === node.name.value; })) {
|
246 | return null;
|
247 | }
|
248 | }
|
249 | return nullIfDocIsEmpty(visitor_1.visit(doc, {
|
250 | FragmentSpread: { enter: enter },
|
251 | FragmentDefinition: { enter: enter },
|
252 | }));
|
253 | }
|
254 | exports.removeFragmentSpreadFromDocument = removeFragmentSpreadFromDocument;
|
255 | function getAllFragmentSpreadsFromSelectionSet(selectionSet) {
|
256 | var allFragments = [];
|
257 | selectionSet.selections.forEach(function (selection) {
|
258 | if ((storeUtils_1.isField(selection) || storeUtils_1.isInlineFragment(selection)) &&
|
259 | selection.selectionSet) {
|
260 | getAllFragmentSpreadsFromSelectionSet(selection.selectionSet).forEach(function (frag) { return allFragments.push(frag); });
|
261 | }
|
262 | else if (selection.kind === 'FragmentSpread') {
|
263 | allFragments.push(selection);
|
264 | }
|
265 | });
|
266 | return allFragments;
|
267 | }
|
268 | function buildQueryFromSelectionSet(document) {
|
269 | var definition = getFromAST_1.getMainDefinition(document);
|
270 | var definitionOperation = definition.operation;
|
271 | if (definitionOperation === 'query') {
|
272 | return document;
|
273 | }
|
274 | var modifiedDoc = visitor_1.visit(document, {
|
275 | OperationDefinition: {
|
276 | enter: function (node) {
|
277 | return tslib_1.__assign(tslib_1.__assign({}, node), { operation: 'query' });
|
278 | },
|
279 | },
|
280 | });
|
281 | return modifiedDoc;
|
282 | }
|
283 | exports.buildQueryFromSelectionSet = buildQueryFromSelectionSet;
|
284 | function removeClientSetsFromDocument(document) {
|
285 | getFromAST_1.checkDocument(document);
|
286 | var modifiedDoc = removeDirectivesFromDocument([
|
287 | {
|
288 | test: function (directive) { return directive.name.value === 'client'; },
|
289 | remove: true,
|
290 | },
|
291 | ], document);
|
292 | if (modifiedDoc) {
|
293 | modifiedDoc = visitor_1.visit(modifiedDoc, {
|
294 | FragmentDefinition: {
|
295 | enter: function (node) {
|
296 | if (node.selectionSet) {
|
297 | var isTypenameOnly = node.selectionSet.selections.every(function (selection) {
|
298 | return storeUtils_1.isField(selection) && selection.name.value === '__typename';
|
299 | });
|
300 | if (isTypenameOnly) {
|
301 | return null;
|
302 | }
|
303 | }
|
304 | },
|
305 | },
|
306 | });
|
307 | }
|
308 | return modifiedDoc;
|
309 | }
|
310 | exports.removeClientSetsFromDocument = removeClientSetsFromDocument;
|
311 |
|
\ | No newline at end of file |