1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | 'use strict';
|
11 |
|
12 | var _objectSpread2 = require("@babel/runtime/helpers/interopRequireDefault")(require("@babel/runtime/helpers/objectSpread"));
|
13 |
|
14 | var _toConsumableArray2 = require("@babel/runtime/helpers/interopRequireDefault")(require("@babel/runtime/helpers/toConsumableArray"));
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | function relayApplyFragmentArgumentTransform(context) {
|
39 | var fragments = new Map();
|
40 |
|
41 | var nextContext = require("./GraphQLIRTransformer").transform(context, {
|
42 | Root: function Root(node) {
|
43 | var scope = require("./RelayCompilerScope").getRootScope(node.argumentDefinitions);
|
44 |
|
45 | return transformNode(context, fragments, scope, node, [node]);
|
46 | },
|
47 |
|
48 |
|
49 | Fragment: function Fragment() {
|
50 | return null;
|
51 | }
|
52 | });
|
53 |
|
54 | return Array.from(fragments.values()).reduce(function (ctx, fragment) {
|
55 | return fragment ? ctx.add(fragment) : ctx;
|
56 | }, nextContext);
|
57 | }
|
58 |
|
59 | function transformNode(context, fragments, scope, node, errorContext) {
|
60 | var selections = transformSelections(context, fragments, scope, node.selections, errorContext);
|
61 |
|
62 | if (!selections) {
|
63 | return null;
|
64 | }
|
65 |
|
66 | if (node.hasOwnProperty('directives')) {
|
67 | var directives = transformDirectives(scope, node.directives, errorContext);
|
68 |
|
69 | return (0, _objectSpread2["default"])({}, node, {
|
70 | directives: directives,
|
71 | selections: selections
|
72 | });
|
73 | }
|
74 |
|
75 | return (0, _objectSpread2["default"])({}, node, {
|
76 | selections: selections
|
77 | });
|
78 | }
|
79 |
|
80 | function transformFragmentSpread(context, fragments, scope, spread, errorContext) {
|
81 | var directives = transformDirectives(scope, spread.directives, errorContext);
|
82 | var appliedFragment = transformFragment(context, fragments, scope, spread, spread.args, (0, _toConsumableArray2["default"])(errorContext).concat([spread]));
|
83 |
|
84 | if (!appliedFragment) {
|
85 | return null;
|
86 | }
|
87 |
|
88 | var transformed = (0, _objectSpread2["default"])({}, spread, {
|
89 | kind: 'FragmentSpread',
|
90 | args: [],
|
91 | directives: directives,
|
92 | name: appliedFragment.name
|
93 | });
|
94 | return transformed;
|
95 | }
|
96 |
|
97 | function transformField(context, fragments, scope, field, errorContext) {
|
98 | var args = transformArguments(scope, field.args, errorContext);
|
99 | var directives = transformDirectives(scope, field.directives, errorContext);
|
100 |
|
101 | if (field.kind === 'LinkedField' || field.kind === 'MatchField') {
|
102 | var selections = transformSelections(context, fragments, scope, field.selections, errorContext);
|
103 |
|
104 | if (!selections) {
|
105 | return null;
|
106 | }
|
107 |
|
108 |
|
109 | return (0, _objectSpread2["default"])({}, field, {
|
110 | args: args,
|
111 | directives: directives,
|
112 | selections: selections
|
113 | });
|
114 | } else {
|
115 | return (0, _objectSpread2["default"])({}, field, {
|
116 | args: args,
|
117 | directives: directives
|
118 | });
|
119 | }
|
120 | }
|
121 |
|
122 | function transformCondition(context, fragments, scope, node, errorContext) {
|
123 | var condition = transformValue(scope, node.condition, errorContext);
|
124 |
|
125 | if (!(condition.kind === 'Literal' || condition.kind === 'Variable')) {
|
126 |
|
127 |
|
128 |
|
129 | throw require("./RelayCompilerError").createNonRecoverableUserError('A non-scalar value was applied to an @include or @skip directive, ' + 'the `if` argument value must be a ' + 'variable or a literal Boolean.', [condition.loc]);
|
130 | }
|
131 |
|
132 | if (condition.kind === 'Literal' && condition.value !== node.passingValue) {
|
133 |
|
134 | return null;
|
135 | }
|
136 |
|
137 | var selections = transformSelections(context, fragments, scope, node.selections, errorContext);
|
138 |
|
139 | if (!selections) {
|
140 | return null;
|
141 | }
|
142 |
|
143 | if (condition.kind === 'Literal' && condition.value === node.passingValue) {
|
144 |
|
145 | return selections;
|
146 | }
|
147 |
|
148 | return [(0, _objectSpread2["default"])({}, node, {
|
149 | condition: condition,
|
150 | selections: selections
|
151 | })];
|
152 | }
|
153 |
|
154 | function transformSelections(context, fragments, scope, selections, errorContext) {
|
155 | var nextSelections = null;
|
156 | selections.forEach(function (selection) {
|
157 | var nextSelection;
|
158 |
|
159 | if (selection.kind === 'InlineFragment' || selection.kind === 'MatchBranch') {
|
160 | nextSelection = transformNode(context, fragments, scope, selection, errorContext);
|
161 | } else if (selection.kind === 'FragmentSpread') {
|
162 | nextSelection = transformFragmentSpread(context, fragments, scope, selection, errorContext);
|
163 | } else if (selection.kind === 'Condition') {
|
164 | var conditionSelections = transformCondition(context, fragments, scope, selection, errorContext);
|
165 |
|
166 | if (conditionSelections) {
|
167 | var _nextSelections;
|
168 |
|
169 | nextSelections = nextSelections || [];
|
170 |
|
171 | (_nextSelections = nextSelections).push.apply(_nextSelections, (0, _toConsumableArray2["default"])(conditionSelections));
|
172 | }
|
173 | } else if (selection.kind === 'LinkedField' || selection.kind === 'ScalarField' || selection.kind === 'MatchField') {
|
174 | nextSelection = transformField(context, fragments, scope, selection, errorContext);
|
175 | } else if (selection.kind === 'Defer' || selection.kind === 'Stream') {
|
176 | throw require("./RelayCompilerError").createCompilerError('RelayApplyFragmentArgumentTransform: Expected to be applied before processing @defer/@stream.', [selection.loc]);
|
177 | } else {
|
178 | selection;
|
179 | throw require("./RelayCompilerError").createCompilerError("RelayApplyFragmentArgumentTransform: Unsupported kind '".concat(selection.kind, "'."), [selection.loc]);
|
180 | }
|
181 |
|
182 | if (nextSelection) {
|
183 | nextSelections = nextSelections || [];
|
184 | nextSelections.push(nextSelection);
|
185 | }
|
186 | });
|
187 | return nextSelections;
|
188 | }
|
189 |
|
190 | function transformDirectives(scope, directives, errorContext) {
|
191 | return directives.map(function (directive) {
|
192 | var args = transformArguments(scope, directive.args, errorContext);
|
193 | return (0, _objectSpread2["default"])({}, directive, {
|
194 | args: args
|
195 | });
|
196 | });
|
197 | }
|
198 |
|
199 | function transformArguments(scope, args, errorContext) {
|
200 | return args.map(function (arg) {
|
201 | var value = transformValue(scope, arg.value, errorContext);
|
202 | return value === arg.value ? arg : (0, _objectSpread2["default"])({}, arg, {
|
203 | value: value
|
204 | });
|
205 | });
|
206 | }
|
207 |
|
208 | function transformValue(scope, value, errorContext) {
|
209 | if (value.kind === 'Variable') {
|
210 | var scopeValue = scope[value.variableName];
|
211 |
|
212 | if (scopeValue == null) {
|
213 |
|
214 |
|
215 |
|
216 | throw require("./RelayCompilerError").createNonRecoverableUserError("Variable '$".concat(value.variableName, "' is not in scope."), [value.loc]);
|
217 | }
|
218 |
|
219 | return scopeValue;
|
220 | } else if (value.kind === 'ListValue') {
|
221 | return (0, _objectSpread2["default"])({}, value, {
|
222 | items: value.items.map(function (item) {
|
223 | return transformValue(scope, item, errorContext);
|
224 | })
|
225 | });
|
226 | } else if (value.kind === 'ObjectValue') {
|
227 | return (0, _objectSpread2["default"])({}, value, {
|
228 | fields: value.fields.map(function (field) {
|
229 | return (0, _objectSpread2["default"])({}, field, {
|
230 | value: transformValue(scope, field.value, errorContext)
|
231 | });
|
232 | })
|
233 | });
|
234 | }
|
235 |
|
236 | return value;
|
237 | }
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 | function transformFragment(context, fragments, parentScope, spread, args, errorContext) {
|
245 | var fragment = context.getFragment(spread.name);
|
246 | var argumentsHash = hashArguments(args, parentScope, errorContext);
|
247 | var fragmentName = argumentsHash ? "".concat(fragment.name, "_").concat(argumentsHash) : fragment.name;
|
248 | var appliedFragment = fragments.get(fragmentName);
|
249 |
|
250 | if (appliedFragment) {
|
251 | return appliedFragment;
|
252 | }
|
253 |
|
254 | var fragmentScope = require("./RelayCompilerScope").getFragmentScope(fragment.argumentDefinitions, args, parentScope, spread);
|
255 |
|
256 | if (fragments.get(fragmentName) === null) {
|
257 |
|
258 |
|
259 |
|
260 | throw require("./RelayCompilerError").createNonRecoverableUserError("Found a circular reference from fragment '".concat(fragment.name, "'."), errorContext.map(function (node) {
|
261 | return node.loc;
|
262 | }));
|
263 | }
|
264 |
|
265 | fragments.set(fragmentName, null);
|
266 |
|
267 | var transformedFragment = null;
|
268 | var selections = transformSelections(context, fragments, fragmentScope, fragment.selections, errorContext);
|
269 |
|
270 | if (selections) {
|
271 | transformedFragment = (0, _objectSpread2["default"])({}, fragment, {
|
272 | selections: selections,
|
273 | name: fragmentName,
|
274 | argumentDefinitions: []
|
275 | });
|
276 | }
|
277 |
|
278 | fragments.set(fragmentName, transformedFragment);
|
279 | return transformedFragment;
|
280 | }
|
281 |
|
282 | function hashArguments(args, scope, errorContext) {
|
283 | if (!args.length) {
|
284 | return null;
|
285 | }
|
286 |
|
287 | var sortedArgs = (0, _toConsumableArray2["default"])(args).sort(function (a, b) {
|
288 | return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
|
289 | });
|
290 | var printedArgs = JSON.stringify(sortedArgs.map(function (arg) {
|
291 | var value;
|
292 |
|
293 | if (arg.value.kind === 'Variable') {
|
294 | value = scope[arg.value.variableName];
|
295 |
|
296 | if (value == null) {
|
297 |
|
298 |
|
299 |
|
300 | throw require("./RelayCompilerError").createNonRecoverableUserError("Variable '$".concat(arg.value.variableName, "' is not in scope."), [arg.value.loc]);
|
301 | }
|
302 | } else {
|
303 | value = arg.value;
|
304 | }
|
305 |
|
306 | return {
|
307 | name: arg.name,
|
308 | value: require("./getIdentifierForArgumentValue")(value)
|
309 | };
|
310 | }));
|
311 | return require("./murmurHash")(printedArgs);
|
312 | }
|
313 |
|
314 | module.exports = {
|
315 | transform: relayApplyFragmentArgumentTransform
|
316 | }; |
\ | No newline at end of file |