relay-compiler 1.5.0-rc.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -221,6 +221,7 @@ function createVisitor(options) {
221
221
  customScalars: options.customScalars,
222
222
  enumsHasteModule: options.enumsHasteModule,
223
223
  existingFragmentNames: options.existingFragmentNames,
224
+ generatedFragments: new Set(),
224
225
  inputFieldWhiteList: options.inputFieldWhiteList,
225
226
  relayRuntimeModule: options.relayRuntimeModule,
226
227
  usedEnums: {},
@@ -248,8 +249,9 @@ function createVisitor(options) {
248
249
  }
249
250
  return [selection];
250
251
  });
252
+ state.generatedFragments.add(node.name);
251
253
  var refTypeName = getRefTypeName(node.name);
252
- var refType = require('babel-types').expressionStatement(require('babel-types').identifier('export opaque type ' + refTypeName + ': FragmentReference = FragmentReference'));
254
+ var refType = require('babel-types').expressionStatement(require('babel-types').identifier('declare export opaque type ' + refTypeName + ': FragmentReference'));
253
255
  var baseType = selectionsToBabel(selections, state, refTypeName);
254
256
  var type = isPlural(node) ? readOnlyArrayOfType(baseType) : baseType;
255
257
  return require('babel-types').program([].concat((0, _toConsumableArray3['default'])(getFragmentImports(state)), (0, _toConsumableArray3['default'])(getEnumDefinitions(state)), [importTypes(['FragmentReference'], state.relayRuntimeModule), refType, exportType(node.name, type)]));
@@ -339,7 +341,7 @@ function groupRefs(props) {
339
341
  return require('babel-types').identifier(getRefTypeName(ref));
340
342
  }));
341
343
  result.push({
342
- key: '__fragments',
344
+ key: '$fragmentRefs',
343
345
  conditional: false,
344
346
  value: _value3
345
347
  });
@@ -360,12 +362,14 @@ function getFragmentImports(state) {
360
362
  var usedFragment = _step3.value;
361
363
 
362
364
  var refTypeName = getRefTypeName(usedFragment);
363
- if (state.useHaste && state.existingFragmentNames.has(usedFragment)) {
364
- // TODO(T22653277) support non-haste environments when importing
365
- // fragments
366
- imports.push(importTypes([refTypeName], usedFragment + '.graphql'));
367
- } else {
368
- imports.push(anyTypeAlias(refTypeName));
365
+ if (!state.generatedFragments.has(usedFragment)) {
366
+ if (state.useHaste && state.existingFragmentNames.has(usedFragment)) {
367
+ // TODO(T22653277) support non-haste environments when importing
368
+ // fragments
369
+ imports.push(importTypes([refTypeName], usedFragment + '.graphql'));
370
+ } else {
371
+ imports.push(anyTypeAlias(refTypeName));
372
+ }
369
373
  }
370
374
  }
371
375
  } catch (err) {
@@ -17,7 +17,8 @@ var _require = require('./GraphQLCompilerPublic'),
17
17
  InlineFragmentsTransform = _require.InlineFragmentsTransform,
18
18
  SkipClientFieldTransform = _require.SkipClientFieldTransform,
19
19
  SkipRedundantNodesTransform = _require.SkipRedundantNodesTransform,
20
- SkipUnreachableNodeTransform = _require.SkipUnreachableNodeTransform;
20
+ SkipUnreachableNodeTransform = _require.SkipUnreachableNodeTransform,
21
+ StripUnusedVariablesTransform = _require.StripUnusedVariablesTransform;
21
22
 
22
23
  // Transforms applied to the code used to process a query response.
23
24
  var relaySchemaExtensions = [require('./RelayConnectionTransform').SCHEMA_EXTENSION, require('./RelayRelayDirectiveTransform').SCHEMA_EXTENSION];
@@ -37,7 +38,7 @@ var relayQueryTransforms = [require('./RelayDeferrableFragmentTransform').transf
37
38
  var relayCodegenTransforms = [InlineFragmentsTransform.transform, FlattenTransform.transformWithOptions({ flattenAbstractTypes: true }), SkipRedundantNodesTransform.transform, require('./RelayGenerateTypeNameTransform').transform, FilterDirectivesTransform.transform];
38
39
 
39
40
  // Transforms applied before printing the query sent to the server.
40
- var relayPrintTransforms = [FlattenTransform.transformWithOptions({}), require('./RelayGenerateTypeNameTransform').transform, require('./RelaySkipHandleFieldTransform').transform, FilterDirectivesTransform.transform];
41
+ var relayPrintTransforms = [FlattenTransform.transformWithOptions({}), require('./RelayGenerateTypeNameTransform').transform, require('./RelaySkipHandleFieldTransform').transform, FilterDirectivesTransform.transform, StripUnusedVariablesTransform.transform];
41
42
 
42
43
  module.exports = {
43
44
  commonTransforms: relayCommonTransforms,
@@ -148,6 +148,7 @@ function transformNode(node, selectionMap) {
148
148
  var identifier = require('./getIdentifierForSelection')(selection);
149
149
  switch (selection.kind) {
150
150
  case 'ScalarField':
151
+ case 'DeferrableFragmentSpread':
151
152
  case 'FragmentSpread':
152
153
  {
153
154
  if (!selectionMap.has(identifier)) {
@@ -60,8 +60,8 @@ function transformNode(context, fragments, node) {
60
60
  nextSelection = transformNode(context, fragments, selection);
61
61
  }
62
62
  break;
63
- case 'FragmentSpread':
64
- // Skip fragment spreads if the referenced fragment is empty
63
+ case 'DeferrableFragmentSpread':
64
+ // Skip deferred fragment spreads if the referenced fragment is empty
65
65
  if (!fragments.has(selection.name)) {
66
66
  var fragment = context.getFragment(selection.name);
67
67
  var nextFragment = transformNode(context, fragments, fragment);
@@ -71,6 +71,17 @@ function transformNode(context, fragments, node) {
71
71
  nextSelection = selection;
72
72
  }
73
73
  break;
74
+ case 'FragmentSpread':
75
+ // Skip fragment spreads if the referenced fragment is empty
76
+ if (!fragments.has(selection.name)) {
77
+ var _fragment = context.getFragment(selection.name);
78
+ var _nextFragment = transformNode(context, fragments, _fragment);
79
+ fragments.set(selection.name, _nextFragment);
80
+ }
81
+ if (fragments.get(selection.name)) {
82
+ nextSelection = selection;
83
+ }
84
+ break;
74
85
  case 'LinkedField':
75
86
  nextSelection = transformNode(context, fragments, selection);
76
87
  break;
@@ -20,9 +20,59 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'd
20
20
  * by the query itself.
21
21
  */
22
22
  function stripUnusedVariablesTransform(context) {
23
+ var fragmentToVariables = new Map();
24
+ var fragmentToFragmentSpreads = new Map();
25
+ var rootToVariables = new Map();
26
+ var rootToFragmentSpreads = new Map();
27
+ context.forEachDocument(function (document) {
28
+ var fragmentVariables = void 0;
29
+ var fragmentFragmentSpreads = void 0;
30
+ var rootVariables = void 0;
31
+ var rootFragmentSpreads = void 0;
32
+ require('./GraphQLIRVisitor').visit(document, {
33
+ Root: {
34
+ enter: function enter(root) {
35
+ rootVariables = new Set();
36
+ rootToVariables.set(root.name, rootVariables);
37
+ rootFragmentSpreads = new Set();
38
+ rootToFragmentSpreads.set(root.name, rootFragmentSpreads);
39
+ },
40
+ leave: function leave(root) {
41
+ rootVariables = null;
42
+ rootFragmentSpreads = null;
43
+ }
44
+ },
45
+ Fragment: {
46
+ enter: function enter(fragment) {
47
+ fragmentVariables = new Set();
48
+ fragmentToVariables.set(fragment.name, fragmentVariables);
49
+ fragmentFragmentSpreads = new Set();
50
+ fragmentToFragmentSpreads.set(fragment.name, fragmentFragmentSpreads);
51
+ },
52
+ leave: function leave(fragment) {
53
+ fragmentVariables = null;
54
+ fragmentFragmentSpreads = null;
55
+ }
56
+ },
57
+ Variable: function Variable(variable) {
58
+ fragmentVariables && fragmentVariables.add(variable.variableName);
59
+ rootVariables && rootVariables.add(variable.variableName);
60
+ },
61
+ FragmentSpread: function FragmentSpread(spread) {
62
+ fragmentFragmentSpreads && fragmentFragmentSpreads.add(spread.name);
63
+ rootFragmentSpreads && rootFragmentSpreads.add(spread.name);
64
+ }
65
+ });
66
+ });
67
+ var variablesMemo = new Map();
68
+ rootToVariables.forEach(function (variables, root) {
69
+ Array.from(require('./nullthrowsOSS')(rootToFragmentSpreads.get(root), 'root ' + root + ' wasn\'t found in StripUnusedVariablesTransform')).forEach(function (spread) {
70
+ return into(variables, allVariablesReferencedInFragment(variablesMemo, spread, fragmentToVariables, fragmentToFragmentSpreads));
71
+ });
72
+ });
23
73
  return require('./GraphQLIRTransformer').transform(context, {
24
74
  Root: function Root(root) {
25
- return transformRoot(context, root);
75
+ return transformRoot(context, root, require('./nullthrowsOSS')(rootToVariables.get(root.name), 'root ' + root.name + ' wasn\'t found in StripUnusedVariablesTransform'));
26
76
  },
27
77
  // Include fragments, but do not traverse into them.
28
78
  Fragment: function Fragment(id) {
@@ -31,43 +81,32 @@ function stripUnusedVariablesTransform(context) {
31
81
  });
32
82
  }
33
83
 
34
- function transformRoot(context, root) {
35
- var state = {
36
- referencedVariables: new Set()
37
- };
38
- var newContext = require('./GraphQLIRTransformer').transform(require('./filterContextForNode')(root, context), {
39
- Argument: visitArgument,
40
- Condition: visitCondition
41
- }, function () {
42
- return state;
43
- });
44
- var transformedNode = newContext.getRoot(root.name);
45
- /**
46
- * Remove the extraneous arguments *after* transform returns, since fragments
47
- * could be transformed after the root query.
48
- */
49
- return (0, _extends3['default'])({}, transformedNode, {
50
- argumentDefinitions: transformedNode.argumentDefinitions.filter(function (arg) {
51
- return state.referencedVariables.has(arg.name);
52
- })
53
- });
84
+ function allVariablesReferencedInFragment(variablesMemo, fragment, fragmentToVariables, fragmentToFragmentSpreads) {
85
+ var variables = variablesMemo.get(fragment);
86
+ if (!variables) {
87
+ var directVariables = require('./nullthrowsOSS')(fragmentToVariables.get(fragment), 'fragment ' + fragment + ' wasn\'t found in StripUnusedVariablesTransform');
88
+ variables = Array.from(require('./nullthrowsOSS')(fragmentToFragmentSpreads.get(fragment), 'fragment ' + fragment + ' wasn\'t found in StripUnusedVariablesTransform')).reduce(function (allVariables, fragmentSpread) {
89
+ return into(allVariables, allVariablesReferencedInFragment(variablesMemo, fragmentSpread, fragmentToVariables, fragmentToFragmentSpreads));
90
+ }, directVariables);
91
+ variablesMemo.set(fragment, variables);
92
+ }
93
+ return variables;
54
94
  }
55
95
 
56
- function visitArgument(argument, state) {
57
- var value = argument.value;
58
-
59
- if (value.kind === 'Variable') {
60
- state.referencedVariables.add(value.variableName);
61
- }
62
- return argument;
96
+ function transformRoot(context, root, variables) {
97
+ return (0, _extends3['default'])({}, root, {
98
+ argumentDefinitions: root.argumentDefinitions.filter(function (arg) {
99
+ return variables.has(arg.name);
100
+ })
101
+ });
63
102
  }
64
103
 
65
- function visitCondition(condition, state) {
66
- var innerCondition = condition.condition;
67
- if (innerCondition.kind === 'Variable') {
68
- state.referencedVariables.add(innerCondition.variableName);
69
- }
70
- return condition;
104
+ // Returns the union of setA and setB. Modifies setA!
105
+ function into(setA, setB) {
106
+ setB.forEach(function (item) {
107
+ return setA.add(item);
108
+ });
109
+ return setA;
71
110
  }
72
111
 
73
112
  module.exports = {
@@ -23,7 +23,7 @@ var _require = require('./GraphQLIRPrinter'),
23
23
  function getIdentifierForSelection(node) {
24
24
  if (node.kind === 'LinkedField' || node.kind === 'ScalarField') {
25
25
  return node.directives.length === 0 ? node.alias || node.name : (node.alias || node.name) + printDirectives(node.directives);
26
- } else if (node.kind === 'FragmentSpread') {
26
+ } else if (node.kind === 'FragmentSpread' || node.kind === 'DeferrableFragmentSpread') {
27
27
  return node.args.length === 0 ? '...' + node.name : '...' + node.name + printArguments(node.args);
28
28
  } else if (node.kind === 'InlineFragment') {
29
29
  return 'I:' + node.typeCondition.name;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "relay-compiler",
3
3
  "description": "A compiler tool for building GraphQL-driven applications.",
4
- "version": "1.5.0-rc.1",
4
+ "version": "1.5.0",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay"
@@ -21,14 +21,14 @@
21
21
  "babel-runtime": "^6.23.0",
22
22
  "babel-traverse": "^6.26.0",
23
23
  "babel-types": "^6.24.1",
24
- "babylon": "^6.18.0",
24
+ "babylon": "^7.0.0-beta",
25
25
  "chalk": "^1.1.1",
26
- "fast-glob": "^1.0.1",
26
+ "fast-glob": "^2.0.0",
27
27
  "fb-watchman": "^2.0.0",
28
28
  "fbjs": "^0.8.14",
29
- "graphql": "^0.12.3",
29
+ "graphql": "^0.13.0",
30
30
  "immutable": "~3.7.6",
31
- "relay-runtime": "1.5.0-rc.1",
31
+ "relay-runtime": "1.5.0",
32
32
  "signedsource": "^1.0.0",
33
33
  "yargs": "^9.0.0"
34
34
  }