UNPKG

12.5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var visitor_1 = require("graphql/language/visitor");
5var getFromAST_1 = require("./getFromAST");
6var filterInPlace_1 = require("./util/filterInPlace");
7var ts_invariant_1 = require("ts-invariant");
8var storeUtils_1 = require("./storeUtils");
9var TYPENAME_FIELD = {
10 kind: 'Field',
11 name: {
12 kind: 'Name',
13 value: '__typename',
14 },
15};
16function 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}
22function 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}
27function 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}
35function 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}
100exports.removeDirectivesFromDocument = removeDirectivesFromDocument;
101function 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}
132exports.addTypenameToDocument = addTypenameToDocument;
133var 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};
146function removeConnectionDirectiveFromDocument(doc) {
147 return removeDirectivesFromDocument([connectionRemoveConfig], getFromAST_1.checkDocument(doc));
148}
149exports.removeConnectionDirectiveFromDocument = removeConnectionDirectiveFromDocument;
150function 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}
158function 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}
170function 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}
195exports.getDirectivesFromDocument = getDirectivesFromDocument;
196function 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}
207function 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}
242exports.removeArgumentsFromDocument = removeArgumentsFromDocument;
243function 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}
254exports.removeFragmentSpreadFromDocument = removeFragmentSpreadFromDocument;
255function 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}
268function 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}
283exports.buildQueryFromSelectionSet = buildQueryFromSelectionSet;
284function 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}
310exports.removeClientSetsFromDocument = removeClientSetsFromDocument;
311//# sourceMappingURL=transform.js.map
\No newline at end of file