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.
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Relay v1.5.0-rc.1
2
+ * Relay v1.5.0
3
3
  *
4
4
  * Copyright (c) 2013-present, Facebook, Inc.
5
5
  *
package/lib/ASTCache.js CHANGED
@@ -43,6 +43,11 @@ var ASTCache = function () {
43
43
  var documents = ImmutableMap();
44
44
 
45
45
  files.forEach(function (file) {
46
+ if (!file.exists) {
47
+ _this._documents['delete'](file.relPath);
48
+ return;
49
+ }
50
+
46
51
  var doc = function () {
47
52
  try {
48
53
  return _this._parse(_this._baseDir, file);
package/lib/ASTConvert.js CHANGED
@@ -16,7 +16,7 @@ var _toConsumableArray3 = _interopRequireDefault(require('babel-runtime/helpers/
16
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
17
17
 
18
18
  var _require = require('./GraphQLSchemaUtils'),
19
- isOperationDefinitionAST = _require.isOperationDefinitionAST,
19
+ isExecutableDefinitionAST = _require.isExecutableDefinitionAST,
20
20
  isSchemaDefinitionAST = _require.isSchemaDefinitionAST;
21
21
 
22
22
  var _require2 = require('graphql'),
@@ -31,7 +31,7 @@ function convertASTDocuments(schema, documents, validationRules, transform) {
31
31
  var astDefinitions = [];
32
32
  documents.forEach(function (doc) {
33
33
  doc.definitions.forEach(function (definition) {
34
- if (isOperationDefinitionAST(definition)) {
34
+ if (isExecutableDefinitionAST(definition)) {
35
35
  astDefinitions.push(definition);
36
36
  }
37
37
  });
@@ -49,7 +49,7 @@ function convertASTDocumentsWithBase(schema, baseDocuments, documents, validatio
49
49
  var requiredDefinitions = new Map();
50
50
  var baseMap = new Map();
51
51
  baseDefinitions.forEach(function (definition) {
52
- if (isOperationDefinitionAST(definition)) {
52
+ if (isExecutableDefinitionAST(definition)) {
53
53
  var definitionName = definition.name && definition.name.value;
54
54
  // If there's no name, no reason to put in the map
55
55
  if (definitionName) {
@@ -63,7 +63,7 @@ function convertASTDocumentsWithBase(schema, baseDocuments, documents, validatio
63
63
 
64
64
  var definitionsToVisit = [];
65
65
  definitions.forEach(function (definition) {
66
- if (isOperationDefinitionAST(definition)) {
66
+ if (isExecutableDefinitionAST(definition)) {
67
67
  definitionsToVisit.push(definition);
68
68
  }
69
69
  });
@@ -103,7 +103,7 @@ function convertASTDocumentsWithBase(schema, baseDocuments, documents, validatio
103
103
  function convertASTDefinitions(schema, definitions, validationRules, transform) {
104
104
  var operationDefinitions = [];
105
105
  definitions.forEach(function (definition) {
106
- if (isOperationDefinitionAST(definition)) {
106
+ if (isExecutableDefinitionAST(definition)) {
107
107
  operationDefinitions.push(definition);
108
108
  }
109
109
  });
@@ -56,7 +56,15 @@ var CodegenDirectory = function () {
56
56
  if (require('fs').existsSync(dir)) {
57
57
  require('fbjs/lib/invariant')(require('fs').statSync(dir).isDirectory(), 'Expected `%s` to be a directory.', dir);
58
58
  } else if (!this.onlyValidate) {
59
- require('fs').mkdirSync(dir);
59
+ var dirs = [dir];
60
+ var parent = require('path').dirname(dir);
61
+ while (!require('fs').existsSync(parent)) {
62
+ dirs.unshift(parent);
63
+ parent = require('path').dirname(parent);
64
+ }
65
+ dirs.forEach(function (d) {
66
+ return require('fs').mkdirSync(d);
67
+ });
60
68
  }
61
69
  this._files = new Set();
62
70
  this.changes = {
@@ -240,8 +240,7 @@ var CodegenRunner = function () {
240
240
 
241
241
  return require('./GraphQLCompilerProfiler').asyncContext('CodegenRunner.write', (0, _asyncToGenerator3.default)(function* () {
242
242
  try {
243
- // eslint-disable-next-line no-console
244
- console.log('\nWriting %s', writerName);
243
+ _this5._reporter.reportMessage('\nWriting ' + writerName);
245
244
  var _writerConfigs$writer = _this5.writerConfigs[writerName],
246
245
  _getWriter = _writerConfigs$writer.getWriter,
247
246
  _parser2 = _writerConfigs$writer.parser,
@@ -391,16 +390,14 @@ var CodegenRunner = function () {
391
390
  } catch (error) {
392
391
  _this6._reporter.reportError('CodegenRunner.watch', error);
393
392
  }
394
- // eslint-disable-next-line no-console
395
- console.log('Watching for changes to %s...', parserName);
393
+ _this6._reporter.reportMessage('Watching for changes to ' + parserName + '...');
396
394
  });
397
395
 
398
396
  return function (_x4) {
399
397
  return _ref9.apply(this, arguments);
400
398
  };
401
399
  })());
402
- // eslint-disable-next-line no-console
403
- console.log('Watching for changes to %s...', parserName);
400
+ this._reporter.reportMessage('Watching for changes to ' + parserName + '...');
404
401
  });
405
402
 
406
403
  function watch(_x3) {
@@ -191,7 +191,7 @@ var SUBSCRIPTION_NAME = 'graphql-codegen';
191
191
  function updateFiles(files, baseDir, filter, fileChanges) {
192
192
  var fileMap = new Map();
193
193
  files.forEach(function (file) {
194
- fileMap.set(file.relPath, file);
194
+ file.exists && fileMap.set(file.relPath, file);
195
195
  });
196
196
 
197
197
  fileChanges.forEach(function (_ref2) {
@@ -199,15 +199,23 @@ function updateFiles(files, baseDir, filter, fileChanges) {
199
199
  exists = _ref2.exists,
200
200
  hash = _ref2['content.sha1hex'];
201
201
 
202
- var file = {
203
- relPath: name,
204
- hash: hash || hashFile(require('path').join(baseDir, name))
205
- };
206
- if (exists && filter(file)) {
207
- fileMap.set(name, file);
208
- } else {
209
- fileMap['delete'](name);
202
+ var shouldRemove = !exists;
203
+ if (!shouldRemove) {
204
+ var _file = {
205
+ exists: true,
206
+ relPath: name,
207
+ hash: hash || hashFile(require('path').join(baseDir, name))
208
+ };
209
+ if (filter(_file)) {
210
+ fileMap.set(name, _file);
211
+ } else {
212
+ shouldRemove = true;
213
+ }
210
214
  }
215
+ shouldRemove && fileMap.set(name, {
216
+ exists: false,
217
+ relPath: name
218
+ });
211
219
  });
212
220
  return new Set(fileMap.values());
213
221
  }
@@ -17,7 +17,9 @@ var _require = require('graphql'),
17
17
 
18
18
  function parseFile(baseDir, file) {
19
19
  var text = require('fs').readFileSync(require('path').join(baseDir, file.relPath), 'utf8');
20
- return parse(new Source(text, file.relPath));
20
+ return parse(new Source(text, file.relPath), {
21
+ experimentalFragmentVariables: true
22
+ });
21
23
  }
22
24
 
23
25
  exports.getParser = function getParser(baseDir) {
@@ -84,17 +84,18 @@ function find(text, filePath, _ref) {
84
84
  var cache = new (require('./RelayCompilerCache'))('FindGraphQLTags', 'v1');
85
85
 
86
86
  function memoizedFind(text, baseDir, file, options) {
87
+ !file.exists ? process.env.NODE_ENV !== 'production' ? invariant(false, 'FindGraphQLTags: Called with non-existent file `%s`', file.relPath) : invariant(false) : void 0;
87
88
  return cache.getOrCompute(file.hash + (options.validateNames ? '1' : '0'), function () {
88
89
  var absPath = require('path').join(baseDir, file.relPath);
89
90
  return find(text, absPath, options);
90
91
  });
91
92
  }
92
93
 
93
- var CREATE_CONTAINER_FUNCTIONS = {
94
- createFragmentContainer: true,
95
- createPaginationContainer: true,
96
- createRefetchContainer: true
97
- };
94
+ var CREATE_CONTAINER_FUNCTIONS = Object.create(null, {
95
+ createFragmentContainer: { value: true },
96
+ createPaginationContainer: { value: true },
97
+ createRefetchContainer: { value: true }
98
+ });
98
99
 
99
100
  var IGNORED_KEYS = {
100
101
  comments: true,
@@ -102,7 +102,7 @@ function flattenSelectionsInto(flattenedSelections, node, state, type) {
102
102
  flattenedSelections.set(nodeIdentifier, (0, _extends3['default'])({}, flattenedSelection, {
103
103
  selections: mergeSelections(flattenedSelection, selection, state, type)
104
104
  }));
105
- } else if (flattenedSelection.kind === 'FragmentSpread') {
105
+ } else if (flattenedSelection.kind === 'FragmentSpread' || flattenedSelection.kind === 'DeferrableFragmentSpread') {
106
106
  // Ignore duplicate fragment spreads.
107
107
  } else if (flattenedSelection.kind === 'LinkedField') {
108
108
  require('fbjs/lib/invariant')(selection.kind === 'LinkedField', 'FlattenTransform: Expected a LinkedField, got a %s', selection.kind);
@@ -20,21 +20,30 @@ var GraphQLConsoleReporter = function () {
20
20
  (0, _classCallCheck3['default'])(this, GraphQLConsoleReporter);
21
21
 
22
22
  this._verbose = options.verbose;
23
+ this._quiet = options.quiet;
23
24
  }
24
25
 
26
+ GraphQLConsoleReporter.prototype.reportMessage = function reportMessage(message) {
27
+ if (!this._quiet) {
28
+ process.stdout.write(message + '\n');
29
+ }
30
+ };
31
+
25
32
  GraphQLConsoleReporter.prototype.reportTime = function reportTime(name, ms) {
26
- if (this._verbose) {
33
+ if (this._verbose && !this.quiet) {
27
34
  var time = ms === 0 ? require('chalk').gray(' <1ms') : ms < 1000 ? require('chalk').blue(leftPad(5, ms + 'ms')) : require('chalk').red(Math.floor(ms / 10) / 100 + 's');
28
35
  process.stdout.write(' ' + time + ' ' + require('chalk').gray(name) + '\n');
29
36
  }
30
37
  };
31
38
 
32
39
  GraphQLConsoleReporter.prototype.reportError = function reportError(caughtLocation, error) {
33
- process.stdout.write(require('chalk').red('ERROR:\n' + error.message + '\n'));
34
- if (this._verbose) {
35
- var frames = error.stack.match(/^ {4}at .*$/gm);
36
- if (frames) {
37
- process.stdout.write(require('chalk').gray('From: ' + caughtLocation + '\n' + frames.join('\n') + '\n'));
40
+ if (!this._quiet) {
41
+ process.stdout.write(require('chalk').red('ERROR:\n' + error.message + '\n'));
42
+ if (this._verbose) {
43
+ var frames = error.stack.match(/^ {4}at .*$/gm);
44
+ if (frames) {
45
+ process.stdout.write(require('chalk').gray('From: ' + caughtLocation + '\n' + frames.join('\n') + '\n'));
46
+ }
38
47
  }
39
48
  }
40
49
  };
@@ -76,6 +76,8 @@ function printSelection(selection, indent, parentCondition) {
76
76
  str += parentCondition;
77
77
  str += printFragmentArguments(selection.args);
78
78
  str += printDirectives(selection.directives);
79
+ } else if (selection.kind === 'DeferrableFragmentSpread') {
80
+ str = selection.alias + ': ' + selection.storageKey;
79
81
  } else if (selection.kind === 'Condition') {
80
82
  var value = printValue(selection.condition);
81
83
  // For Flow
@@ -194,12 +194,20 @@ var Transformer = function () {
194
194
  nextNode = this._traverseChildren(prevNode, ['fields']);
195
195
  break;
196
196
  case 'Condition':
197
+ nextNode = this._traverseChildren(prevNode, ['directives', 'selections'], ['condition']);
198
+ if (!nextNode.selections.length) {
199
+ nextNode = null;
200
+ }
201
+ break;
197
202
  case 'InlineFragment':
198
203
  nextNode = this._traverseChildren(prevNode, ['directives', 'selections']);
199
204
  if (!nextNode.selections.length) {
200
205
  nextNode = null;
201
206
  }
202
207
  break;
208
+ case 'DeferrableFragmentSpread':
209
+ nextNode = this._traverseChildren(prevNode, ['args', 'fragmentArgs', 'directives']);
210
+ break;
203
211
  case 'Fragment':
204
212
  case 'Root':
205
213
  nextNode = this._traverseChildren(prevNode, ['argumentDefinitions', 'directives', 'selections']);
@@ -28,7 +28,7 @@ var NodeKeys = {
28
28
  RootArgumentDefinition: [],
29
29
  ScalarField: ['args', 'directives'],
30
30
  Variable: [],
31
- DeferrableFragmentSpread: ['args']
31
+ DeferrableFragmentSpread: ['args', 'directives', 'fragmentArgs']
32
32
  };
33
33
 
34
34
  function visitIR(root, visitor) {
@@ -26,6 +26,12 @@ var GraphQLMultiReporter = function () {
26
26
  this._reporters = reporters;
27
27
  }
28
28
 
29
+ GraphQLMultiReporter.prototype.reportMessage = function reportMessage(message) {
30
+ this._reporters.forEach(function (reporter) {
31
+ reporter.reportMessage(message);
32
+ });
33
+ };
34
+
29
35
  GraphQLMultiReporter.prototype.reportTime = function reportTime(name, ms) {
30
36
  this._reporters.forEach(function (reporter) {
31
37
  reporter.reportTime(name, ms);
@@ -24,7 +24,7 @@ var _require2 = require('./GraphQLSchemaUtils'),
24
24
  getNullableType = _require2.getNullableType,
25
25
  getRawType = _require2.getRawType,
26
26
  getTypeFromAST = _require2.getTypeFromAST,
27
- isOperationDefinitionAST = _require2.isOperationDefinitionAST;
27
+ isExecutableDefinitionAST = _require2.isExecutableDefinitionAST;
28
28
 
29
29
  var _require3 = require('graphql'),
30
30
  assertCompositeType = _require3.assertCompositeType,
@@ -75,7 +75,7 @@ var GraphQLParser = function () {
75
75
  // TODO T24511737 figure out if this is dangerous
76
76
  schema = extendSchema(schema, ast, { assumeValid: true });
77
77
  ast.definitions.forEach(function (definition) {
78
- if (isOperationDefinitionAST(definition)) {
78
+ if (isExecutableDefinitionAST(definition)) {
79
79
  nodes.push(_this.transform(schema, definition));
80
80
  }
81
81
  }, this);
@@ -132,7 +132,7 @@ function getInterfaces(type) {
132
132
  *
133
133
  * Determine if an AST node contains a fragment/operation definition.
134
134
  */
135
- function isOperationDefinitionAST(ast) {
135
+ function isExecutableDefinitionAST(ast) {
136
136
  return ast.kind === 'FragmentDefinition' || ast.kind === 'OperationDefinition';
137
137
  }
138
138
 
@@ -172,7 +172,7 @@ module.exports = {
172
172
  implementsInterface: implementsInterface,
173
173
  isAbstractType: isAbstractType,
174
174
  isUnionType: isUnionType,
175
- isOperationDefinitionAST: isOperationDefinitionAST,
175
+ isExecutableDefinitionAST: isExecutableDefinitionAST,
176
176
  isSchemaDefinitionAST: isSchemaDefinitionAST,
177
177
  mayImplement: mayImplement
178
178
  };
@@ -17,7 +17,6 @@ var _require = require('graphql'),
17
17
  KnownArgumentNamesRule = _require.KnownArgumentNamesRule,
18
18
  KnownTypeNamesRule = _require.KnownTypeNamesRule,
19
19
  LoneAnonymousOperationRule = _require.LoneAnonymousOperationRule,
20
- NoFragmentCyclesRule = _require.NoFragmentCyclesRule,
21
20
  NoUnusedVariablesRule = _require.NoUnusedVariablesRule,
22
21
  PossibleFragmentSpreadsRule = _require.PossibleFragmentSpreadsRule,
23
22
  ProvidedNonNullArgumentsRule = _require.ProvidedNonNullArgumentsRule,
@@ -51,8 +50,10 @@ module.exports = {
51
50
  GLOBAL_RULES: [KnownArgumentNamesRule,
52
51
  // TODO #19327202 Relay Classic generates some fragments in runtime, so Relay
53
52
  // Modern queries might reference fragments unknown in build time
54
- //KnownFragmentNamesRule,
55
- NoFragmentCyclesRule,
53
+ // KnownFragmentNamesRule,
54
+ // TODO: #25618795 Because of @argumentDefinitions, this validation
55
+ // incorrectly flags a subset of fragments using @include/@skip as recursive.
56
+ // NoFragmentCyclesRule,
56
57
  // TODO #19327144 Because of @argumentDefinitions, this validation
57
58
  // incorrectly marks some fragment variables as undefined.
58
59
  // NoUndefinedVariablesRule,
@@ -99,6 +99,20 @@ function transformFragmentSpread(context, fragments, scope, spread) {
99
99
  });
100
100
  }
101
101
 
102
+ function transformDeferrableFragmentSpread(context, fragments, scope, spread) {
103
+ var directives = transformDirectives(scope, spread.directives);
104
+ var fragment = context.getFragment(spread.name);
105
+ var appliedFragment = transformFragment(context, fragments, scope, fragment, spread.fragmentArgs);
106
+ if (!appliedFragment) {
107
+ return null;
108
+ }
109
+ return (0, _extends3['default'])({}, spread, {
110
+ fragmentArgs: [],
111
+ directives: directives,
112
+ name: appliedFragment.name
113
+ });
114
+ }
115
+
102
116
  function transformField(context, fragments, scope, field) {
103
117
  var args = transformArguments(scope, field.args);
104
118
  var directives = transformDirectives(scope, field.directives);
@@ -150,6 +164,8 @@ function transformSelections(context, fragments, scope, selections) {
150
164
  nextSelection = transformNode(context, fragments, scope, selection);
151
165
  } else if (selection.kind === 'FragmentSpread') {
152
166
  nextSelection = transformFragmentSpread(context, fragments, scope, selection);
167
+ } else if (selection.kind === 'DeferrableFragmentSpread') {
168
+ nextSelection = transformDeferrableFragmentSpread(context, fragments, scope, selection);
153
169
  } else if (selection.kind === 'Condition') {
154
170
  var conditionSelections = transformCondition(context, fragments, scope, selection);
155
171
  if (conditionSelections) {
@@ -43,13 +43,6 @@ function generate(node) {
43
43
  }
44
44
 
45
45
  var RelayCodeGenVisitor = {
46
- enter: function enter(node) {
47
- if ((node.kind === 'FragmentSpread' || node.kind === 'ScalarField') && node.metadata && node.metadata.deferred) {
48
- return deferrableFragmentSpread(node.metadata.deferredFragmentName, node.metadata.deferredArgumentName, node.metadata.deferredArgumentStorageKey, node.metadata.idType);
49
- }
50
- return node;
51
- },
52
-
53
46
  leave: {
54
47
  Batch: function Batch(node) {
55
48
  require('fbjs/lib/invariant')(node.requests.length !== 0, 'Batch must contain Requests.');
@@ -294,25 +287,4 @@ function getStaticStorageKey(field) {
294
287
  return getStorageKey(field, {});
295
288
  }
296
289
 
297
- function deferrableFragmentSpread(fragmentName, argumentName, storageKey, idType) {
298
- return {
299
- kind: 'DeferrableFragmentSpread',
300
- name: fragmentName,
301
- args: [{
302
- kind: 'Argument',
303
- name: argumentName,
304
- metadata: null,
305
- value: {
306
- kind: 'Variable',
307
- variableName: argumentName,
308
- metadata: null,
309
- type: idType
310
- },
311
- type: idType
312
- }],
313
- rootFieldVariable: argumentName,
314
- storageKey: storageKey
315
- };
316
- }
317
-
318
290
  module.exports = { generate: generate };
@@ -33,30 +33,55 @@ let run = (() => {
33
33
  if (options.watch && !hasWatchmanRootFile(srcDir)) {
34
34
  throw new Error(('\n--watch requires that the src directory have a valid watchman "root" file.\n\nRoot files can include:\n- A .git/ Git folder\n- A .hg/ Mercurial folder\n- A .watchmanconfig file\n\nEnsure that one such file exists in ' + srcDir + ' or its parents.\n ').trim());
35
35
  }
36
+ if (options.verbose && options.quiet) {
37
+ throw new Error("I can't be quiet and verbose at the same time");
38
+ }
36
39
 
37
- var reporter = new ConsoleReporter({ verbose: options.verbose });
40
+ var reporter = new ConsoleReporter({
41
+ verbose: options.verbose,
42
+ quiet: options.quiet
43
+ });
38
44
 
39
45
  var useWatchman = options.watchman && (yield WatchmanClient.isAvailable());
40
46
 
47
+ var schema = getSchema(schemaPath);
41
48
  var parserConfigs = {
42
- 'default': {
49
+ js: {
43
50
  baseDir: srcDir,
44
51
  getFileFilter: require('./RelayJSModuleParser').getFileFilter,
45
52
  getParser: require('./RelayJSModuleParser').getParser,
46
53
  getSchema: function getSchema() {
47
- return _getSchema(schemaPath);
54
+ return schema;
48
55
  },
49
56
  watchmanExpression: useWatchman ? buildWatchExpression(options) : null,
50
57
  filepaths: useWatchman ? null : getFilepathsFromGlob(srcDir, options)
58
+ },
59
+ graphql: {
60
+ baseDir: srcDir,
61
+ getParser: DotGraphQLParser.getParser,
62
+ getSchema: function getSchema() {
63
+ return schema;
64
+ },
65
+ watchmanExpression: useWatchman ? buildWatchExpression({
66
+ extensions: ['graphql'],
67
+ include: options.include,
68
+ exclude: options.exclude
69
+ }) : null,
70
+ filepaths: useWatchman ? null : getFilepathsFromGlob(srcDir, {
71
+ extensions: ['graphql'],
72
+ include: options.include,
73
+ exclude: options.exclude
74
+ })
51
75
  }
52
76
  };
53
77
  var writerConfigs = {
54
- 'default': {
78
+ js: {
55
79
  getWriter: getRelayFileWriter(srcDir),
56
80
  isGeneratedFile: function isGeneratedFile(filePath) {
57
81
  return filePath.endsWith('.js') && filePath.includes('__generated__');
58
82
  },
59
- parser: 'default'
83
+ parser: 'js',
84
+ baseParsers: ['graphql']
60
85
  }
61
86
  };
62
87
  var codegenRunner = new CodegenRunner({
@@ -93,7 +118,8 @@ require('babel-polyfill');
93
118
  var _require = require('./GraphQLCompilerPublic'),
94
119
  CodegenRunner = _require.CodegenRunner,
95
120
  ConsoleReporter = _require.ConsoleReporter,
96
- WatchmanClient = _require.WatchmanClient;
121
+ WatchmanClient = _require.WatchmanClient,
122
+ DotGraphQLParser = _require.DotGraphQLParser;
97
123
 
98
124
  var _require2 = require('graphql'),
99
125
  buildASTSchema = _require2.buildASTSchema,
@@ -130,8 +156,6 @@ function getFilepathsFromGlob(baseDir, options) {
130
156
  var glob = require('fast-glob');
131
157
  return glob.sync(patterns, {
132
158
  cwd: baseDir,
133
- bashNative: [],
134
- onlyFiles: true,
135
159
  ignore: exclude
136
160
  });
137
161
  }
@@ -170,7 +194,7 @@ function getRelayFileWriter(baseDir) {
170
194
  };
171
195
  }
172
196
 
173
- function _getSchema(schemaPath) {
197
+ function getSchema(schemaPath) {
174
198
  try {
175
199
  var source = require('fs').readFileSync(schemaPath, 'utf8');
176
200
  if (require('path').extname(schemaPath) === '.json') {
@@ -232,6 +256,10 @@ var argv = require('yargs').usage('Create Relay generated files\n\n' + '$0 --sch
232
256
  describe: 'More verbose logging',
233
257
  type: 'boolean'
234
258
  },
259
+ quiet: {
260
+ describe: 'No output to stdout',
261
+ type: 'boolean'
262
+ },
235
263
  watchman: {
236
264
  describe: 'Use watchman when not in watch mode',
237
265
  type: 'boolean',
@@ -23,7 +23,7 @@ var _require = require('graphql'),
23
23
  isInputType = _require.isInputType,
24
24
  GraphQLInterfaceType = _require.GraphQLInterfaceType,
25
25
  GraphQLList = _require.GraphQLList,
26
- GraphQLScalarType = _require.GraphQLScalarType;
26
+ GraphQLInputType = _require.GraphQLInputType;
27
27
 
28
28
  var _require2 = require('./GraphQLCompilerPublic'),
29
29
  IRTransformer = _require2.IRTransformer,
@@ -89,8 +89,6 @@ function transformOperations(context) {
89
89
  return context;
90
90
  }
91
91
 
92
- var idType = getIdType(context.clientSchema);
93
-
94
92
  // Next, transform any existing root operations to include references to
95
93
  // their dependent requests.
96
94
  var transformedContext = IRTransformer.transform(context, {
@@ -121,18 +119,8 @@ function transformOperations(context) {
121
119
  });
122
120
  return completeDeferrableOperation;
123
121
  });
124
- var transformedContextPostFragments = IRTransformer.transform(transformedContext, {
125
- FragmentSpread: function FragmentSpread(spread) {
126
- if (isDeferrable(spread)) {
127
- return (0, _extends3['default'])({}, spread, {
128
- metadata: (0, _extends3['default'])({}, spread.metadata, deferrableFragmentSpreadMetadata(spread.name, idType))
129
- });
130
- }
131
- return spread;
132
- }
133
- });
134
122
 
135
- return transformedContextPostFragments.addAll(deferrableOperations);
123
+ return transformedContext.addAll(deferrableOperations);
136
124
  }
137
125
 
138
126
  /**
@@ -364,16 +352,7 @@ function createDeferrableReference(context, spread) {
364
352
  metadata: null,
365
353
  typeCondition: nodeType,
366
354
  directives: [],
367
- selections: [{
368
- kind: 'ScalarField',
369
- name: 'id',
370
- alias: deferrableAlias(spread.name),
371
- args: [],
372
- handles: null,
373
- directives: spread.directives,
374
- metadata: (0, _extends3['default'])({}, spread.metadata, deferrableFragmentSpreadMetadata(spread.name, idType)),
375
- type: idType
376
- }]
355
+ selections: [deferrableFragmentSpread(spread, idType)]
377
356
  }]
378
357
  };
379
358
  }
@@ -427,7 +406,7 @@ function createDeferrableOperation(context, fragment) {
427
406
  kind: 'FragmentSpread',
428
407
  args: [],
429
408
  name: fragment.name,
430
- metadata: deferrableFragmentSpreadMetadata(fragment.name, idType),
409
+ metadata: null,
431
410
  directives: []
432
411
  }],
433
412
  type: nodeField.type
@@ -436,20 +415,34 @@ function createDeferrableOperation(context, fragment) {
436
415
  };
437
416
  }
438
417
 
439
- function deferrableFragmentSpreadMetadata(name, idType) {
440
- return {
441
- deferred: true,
442
- deferredFragmentName: name,
443
- deferredArgumentName: DEFERRABLE_ARGUMENT_NAME,
444
- deferredArgumentStorageKey: 'id',
445
- idType: idType
446
- };
447
- }
448
-
449
418
  function deferrableAlias(name) {
450
419
  return name + '_' + DEFERRABLE_ARGUMENT_NAME;
451
420
  }
452
421
 
422
+ function deferrableFragmentSpread(spread, idType) {
423
+ return {
424
+ kind: 'DeferrableFragmentSpread',
425
+ name: spread.name,
426
+ directives: [],
427
+ fragmentArgs: spread.args,
428
+ args: [{
429
+ kind: 'Argument',
430
+ name: DEFERRABLE_ARGUMENT_NAME,
431
+ metadata: null,
432
+ value: {
433
+ kind: 'Variable',
434
+ variableName: DEFERRABLE_ARGUMENT_NAME,
435
+ metadata: null,
436
+ type: idType
437
+ },
438
+ type: idType
439
+ }],
440
+ rootFieldVariable: DEFERRABLE_ARGUMENT_NAME,
441
+ storageKey: 'id',
442
+ alias: deferrableAlias(spread.name)
443
+ };
444
+ }
445
+
453
446
  function getNodeType(schema) {
454
447
  var nodeType = schema.getType('Node');
455
448
  require('fbjs/lib/invariant')(nodeType instanceof GraphQLInterfaceType, 'RelayDeferrableFragmentTransform: Schema must define the interface "Node".');
@@ -461,7 +454,7 @@ function getIdType(schema) {
461
454
  var idField = nodeType.getFields().id;
462
455
  require('fbjs/lib/invariant')(idField, 'RelayDeferrableFragmentTransform: "Node" must define the field "id"');
463
456
  var idType = getNamedType(idField.type);
464
- require('fbjs/lib/invariant')(idType instanceof GraphQLScalarType, 'RelayDeferrableFragmentTransform: "Node" must define the scalar field "id"');
457
+ require('fbjs/lib/invariant')(isInputType(idType), 'RelayDeferrableFragmentTransform: "Node" must define the scalar field "id"');
465
458
  return idType;
466
459
  }
467
460
 
@@ -31,7 +31,7 @@ var _require = require('./GraphQLCompilerPublic'),
31
31
  var _require2 = require('immutable'),
32
32
  ImmutableMap = _require2.Map;
33
33
 
34
- var isOperationDefinitionAST = SchemaUtils.isOperationDefinitionAST;
34
+ var isExecutableDefinitionAST = SchemaUtils.isExecutableDefinitionAST;
35
35
 
36
36
  var RelayFileWriter = function () {
37
37
  function RelayFileWriter(_ref) {
@@ -67,7 +67,7 @@ var RelayFileWriter = function () {
67
67
  var baseDefinitionNames = new Set();
68
68
  _this._baseDocuments.forEach(function (doc) {
69
69
  doc.definitions.forEach(function (def) {
70
- if (isOperationDefinitionAST(def) && def.name) {
70
+ if (isExecutableDefinitionAST(def) && def.name) {
71
71
  baseDefinitionNames.add(def.name.value);
72
72
  }
73
73
  });