relay-compiler 7.0.0 → 9.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. package/bin/RelayCompilerBin.js.flow +169 -0
  2. package/bin/RelayCompilerMain.js.flow +508 -0
  3. package/bin/__fixtures__/plugin-module.js.flow +17 -0
  4. package/bin/relay-compiler +8554 -8142
  5. package/codegen/CodegenDirectory.js.flow +375 -0
  6. package/codegen/CodegenRunner.js.flow +431 -0
  7. package/codegen/CodegenTypes.js.flow +28 -0
  8. package/codegen/CodegenWatcher.js.flow +254 -0
  9. package/codegen/NormalizationCodeGenerator.js.flow +499 -0
  10. package/codegen/ReaderCodeGenerator.js.flow +453 -0
  11. package/codegen/RelayCodeGenerator.js.flow +76 -0
  12. package/codegen/RelayFileWriter.js.flow +366 -0
  13. package/codegen/SourceControl.js.flow +58 -0
  14. package/codegen/compileRelayArtifacts.js.flow +182 -0
  15. package/codegen/createPrintRequireModuleDependency.js.flow +21 -0
  16. package/codegen/writeRelayGeneratedFile.js.flow +194 -0
  17. package/core/ASTCache.js.flow +73 -0
  18. package/core/ASTConvert.js.flow +233 -0
  19. package/core/CompilerContext.js.flow +190 -0
  20. package/core/CompilerError.js.flow +250 -0
  21. package/core/DotGraphQLParser.js.flow +39 -0
  22. package/core/GraphQLCompilerProfiler.js.flow +341 -0
  23. package/core/GraphQLDerivedFromMetadata.js.flow +48 -0
  24. package/core/GraphQLWatchmanClient.js.flow +111 -0
  25. package/core/IR.js.flow +329 -0
  26. package/core/IRPrinter.js.flow +488 -0
  27. package/core/IRTransformer.js.flow +377 -0
  28. package/core/IRValidator.js.flow +260 -0
  29. package/core/IRVisitor.js.flow +150 -0
  30. package/core/JSModuleParser.js.flow +24 -0
  31. package/core/RelayCompilerScope.js.flow +199 -0
  32. package/core/RelayFindGraphQLTags.js.flow +119 -0
  33. package/core/RelayGraphQLEnumsGenerator.js.flow +55 -0
  34. package/core/RelayIRTransforms.js.flow +130 -0
  35. package/core/RelayParser.js.flow +1759 -0
  36. package/core/RelaySourceModuleParser.js.flow +135 -0
  37. package/core/Schema.js.flow +1985 -0
  38. package/core/SchemaUtils.js.flow +109 -0
  39. package/core/filterContextForNode.js.flow +50 -0
  40. package/core/getFieldDefinition.js.flow +156 -0
  41. package/core/getIdentifierForArgumentValue.js.flow +49 -0
  42. package/core/getIdentifierForSelection.js.flow +69 -0
  43. package/core/getLiteralArgumentValues.js.flow +32 -0
  44. package/core/getNormalizationOperationName.js.flow +19 -0
  45. package/core/inferRootArgumentDefinitions.js.flow +323 -0
  46. package/index.js +1 -1
  47. package/index.js.flow +202 -0
  48. package/language/RelayLanguagePluginInterface.js.flow +283 -0
  49. package/language/javascript/FindGraphQLTags.js.flow +233 -0
  50. package/language/javascript/RelayFlowBabelFactories.js.flow +180 -0
  51. package/language/javascript/RelayFlowGenerator.js.flow +1040 -0
  52. package/language/javascript/RelayFlowTypeTransformers.js.flow +184 -0
  53. package/language/javascript/RelayLanguagePluginJavaScript.js.flow +34 -0
  54. package/language/javascript/formatGeneratedModule.js.flow +65 -0
  55. package/lib/bin/RelayCompilerBin.js +25 -7
  56. package/lib/bin/RelayCompilerMain.js +134 -125
  57. package/lib/bin/__fixtures__/plugin-module.js +1 -0
  58. package/lib/codegen/CodegenDirectory.js +14 -8
  59. package/lib/codegen/CodegenRunner.js +35 -75
  60. package/lib/codegen/CodegenTypes.js +1 -0
  61. package/lib/codegen/CodegenWatcher.js +14 -21
  62. package/lib/codegen/NormalizationCodeGenerator.js +80 -127
  63. package/lib/codegen/ReaderCodeGenerator.js +85 -111
  64. package/lib/codegen/RelayCodeGenerator.js +9 -6
  65. package/lib/codegen/RelayFileWriter.js +22 -41
  66. package/lib/codegen/SourceControl.js +1 -0
  67. package/lib/codegen/compileRelayArtifacts.js +18 -31
  68. package/lib/codegen/createPrintRequireModuleDependency.js +1 -0
  69. package/lib/codegen/writeRelayGeneratedFile.js +62 -90
  70. package/lib/core/ASTCache.js +4 -4
  71. package/lib/core/ASTConvert.js +1 -0
  72. package/lib/core/{GraphQLCompilerContext.js → CompilerContext.js} +10 -11
  73. package/lib/core/{RelayCompilerError.js → CompilerError.js} +29 -55
  74. package/lib/core/DotGraphQLParser.js +1 -0
  75. package/lib/core/GraphQLCompilerProfiler.js +9 -12
  76. package/lib/core/GraphQLDerivedFromMetadata.js +1 -0
  77. package/lib/core/GraphQLWatchmanClient.js +5 -12
  78. package/lib/core/{GraphQLIR.js → IR.js} +1 -0
  79. package/lib/core/{GraphQLIRPrinter.js → IRPrinter.js} +39 -17
  80. package/lib/core/{GraphQLIRTransformer.js → IRTransformer.js} +21 -16
  81. package/lib/core/{GraphQLIRValidator.js → IRValidator.js} +18 -10
  82. package/lib/core/{GraphQLIRVisitor.js → IRVisitor.js} +1 -2
  83. package/lib/core/JSModuleParser.js +18 -0
  84. package/lib/core/RelayCompilerScope.js +6 -5
  85. package/lib/core/RelayFindGraphQLTags.js +1 -0
  86. package/lib/core/RelayGraphQLEnumsGenerator.js +26 -12
  87. package/lib/core/RelayIRTransforms.js +12 -9
  88. package/lib/core/RelayParser.js +113 -75
  89. package/lib/core/RelaySourceModuleParser.js +4 -3
  90. package/lib/core/Schema.js +808 -317
  91. package/lib/core/SchemaUtils.js +1 -0
  92. package/lib/core/filterContextForNode.js +5 -4
  93. package/lib/core/getFieldDefinition.js +14 -16
  94. package/lib/core/getIdentifierForArgumentValue.js +18 -0
  95. package/lib/core/getIdentifierForSelection.js +4 -5
  96. package/lib/core/getLiteralArgumentValues.js +1 -0
  97. package/lib/core/getNormalizationOperationName.js +1 -0
  98. package/lib/core/inferRootArgumentDefinitions.js +79 -99
  99. package/lib/index.js +69 -19
  100. package/lib/language/RelayLanguagePluginInterface.js +1 -0
  101. package/lib/language/javascript/FindGraphQLTags.js +1 -0
  102. package/lib/language/javascript/RelayFlowBabelFactories.js +15 -0
  103. package/lib/language/javascript/RelayFlowGenerator.js +94 -173
  104. package/lib/language/javascript/RelayFlowTypeTransformers.js +2 -3
  105. package/lib/language/javascript/RelayLanguagePluginJavaScript.js +7 -4
  106. package/lib/language/javascript/formatGeneratedModule.js +14 -4
  107. package/lib/reporters/ConsoleReporter.js +2 -3
  108. package/lib/reporters/MultiReporter.js +2 -3
  109. package/lib/reporters/Reporter.js +1 -0
  110. package/lib/runner/Artifacts.js +327 -0
  111. package/lib/runner/BufferedFilesystem.js +265 -0
  112. package/lib/runner/GraphQLASTNodeGroup.js +260 -0
  113. package/lib/runner/GraphQLASTUtils.js +23 -0
  114. package/lib/runner/GraphQLNodeMap.js +85 -0
  115. package/lib/runner/Sources.js +266 -0
  116. package/lib/runner/StrictMap.js +136 -0
  117. package/lib/runner/compileArtifacts.js +39 -0
  118. package/lib/runner/extractAST.js +77 -0
  119. package/lib/runner/getChangedNodeNames.js +84 -0
  120. package/lib/runner/getSchemaInstance.js +30 -0
  121. package/lib/runner/types.js +12 -0
  122. package/lib/transforms/ApplyFragmentArgumentTransform.js +49 -55
  123. package/lib/transforms/ClientExtensionsTransform.js +11 -17
  124. package/lib/transforms/ConnectionTransform.js +35 -28
  125. package/lib/transforms/DeferStreamTransform.js +26 -74
  126. package/lib/transforms/DisallowIdAsAlias.js +5 -4
  127. package/lib/transforms/DisallowTypenameOnRoot.js +55 -0
  128. package/lib/transforms/FieldHandleTransform.js +8 -3
  129. package/lib/transforms/FilterDirectivesTransform.js +4 -3
  130. package/lib/transforms/FlattenTransform.js +23 -47
  131. package/lib/transforms/GenerateIDFieldTransform.js +9 -4
  132. package/lib/transforms/GenerateTypeNameTransform.js +8 -3
  133. package/lib/transforms/InlineDataFragmentTransform.js +11 -6
  134. package/lib/transforms/InlineFragmentsTransform.js +3 -2
  135. package/lib/transforms/MaskTransform.js +20 -19
  136. package/lib/transforms/MatchTransform.js +113 -34
  137. package/lib/transforms/RefetchableFragmentTransform.js +25 -41
  138. package/lib/transforms/RelayDirectiveTransform.js +13 -4
  139. package/lib/transforms/SkipClientExtensionsTransform.js +11 -2
  140. package/lib/transforms/SkipHandleFieldTransform.js +8 -3
  141. package/lib/transforms/SkipRedundantNodesTransform.js +9 -6
  142. package/lib/transforms/SkipSplitOperationTransform.js +32 -0
  143. package/lib/transforms/SkipUnreachableNodeTransform.js +12 -12
  144. package/lib/transforms/SkipUnusedVariablesTransform.js +19 -17
  145. package/lib/transforms/SplitModuleImportTransform.js +4 -3
  146. package/lib/transforms/TestOperationTransform.js +9 -6
  147. package/lib/transforms/TransformUtils.js +1 -0
  148. package/lib/transforms/ValidateGlobalVariablesTransform.js +20 -31
  149. package/lib/transforms/ValidateRequiredArgumentsTransform.js +17 -20
  150. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +20 -33
  151. package/lib/transforms/ValidateUnusedVariablesTransform.js +20 -31
  152. package/lib/transforms/query-generators/FetchableQueryGenerator.js +161 -0
  153. package/lib/transforms/query-generators/NodeQueryGenerator.js +9 -3
  154. package/lib/transforms/query-generators/QueryQueryGenerator.js +2 -0
  155. package/lib/transforms/query-generators/ViewerQueryGenerator.js +6 -3
  156. package/lib/transforms/query-generators/index.js +25 -7
  157. package/lib/transforms/query-generators/utils.js +13 -15
  158. package/lib/util/CodeMarker.js +1 -0
  159. package/lib/util/DefaultHandleKey.js +1 -0
  160. package/lib/util/RelayCompilerCache.js +2 -3
  161. package/lib/util/Rollout.js +1 -0
  162. package/lib/util/TimeReporter.js +83 -0
  163. package/lib/util/areEqualOSS.js +1 -0
  164. package/lib/util/dedupeJSONStringify.js +16 -12
  165. package/lib/util/getDefinitionNodeHash.js +22 -0
  166. package/lib/util/getModuleName.js +4 -5
  167. package/lib/util/joinArgumentDefinitions.js +2 -1
  168. package/lib/util/md5.js +17 -0
  169. package/lib/util/murmurHash.js +1 -0
  170. package/lib/util/nullthrowsOSS.js +1 -0
  171. package/lib/util/orList.js +2 -1
  172. package/lib/util/partitionArray.js +1 -0
  173. package/package.json +4 -4
  174. package/relay-compiler.js +4 -4
  175. package/relay-compiler.min.js +4 -4
  176. package/reporters/ConsoleReporter.js.flow +81 -0
  177. package/reporters/MultiReporter.js.flow +43 -0
  178. package/reporters/Reporter.js.flow +19 -0
  179. package/runner/Artifacts.js.flow +219 -0
  180. package/runner/BufferedFilesystem.js.flow +194 -0
  181. package/runner/GraphQLASTNodeGroup.js.flow +176 -0
  182. package/runner/GraphQLASTUtils.js.flow +26 -0
  183. package/runner/GraphQLNodeMap.js.flow +55 -0
  184. package/runner/Sources.js.flow +218 -0
  185. package/runner/StrictMap.js.flow +96 -0
  186. package/runner/compileArtifacts.js.flow +76 -0
  187. package/runner/extractAST.js.flow +100 -0
  188. package/runner/getChangedNodeNames.js.flow +48 -0
  189. package/runner/getSchemaInstance.js.flow +36 -0
  190. package/runner/types.js.flow +37 -0
  191. package/transforms/ApplyFragmentArgumentTransform.js.flow +474 -0
  192. package/transforms/ClientExtensionsTransform.js.flow +220 -0
  193. package/transforms/ConnectionTransform.js.flow +869 -0
  194. package/transforms/DeferStreamTransform.js.flow +258 -0
  195. package/transforms/DisallowIdAsAlias.js.flow +47 -0
  196. package/transforms/DisallowTypenameOnRoot.js.flow +45 -0
  197. package/transforms/FieldHandleTransform.js.flow +80 -0
  198. package/transforms/FilterDirectivesTransform.js.flow +45 -0
  199. package/transforms/FlattenTransform.js.flow +456 -0
  200. package/transforms/GenerateIDFieldTransform.js.flow +134 -0
  201. package/transforms/GenerateTypeNameTransform.js.flow +81 -0
  202. package/transforms/InlineDataFragmentTransform.js.flow +124 -0
  203. package/transforms/InlineFragmentsTransform.js.flow +71 -0
  204. package/transforms/MaskTransform.js.flow +126 -0
  205. package/transforms/MatchTransform.js.flow +583 -0
  206. package/transforms/RefetchableFragmentTransform.js.flow +272 -0
  207. package/transforms/RelayDirectiveTransform.js.flow +99 -0
  208. package/transforms/SkipClientExtensionsTransform.js.flow +54 -0
  209. package/transforms/SkipHandleFieldTransform.js.flow +44 -0
  210. package/transforms/SkipRedundantNodesTransform.js.flow +253 -0
  211. package/transforms/SkipSplitOperationTransform.js.flow +37 -0
  212. package/transforms/SkipUnreachableNodeTransform.js.flow +149 -0
  213. package/transforms/SkipUnusedVariablesTransform.js.flow +59 -0
  214. package/transforms/SplitModuleImportTransform.js.flow +98 -0
  215. package/transforms/TestOperationTransform.js.flow +138 -0
  216. package/transforms/TransformUtils.js.flow +26 -0
  217. package/transforms/ValidateGlobalVariablesTransform.js.flow +81 -0
  218. package/transforms/ValidateRequiredArgumentsTransform.js.flow +127 -0
  219. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +112 -0
  220. package/transforms/ValidateUnusedVariablesTransform.js.flow +89 -0
  221. package/transforms/query-generators/FetchableQueryGenerator.js.flow +190 -0
  222. package/transforms/query-generators/NodeQueryGenerator.js.flow +206 -0
  223. package/transforms/query-generators/QueryQueryGenerator.js.flow +57 -0
  224. package/transforms/query-generators/ViewerQueryGenerator.js.flow +97 -0
  225. package/transforms/query-generators/index.js.flow +90 -0
  226. package/transforms/query-generators/utils.js.flow +72 -0
  227. package/util/CodeMarker.js.flow +79 -0
  228. package/util/DefaultHandleKey.js.flow +17 -0
  229. package/util/RelayCompilerCache.js.flow +88 -0
  230. package/util/Rollout.js.flow +39 -0
  231. package/util/TimeReporter.js.flow +79 -0
  232. package/util/areEqualOSS.js.flow +123 -0
  233. package/util/dedupeJSONStringify.js.flow +152 -0
  234. package/util/getDefinitionNodeHash.js.flow +25 -0
  235. package/util/getModuleName.js.flow +39 -0
  236. package/util/joinArgumentDefinitions.js.flow +99 -0
  237. package/util/md5.js.flow +22 -0
  238. package/util/murmurHash.js.flow +94 -0
  239. package/util/nullthrowsOSS.js.flow +25 -0
  240. package/util/orList.js.flow +37 -0
  241. package/util/partitionArray.js.flow +37 -0
  242. package/lib/transforms/ConnectionFieldTransform.js +0 -275
@@ -0,0 +1,366 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const ASTConvert = require('../core/ASTConvert');
16
+ const CodegenDirectory = require('./CodegenDirectory');
17
+ const CompilerContext = require('../core/CompilerContext');
18
+ const Profiler = require('../core/GraphQLCompilerProfiler');
19
+ const RelayParser = require('../core/RelayParser');
20
+
21
+ const compileRelayArtifacts = require('./compileRelayArtifacts');
22
+ const graphql = require('graphql');
23
+ const invariant = require('invariant');
24
+ const md5 = require('../util/md5');
25
+ const nullthrows = require('nullthrows');
26
+ const path = require('path');
27
+ const writeRelayGeneratedFile = require('./writeRelayGeneratedFile');
28
+
29
+ const {
30
+ getReaderSourceDefinitionName,
31
+ } = require('../core/GraphQLDerivedFromMetadata');
32
+ const {isExecutableDefinitionAST} = require('../core/SchemaUtils');
33
+ const {Map: ImmutableMap} = require('immutable');
34
+
35
+ import type {Schema} from '../core/Schema';
36
+ import type {
37
+ FormatModule,
38
+ PluginInterface,
39
+ TypeGenerator,
40
+ } from '../language/RelayLanguagePluginInterface';
41
+ import type {ScalarTypeMapping} from '../language/javascript/RelayFlowTypeTransformers';
42
+ import type {Reporter} from '../reporters/Reporter';
43
+ import type {Filesystem} from './CodegenDirectory';
44
+ import type {SourceControl} from './SourceControl';
45
+ import type {RelayCompilerTransforms} from './compileRelayArtifacts';
46
+ import type {DocumentNode, ValidationContext} from 'graphql';
47
+ import type {RequestParameters} from 'relay-runtime';
48
+
49
+ export type GenerateExtraFiles = (
50
+ getOutputDirectory: (path?: string) => CodegenDirectory,
51
+ compilerContext: CompilerContext,
52
+ getGeneratedDirectory: (definitionName: string) => CodegenDirectory,
53
+ ) => void;
54
+
55
+ export type ValidationRule = (context: ValidationContext) => any;
56
+
57
+ export type WriterConfig = {
58
+ baseDir: string,
59
+ compilerTransforms: RelayCompilerTransforms,
60
+ customScalars: ScalarTypeMapping,
61
+ formatModule: FormatModule,
62
+ generateExtraFiles?: GenerateExtraFiles,
63
+ optionalInputFieldsForFlow: $ReadOnlyArray<string>,
64
+ outputDir?: ?string,
65
+ generatedDirectories?: $ReadOnlyArray<string>,
66
+ persistQuery?: ?(text: string) => Promise<string>,
67
+ schemaExtensions: $ReadOnlyArray<string>,
68
+ noFutureProofEnums: boolean,
69
+ useHaste: boolean,
70
+ extension: string,
71
+ typeGenerator: TypeGenerator,
72
+ // Haste style module that exports flow types for GraphQL enums.
73
+ // TODO(T22422153) support non-haste environments
74
+ enumsHasteModule?: string,
75
+ printModuleDependency?: string => string,
76
+ filesystem?: Filesystem,
77
+ repersist?: boolean,
78
+ writeQueryParameters?: (
79
+ outputDirectory: CodegenDirectory,
80
+ filename: string,
81
+ moduleName: string,
82
+ requestParams: RequestParameters,
83
+ ) => void,
84
+ ...
85
+ };
86
+
87
+ function compileAll({
88
+ baseDir,
89
+ baseDocuments,
90
+ schema,
91
+ compilerTransforms,
92
+ documents,
93
+ reporter,
94
+ typeGenerator,
95
+ }: {|
96
+ baseDir: string,
97
+ baseDocuments: $ReadOnlyArray<DocumentNode>,
98
+ schema: Schema,
99
+ compilerTransforms: RelayCompilerTransforms,
100
+ documents: $ReadOnlyArray<DocumentNode>,
101
+ reporter: Reporter,
102
+ typeGenerator: TypeGenerator,
103
+ |}) {
104
+ const definitions = ASTConvert.convertASTDocumentsWithBase(
105
+ schema,
106
+ baseDocuments,
107
+ documents,
108
+ RelayParser.transform,
109
+ );
110
+ const compilerContext = new CompilerContext(schema).addAll(definitions);
111
+
112
+ const transformedTypeContext = compilerContext.applyTransforms(
113
+ typeGenerator.transforms,
114
+ reporter,
115
+ );
116
+ const transformedQueryContext = compilerContext.applyTransforms(
117
+ [
118
+ ...compilerTransforms.commonTransforms,
119
+ ...compilerTransforms.queryTransforms,
120
+ ],
121
+ reporter,
122
+ );
123
+ const artifacts = compileRelayArtifacts(
124
+ compilerContext,
125
+ compilerTransforms,
126
+ reporter,
127
+ );
128
+
129
+ return {
130
+ artifacts,
131
+ definitions,
132
+ transformedQueryContext,
133
+ transformedTypeContext,
134
+ };
135
+ }
136
+
137
+ function writeAll({
138
+ config: writerConfig,
139
+ onlyValidate,
140
+ baseDocuments,
141
+ documents,
142
+ schema,
143
+ reporter,
144
+ sourceControl,
145
+ languagePlugin,
146
+ }: {|
147
+ config: WriterConfig,
148
+ onlyValidate: boolean,
149
+ baseDocuments: ImmutableMap<string, DocumentNode>,
150
+ documents: ImmutableMap<string, DocumentNode>,
151
+ schema: Schema,
152
+ reporter: Reporter,
153
+ sourceControl: ?SourceControl,
154
+ languagePlugin?: ?PluginInterface,
155
+ |}): Promise<Map<string, CodegenDirectory>> {
156
+ return Profiler.asyncContext('RelayFileWriter.writeAll', async () => {
157
+ const {
158
+ artifacts: artifactsWithBase,
159
+ definitions,
160
+ transformedTypeContext,
161
+ transformedQueryContext,
162
+ } = compileAll({
163
+ schema,
164
+ baseDir: writerConfig.baseDir,
165
+ baseDocuments: baseDocuments.valueSeq().toArray(),
166
+ compilerTransforms: writerConfig.compilerTransforms,
167
+ documents: documents.valueSeq().toArray(),
168
+ reporter,
169
+ typeGenerator: writerConfig.typeGenerator,
170
+ });
171
+ // Build a context from all the documents
172
+ const baseDefinitionNames = new Set();
173
+ baseDocuments.forEach(doc => {
174
+ doc.definitions.forEach(def => {
175
+ if (isExecutableDefinitionAST(def) && def.name) {
176
+ baseDefinitionNames.add(def.name.value);
177
+ }
178
+ });
179
+ });
180
+
181
+ // remove nodes that are present in the base or that derive from nodes
182
+ // in the base
183
+ const artifacts = artifactsWithBase.filter(([_definition, node]) => {
184
+ const sourceName = getReaderSourceDefinitionName(node);
185
+ return !baseDefinitionNames.has(sourceName);
186
+ });
187
+
188
+ const artifactMap = new Map(
189
+ artifacts.map(([_definition, node]) => [
190
+ node.kind === 'Request' ? node.params.name : node.name,
191
+ node,
192
+ ]),
193
+ );
194
+
195
+ const definitionsMeta = new Map();
196
+ const getDefinitionMeta = (definitionName: string) => {
197
+ const artifact = nullthrows(artifactMap.get(definitionName));
198
+ const sourceName = getReaderSourceDefinitionName(artifact);
199
+ const definitionMeta = definitionsMeta.get(sourceName);
200
+ invariant(
201
+ definitionMeta,
202
+ 'RelayFileWriter: Could not determine source for definition: `%s`.',
203
+ definitionName,
204
+ );
205
+ return definitionMeta;
206
+ };
207
+ documents.forEach((doc, filePath) => {
208
+ doc.definitions.forEach(def => {
209
+ if (def.name) {
210
+ definitionsMeta.set(def.name.value, {
211
+ dir: path.join(writerConfig.baseDir, path.dirname(filePath)),
212
+ ast: def,
213
+ });
214
+ }
215
+ });
216
+ });
217
+
218
+ const allOutputDirectories: Map<string, CodegenDirectory> = new Map();
219
+ const addCodegenDir = dirPath => {
220
+ const codegenDir = new CodegenDirectory(dirPath, {
221
+ onlyValidate: onlyValidate,
222
+ filesystem: writerConfig.filesystem,
223
+ });
224
+ allOutputDirectories.set(dirPath, codegenDir);
225
+ return codegenDir;
226
+ };
227
+
228
+ for (const existingDirectory of writerConfig.generatedDirectories || []) {
229
+ addCodegenDir(existingDirectory);
230
+ }
231
+
232
+ let configOutputDirectory;
233
+ if (writerConfig.outputDir) {
234
+ configOutputDirectory = addCodegenDir(writerConfig.outputDir);
235
+ }
236
+
237
+ const getGeneratedDirectory = definitionName => {
238
+ if (configOutputDirectory) {
239
+ return configOutputDirectory;
240
+ }
241
+ const generatedPath = path.join(
242
+ getDefinitionMeta(definitionName).dir,
243
+ '__generated__',
244
+ );
245
+ let cachedDir = allOutputDirectories.get(generatedPath);
246
+ if (!cachedDir) {
247
+ cachedDir = addCodegenDir(generatedPath);
248
+ }
249
+ return cachedDir;
250
+ };
251
+
252
+ const formatModule = Profiler.instrument(
253
+ writerConfig.formatModule,
254
+ 'RelayFileWriter:formatModule',
255
+ );
256
+
257
+ const persistQuery = writerConfig.persistQuery
258
+ ? Profiler.instrumentWait(
259
+ writerConfig.persistQuery,
260
+ 'RelayFileWriter:persistQuery',
261
+ )
262
+ : null;
263
+
264
+ try {
265
+ await Promise.all(
266
+ artifacts.map(async ([definition, node]) => {
267
+ const nodeName =
268
+ node.kind === 'Request' ? node.params.name : node.name;
269
+ if (baseDefinitionNames.has(nodeName)) {
270
+ // don't add definitions that were part of base context
271
+ return;
272
+ }
273
+
274
+ const typeNode = transformedTypeContext.get(nodeName);
275
+ const typeText = typeNode
276
+ ? writerConfig.typeGenerator.generate(
277
+ schema,
278
+ (typeNode: $FlowFixMe),
279
+ {
280
+ customScalars: writerConfig.customScalars,
281
+ enumsHasteModule: writerConfig.enumsHasteModule,
282
+ optionalInputFields: writerConfig.optionalInputFieldsForFlow,
283
+ useHaste: writerConfig.useHaste,
284
+ useSingleArtifactDirectory: !!writerConfig.outputDir,
285
+ noFutureProofEnums: writerConfig.noFutureProofEnums,
286
+ normalizationIR:
287
+ definition.kind === 'Request' ? definition.root : undefined,
288
+ },
289
+ )
290
+ : '';
291
+
292
+ const sourceHash = Profiler.run('hashGraphQL', () =>
293
+ md5(graphql.print(getDefinitionMeta(nodeName).ast)),
294
+ );
295
+
296
+ await writeRelayGeneratedFile(
297
+ schema,
298
+ getGeneratedDirectory(nodeName),
299
+ definition,
300
+ node,
301
+ formatModule,
302
+ typeText,
303
+ persistQuery,
304
+ sourceHash,
305
+ writerConfig.extension,
306
+ writerConfig.printModuleDependency,
307
+ writerConfig.repersist ?? false,
308
+ writerConfig.writeQueryParameters ?? function noop() {},
309
+ languagePlugin,
310
+ );
311
+ }),
312
+ );
313
+
314
+ const generateExtraFiles = writerConfig.generateExtraFiles;
315
+ if (generateExtraFiles) {
316
+ Profiler.run('RelayFileWriter:generateExtraFiles', () => {
317
+ const configDirectory = writerConfig.outputDir;
318
+ generateExtraFiles(
319
+ dir => {
320
+ const outputDirectory = dir || configDirectory;
321
+ invariant(
322
+ outputDirectory,
323
+ 'RelayFileWriter: cannot generate extra files without specifying ' +
324
+ 'an outputDir in the config or passing it in.',
325
+ );
326
+ let outputDir = allOutputDirectories.get(outputDirectory);
327
+ if (!outputDir) {
328
+ outputDir = addCodegenDir(outputDirectory);
329
+ }
330
+ return outputDir;
331
+ },
332
+ transformedQueryContext,
333
+ getGeneratedDirectory,
334
+ );
335
+ });
336
+ }
337
+
338
+ allOutputDirectories.forEach(dir => {
339
+ dir.deleteExtraFiles(languagePlugin?.keepExtraFile);
340
+ });
341
+ if (sourceControl && !onlyValidate) {
342
+ await CodegenDirectory.sourceControlAddRemove(
343
+ sourceControl,
344
+ Array.from(allOutputDirectories.values()),
345
+ );
346
+ }
347
+ } catch (error) {
348
+ let details;
349
+ try {
350
+ details = JSON.parse(error.message);
351
+ } catch (_) {} // eslint-disable-line lint/no-unused-catch-bindings
352
+ if (details && details.name === 'GraphQL2Exception' && details.message) {
353
+ throw new Error('GraphQL error writing modules:\n' + details.message);
354
+ }
355
+ throw new Error(
356
+ 'Error writing modules:\n' + String(error.stack || error),
357
+ );
358
+ }
359
+
360
+ return allOutputDirectories;
361
+ });
362
+ }
363
+
364
+ module.exports = {
365
+ writeAll,
366
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const childProcess = require('child_process');
16
+
17
+ function execFile(cmd: string, args: Array<string>): Promise<void> {
18
+ return new Promise((resolve, reject) => {
19
+ childProcess.execFile(cmd, args, err => {
20
+ if (err) {
21
+ reject(err);
22
+ } else {
23
+ resolve();
24
+ }
25
+ });
26
+ });
27
+ }
28
+
29
+ /**
30
+ * An abstraction over the source control system to make it injectable.
31
+ */
32
+ export type SourceControl = {
33
+ addRemove(
34
+ added: $ReadOnlyArray<string>,
35
+ removed: $ReadOnlyArray<string>,
36
+ ): Promise<void>,
37
+ ...
38
+ };
39
+
40
+ const SourceControlMercurial: SourceControl = {
41
+ async addRemove(
42
+ added: $ReadOnlyArray<string>,
43
+ removed: $ReadOnlyArray<string>,
44
+ ): Promise<void> {
45
+ // NOTE: Not using `hg addremove` as that has a bug when deleting a file
46
+ // that was just added, but not yet committed: T10711513
47
+ if (added.length > 0) {
48
+ await execFile('hg', ['add', ...added]);
49
+ }
50
+ if (removed.length > 0) {
51
+ await execFile('hg', ['forget', ...removed]);
52
+ }
53
+ },
54
+ };
55
+
56
+ module.exports = {
57
+ SourceControlMercurial,
58
+ };
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict-local
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ const Printer = require('../core/IRPrinter');
16
+ const Profiler = require('../core/GraphQLCompilerProfiler');
17
+ const RelayCodeGenerator = require('./RelayCodeGenerator');
18
+
19
+ const filterContextForNode = require('../core/filterContextForNode');
20
+
21
+ import type CompilerContext from '../core/CompilerContext';
22
+ import type {IRTransform} from '../core/CompilerContext';
23
+ import type {GeneratedDefinition} from '../core/IR';
24
+ import type {Reporter} from '../reporters/Reporter';
25
+ import type {GeneratedNode} from 'relay-runtime';
26
+
27
+ export type RelayCompilerTransforms = {
28
+ commonTransforms: $ReadOnlyArray<IRTransform>,
29
+ codegenTransforms: $ReadOnlyArray<IRTransform>,
30
+ fragmentTransforms: $ReadOnlyArray<IRTransform>,
31
+ printTransforms: $ReadOnlyArray<IRTransform>,
32
+ queryTransforms: $ReadOnlyArray<IRTransform>,
33
+ ...
34
+ };
35
+
36
+ function createFragmentContext(
37
+ context: CompilerContext,
38
+ transforms: RelayCompilerTransforms,
39
+ reporter?: Reporter,
40
+ ): CompilerContext {
41
+ // The fragment is used for reading data from the normalized store.
42
+ return context.applyTransforms(
43
+ [...transforms.commonTransforms, ...transforms.fragmentTransforms],
44
+ reporter,
45
+ );
46
+ }
47
+
48
+ function createPrintContext(
49
+ context: CompilerContext,
50
+ transforms: RelayCompilerTransforms,
51
+ reporter?: Reporter,
52
+ ): CompilerContext {
53
+ // The unflattened query is used for printing, since flattening creates an
54
+ // invalid query.
55
+ return context.applyTransforms(
56
+ [
57
+ ...transforms.commonTransforms,
58
+ ...transforms.queryTransforms,
59
+ ...transforms.printTransforms,
60
+ ],
61
+ reporter,
62
+ );
63
+ }
64
+
65
+ function createCodeGenContext(
66
+ context: CompilerContext,
67
+ transforms: RelayCompilerTransforms,
68
+ reporter?: Reporter,
69
+ ): CompilerContext {
70
+ // The flattened query is used for codegen in order to reduce the number of
71
+ // duplicate fields that must be processed during response normalization.
72
+ return context.applyTransforms(
73
+ [
74
+ ...transforms.commonTransforms,
75
+ ...transforms.queryTransforms,
76
+ ...transforms.codegenTransforms,
77
+ ],
78
+ reporter,
79
+ );
80
+ }
81
+
82
+ function compile(
83
+ context: CompilerContext,
84
+ fragmentContext: CompilerContext,
85
+ printContext: CompilerContext,
86
+ codeGenContext: CompilerContext,
87
+ ): $ReadOnlyArray<[GeneratedDefinition, GeneratedNode]> {
88
+ const results = [];
89
+ const schema = context.getSchema();
90
+
91
+ // Add everything from codeGenContext, these are the operations as well as
92
+ // SplitOperations from @match.
93
+ for (const node of codeGenContext.documents()) {
94
+ if (node.kind === 'Root') {
95
+ const fragment = fragmentContext.getRoot(node.name);
96
+ const request = {
97
+ kind: 'Request',
98
+ fragment: {
99
+ kind: 'Fragment',
100
+ argumentDefinitions: fragment.argumentDefinitions,
101
+ directives: fragment.directives,
102
+ loc: {kind: 'Derived', source: node.loc},
103
+ metadata: null,
104
+ name: fragment.name,
105
+ selections: fragment.selections,
106
+ type: fragment.type,
107
+ },
108
+ id: null,
109
+ loc: node.loc,
110
+ metadata: node.metadata || {},
111
+ name: fragment.name,
112
+ root: node,
113
+ text: printOperation(printContext, fragment.name),
114
+ };
115
+ results.push([request, RelayCodeGenerator.generate(schema, request)]);
116
+ } else {
117
+ results.push([node, RelayCodeGenerator.generate(schema, node)]);
118
+ }
119
+ }
120
+
121
+ // Add all the Fragments from the fragmentContext for the reader ASTs.
122
+ for (const node of fragmentContext.documents()) {
123
+ if (node.kind === 'Fragment') {
124
+ results.push([node, RelayCodeGenerator.generate(schema, node)]);
125
+ }
126
+ }
127
+ return results;
128
+ }
129
+
130
+ const OPERATION_ORDER = {
131
+ Root: 0,
132
+ SplitOperation: 1,
133
+ Fragment: 2,
134
+ };
135
+ function printOperation(printContext: CompilerContext, name: string): string {
136
+ const printableRoot = printContext.getRoot(name);
137
+ return filterContextForNode(printableRoot, printContext)
138
+ .documents()
139
+ .sort((a, b) => {
140
+ if (a.kind !== b.kind) {
141
+ return OPERATION_ORDER[a.kind] - OPERATION_ORDER[b.kind];
142
+ }
143
+ return a.name < b.name ? -1 : 1;
144
+ })
145
+ .map(doc => Printer.print(printContext.getSchema(), doc))
146
+ .join('\n');
147
+ }
148
+
149
+ /**
150
+ * Transforms the provided compiler context
151
+ *
152
+ * compileRelayArtifacts generates artifacts for Relay's runtime as a result of
153
+ * applying a series of transforms. Each kind of artifact is dependent on
154
+ * transforms being applied in the following order:
155
+ *
156
+ * - Fragment Readers: commonTransforms, fragmentTransforms
157
+ * - Operation Writers: commonTransforms, queryTransforms, codegenTransforms
158
+ * - GraphQL Text: commonTransforms, queryTransforms, printTransforms
159
+ *
160
+ * The order of the transforms applied for each artifact below is important.
161
+ * CompilerContext will memoize applying each transform, so while
162
+ * `commonTransforms` appears in each artifacts' application, it will not result
163
+ * in repeated work as long as the order remains consistent across each context.
164
+ */
165
+ function compileRelayArtifacts(
166
+ context: CompilerContext,
167
+ transforms: RelayCompilerTransforms,
168
+ reporter?: Reporter,
169
+ ): $ReadOnlyArray<[GeneratedDefinition, GeneratedNode]> {
170
+ return Profiler.run('GraphQLCompiler.compile', () => {
171
+ const fragmentContext = createFragmentContext(
172
+ context,
173
+ transforms,
174
+ reporter,
175
+ );
176
+ const printContext = createPrintContext(context, transforms, reporter);
177
+ const codeGenContext = createCodeGenContext(context, transforms, reporter);
178
+ return compile(context, fragmentContext, printContext, codeGenContext);
179
+ });
180
+ }
181
+
182
+ module.exports = compileRelayArtifacts;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ */
10
+
11
+ // flowlint ambiguous-object-type:error
12
+
13
+ 'use strict';
14
+
15
+ function createPrintRequireModuleDependency(
16
+ extension: string,
17
+ ): string => string {
18
+ return moduleName => `require('./${moduleName}.${extension}')`;
19
+ }
20
+
21
+ module.exports = createPrintRequireModuleDependency;