@ardatan/relay-compiler 12.0.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.
Files changed (256) hide show
  1. package/LICENSE +21 -0
  2. package/bin/RelayCompilerBin.js.flow +169 -0
  3. package/bin/RelayCompilerMain.js.flow +515 -0
  4. package/bin/__fixtures__/plugin-module.js.flow +17 -0
  5. package/bin/relay-compiler +19066 -0
  6. package/codegen/CodegenDirectory.js.flow +375 -0
  7. package/codegen/CodegenRunner.js.flow +432 -0
  8. package/codegen/CodegenTypes.js.flow +28 -0
  9. package/codegen/CodegenWatcher.js.flow +254 -0
  10. package/codegen/NormalizationCodeGenerator.js.flow +566 -0
  11. package/codegen/ReaderCodeGenerator.js.flow +512 -0
  12. package/codegen/RelayCodeGenerator.js.flow +85 -0
  13. package/codegen/RelayFileWriter.js.flow +367 -0
  14. package/codegen/SourceControl.js.flow +58 -0
  15. package/codegen/compileRelayArtifacts.js.flow +182 -0
  16. package/codegen/createPrintRequireModuleDependency.js.flow +19 -0
  17. package/codegen/sortObjectByKey.js.flow +25 -0
  18. package/codegen/writeRelayGeneratedFile.js.flow +239 -0
  19. package/core/ASTCache.js.flow +74 -0
  20. package/core/ASTConvert.js.flow +233 -0
  21. package/core/CompilerContext.js.flow +191 -0
  22. package/core/CompilerError.js.flow +255 -0
  23. package/core/DotGraphQLParser.js.flow +39 -0
  24. package/core/GraphQLCompilerProfiler.js.flow +341 -0
  25. package/core/GraphQLDerivedFromMetadata.js.flow +36 -0
  26. package/core/GraphQLWatchmanClient.js.flow +111 -0
  27. package/core/IR.js.flow +326 -0
  28. package/core/IRPrinter.js.flow +478 -0
  29. package/core/IRTransformer.js.flow +377 -0
  30. package/core/IRValidator.js.flow +260 -0
  31. package/core/IRVisitor.js.flow +150 -0
  32. package/core/JSModuleParser.js.flow +24 -0
  33. package/core/RelayCompilerScope.js.flow +199 -0
  34. package/core/RelayFindGraphQLTags.js.flow +119 -0
  35. package/core/RelayGraphQLEnumsGenerator.js.flow +55 -0
  36. package/core/RelayIRTransforms.js.flow +138 -0
  37. package/core/RelayParser.js.flow +1734 -0
  38. package/core/RelaySourceModuleParser.js.flow +135 -0
  39. package/core/Schema.js.flow +2037 -0
  40. package/core/SchemaUtils.js.flow +120 -0
  41. package/core/filterContextForNode.js.flow +50 -0
  42. package/core/getFieldDefinition.js.flow +156 -0
  43. package/core/getIdentifierForArgumentValue.js.flow +49 -0
  44. package/core/getIdentifierForSelection.js.flow +69 -0
  45. package/core/getLiteralArgumentValues.js.flow +32 -0
  46. package/core/getNormalizationOperationName.js.flow +19 -0
  47. package/core/inferRootArgumentDefinitions.js.flow +323 -0
  48. package/index.js +10 -0
  49. package/index.js.flow +200 -0
  50. package/language/RelayLanguagePluginInterface.js.flow +283 -0
  51. package/language/javascript/FindGraphQLTags.js.flow +137 -0
  52. package/language/javascript/RelayFlowBabelFactories.js.flow +176 -0
  53. package/language/javascript/RelayFlowGenerator.js.flow +1100 -0
  54. package/language/javascript/RelayFlowTypeTransformers.js.flow +184 -0
  55. package/language/javascript/RelayLanguagePluginJavaScript.js.flow +34 -0
  56. package/language/javascript/formatGeneratedModule.js.flow +65 -0
  57. package/lib/bin/RelayCompilerBin.js +143 -0
  58. package/lib/bin/RelayCompilerMain.js +486 -0
  59. package/lib/bin/__fixtures__/plugin-module.js +16 -0
  60. package/lib/codegen/CodegenDirectory.js +336 -0
  61. package/lib/codegen/CodegenRunner.js +433 -0
  62. package/lib/codegen/CodegenTypes.js +11 -0
  63. package/lib/codegen/CodegenWatcher.js +271 -0
  64. package/lib/codegen/NormalizationCodeGenerator.js +480 -0
  65. package/lib/codegen/ReaderCodeGenerator.js +472 -0
  66. package/lib/codegen/RelayCodeGenerator.js +68 -0
  67. package/lib/codegen/RelayFileWriter.js +270 -0
  68. package/lib/codegen/SourceControl.js +60 -0
  69. package/lib/codegen/compileRelayArtifacts.js +157 -0
  70. package/lib/codegen/createPrintRequireModuleDependency.js +19 -0
  71. package/lib/codegen/sortObjectByKey.js +41 -0
  72. package/lib/codegen/writeRelayGeneratedFile.js +208 -0
  73. package/lib/core/ASTCache.js +70 -0
  74. package/lib/core/ASTConvert.js +198 -0
  75. package/lib/core/CompilerContext.js +165 -0
  76. package/lib/core/CompilerError.js +251 -0
  77. package/lib/core/DotGraphQLParser.js +40 -0
  78. package/lib/core/GraphQLCompilerProfiler.js +299 -0
  79. package/lib/core/GraphQLDerivedFromMetadata.js +31 -0
  80. package/lib/core/GraphQLWatchmanClient.js +150 -0
  81. package/lib/core/IR.js +11 -0
  82. package/lib/core/IRPrinter.js +389 -0
  83. package/lib/core/IRTransformer.js +345 -0
  84. package/lib/core/IRValidator.js +226 -0
  85. package/lib/core/IRVisitor.js +45 -0
  86. package/lib/core/JSModuleParser.js +18 -0
  87. package/lib/core/RelayCompilerScope.js +149 -0
  88. package/lib/core/RelayFindGraphQLTags.js +79 -0
  89. package/lib/core/RelayGraphQLEnumsGenerator.js +50 -0
  90. package/lib/core/RelayIRTransforms.js +109 -0
  91. package/lib/core/RelayParser.js +1382 -0
  92. package/lib/core/RelaySourceModuleParser.js +104 -0
  93. package/lib/core/Schema.js +1877 -0
  94. package/lib/core/SchemaUtils.js +98 -0
  95. package/lib/core/filterContextForNode.js +49 -0
  96. package/lib/core/getFieldDefinition.js +145 -0
  97. package/lib/core/getIdentifierForArgumentValue.js +53 -0
  98. package/lib/core/getIdentifierForSelection.js +48 -0
  99. package/lib/core/getLiteralArgumentValues.js +26 -0
  100. package/lib/core/getNormalizationOperationName.js +17 -0
  101. package/lib/core/inferRootArgumentDefinitions.js +351 -0
  102. package/lib/index.js +178 -0
  103. package/lib/language/RelayLanguagePluginInterface.js +14 -0
  104. package/lib/language/javascript/FindGraphQLTags.js +126 -0
  105. package/lib/language/javascript/RelayFlowBabelFactories.js +160 -0
  106. package/lib/language/javascript/RelayFlowGenerator.js +857 -0
  107. package/lib/language/javascript/RelayFlowTypeTransformers.js +119 -0
  108. package/lib/language/javascript/RelayLanguagePluginJavaScript.js +30 -0
  109. package/lib/language/javascript/formatGeneratedModule.js +36 -0
  110. package/lib/reporters/ConsoleReporter.js +61 -0
  111. package/lib/reporters/MultiReporter.js +45 -0
  112. package/lib/reporters/Reporter.js +11 -0
  113. package/lib/runner/Artifacts.js +323 -0
  114. package/lib/runner/BufferedFilesystem.js +261 -0
  115. package/lib/runner/GraphQLASTNodeGroup.js +256 -0
  116. package/lib/runner/GraphQLASTUtils.js +23 -0
  117. package/lib/runner/GraphQLNodeMap.js +81 -0
  118. package/lib/runner/Sources.js +271 -0
  119. package/lib/runner/StrictMap.js +134 -0
  120. package/lib/runner/compileArtifacts.js +39 -0
  121. package/lib/runner/extractAST.js +77 -0
  122. package/lib/runner/getChangedNodeNames.js +82 -0
  123. package/lib/runner/getSchemaInstance.js +30 -0
  124. package/lib/runner/types.js +12 -0
  125. package/lib/transforms/ApplyFragmentArgumentTransform.js +393 -0
  126. package/lib/transforms/ClientExtensionsTransform.js +222 -0
  127. package/lib/transforms/ConnectionTransform.js +643 -0
  128. package/lib/transforms/DeclarativeConnectionMutationTransform.js +221 -0
  129. package/lib/transforms/DeferStreamTransform.js +247 -0
  130. package/lib/transforms/DisallowIdAsAlias.js +41 -0
  131. package/lib/transforms/DisallowTypenameOnRoot.js +53 -0
  132. package/lib/transforms/FieldHandleTransform.js +81 -0
  133. package/lib/transforms/FilterCompilerDirectivesTransform.js +29 -0
  134. package/lib/transforms/FilterDirectivesTransform.js +41 -0
  135. package/lib/transforms/FlattenTransform.js +308 -0
  136. package/lib/transforms/GenerateIDFieldTransform.js +137 -0
  137. package/lib/transforms/GenerateTypeNameTransform.js +155 -0
  138. package/lib/transforms/InlineDataFragmentTransform.js +104 -0
  139. package/lib/transforms/InlineFragmentsTransform.js +63 -0
  140. package/lib/transforms/MaskTransform.js +121 -0
  141. package/lib/transforms/MatchTransform.js +438 -0
  142. package/lib/transforms/ReactFlightComponentTransform.js +161 -0
  143. package/lib/transforms/RefetchableFragmentTransform.js +249 -0
  144. package/lib/transforms/RelayDirectiveTransform.js +85 -0
  145. package/lib/transforms/RequiredFieldTransform.js +373 -0
  146. package/lib/transforms/SkipClientExtensionsTransform.js +49 -0
  147. package/lib/transforms/SkipHandleFieldTransform.js +45 -0
  148. package/lib/transforms/SkipRedundantNodesTransform.js +255 -0
  149. package/lib/transforms/SkipSplitOperationTransform.js +32 -0
  150. package/lib/transforms/SkipUnreachableNodeTransform.js +158 -0
  151. package/lib/transforms/SkipUnusedVariablesTransform.js +74 -0
  152. package/lib/transforms/SplitModuleImportTransform.js +85 -0
  153. package/lib/transforms/TestOperationTransform.js +145 -0
  154. package/lib/transforms/TransformUtils.js +21 -0
  155. package/lib/transforms/ValidateGlobalVariablesTransform.js +91 -0
  156. package/lib/transforms/ValidateRequiredArgumentsTransform.js +118 -0
  157. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +111 -0
  158. package/lib/transforms/ValidateUnusedVariablesTransform.js +96 -0
  159. package/lib/transforms/query-generators/FetchableQueryGenerator.js +157 -0
  160. package/lib/transforms/query-generators/NodeQueryGenerator.js +166 -0
  161. package/lib/transforms/query-generators/QueryQueryGenerator.js +48 -0
  162. package/lib/transforms/query-generators/ViewerQueryGenerator.js +77 -0
  163. package/lib/transforms/query-generators/index.js +60 -0
  164. package/lib/transforms/query-generators/utils.js +92 -0
  165. package/lib/util/CodeMarker.js +80 -0
  166. package/lib/util/DefaultHandleKey.js +15 -0
  167. package/lib/util/RelayCompilerCache.js +98 -0
  168. package/lib/util/Rollout.js +40 -0
  169. package/lib/util/TimeReporter.js +83 -0
  170. package/lib/util/areEqualArgValues.js +135 -0
  171. package/lib/util/argumentContainsVariables.js +37 -0
  172. package/lib/util/dedupeJSONStringify.js +160 -0
  173. package/lib/util/generateAbstractTypeRefinementKey.js +24 -0
  174. package/lib/util/getDefinitionNodeHash.js +22 -0
  175. package/lib/util/getModuleName.js +32 -0
  176. package/lib/util/joinArgumentDefinitions.js +66 -0
  177. package/lib/util/md5.js +17 -0
  178. package/lib/util/murmurHash.js +86 -0
  179. package/lib/util/nullthrowsOSS.js +23 -0
  180. package/lib/util/orList.js +36 -0
  181. package/lib/util/partitionArray.js +35 -0
  182. package/package.json +42 -0
  183. package/relay-compiler.js +17 -0
  184. package/relay-compiler.min.js +22 -0
  185. package/reporters/ConsoleReporter.js.flow +81 -0
  186. package/reporters/MultiReporter.js.flow +43 -0
  187. package/reporters/Reporter.js.flow +19 -0
  188. package/runner/Artifacts.js.flow +219 -0
  189. package/runner/BufferedFilesystem.js.flow +194 -0
  190. package/runner/GraphQLASTNodeGroup.js.flow +176 -0
  191. package/runner/GraphQLASTUtils.js.flow +26 -0
  192. package/runner/GraphQLNodeMap.js.flow +55 -0
  193. package/runner/Sources.js.flow +228 -0
  194. package/runner/StrictMap.js.flow +96 -0
  195. package/runner/compileArtifacts.js.flow +76 -0
  196. package/runner/extractAST.js.flow +100 -0
  197. package/runner/getChangedNodeNames.js.flow +48 -0
  198. package/runner/getSchemaInstance.js.flow +36 -0
  199. package/runner/types.js.flow +37 -0
  200. package/transforms/ApplyFragmentArgumentTransform.js.flow +526 -0
  201. package/transforms/ClientExtensionsTransform.js.flow +226 -0
  202. package/transforms/ConnectionTransform.js.flow +859 -0
  203. package/transforms/DeclarativeConnectionMutationTransform.js.flow +250 -0
  204. package/transforms/DeferStreamTransform.js.flow +266 -0
  205. package/transforms/DisallowIdAsAlias.js.flow +48 -0
  206. package/transforms/DisallowTypenameOnRoot.js.flow +45 -0
  207. package/transforms/FieldHandleTransform.js.flow +81 -0
  208. package/transforms/FilterCompilerDirectivesTransform.js.flow +33 -0
  209. package/transforms/FilterDirectivesTransform.js.flow +45 -0
  210. package/transforms/FlattenTransform.js.flow +462 -0
  211. package/transforms/GenerateIDFieldTransform.js.flow +154 -0
  212. package/transforms/GenerateTypeNameTransform.js.flow +167 -0
  213. package/transforms/InlineDataFragmentTransform.js.flow +129 -0
  214. package/transforms/InlineFragmentsTransform.js.flow +73 -0
  215. package/transforms/MaskTransform.js.flow +130 -0
  216. package/transforms/MatchTransform.js.flow +593 -0
  217. package/transforms/ReactFlightComponentTransform.js.flow +198 -0
  218. package/transforms/RefetchableFragmentTransform.js.flow +272 -0
  219. package/transforms/RelayDirectiveTransform.js.flow +99 -0
  220. package/transforms/RequiredFieldTransform.js.flow +419 -0
  221. package/transforms/SkipClientExtensionsTransform.js.flow +57 -0
  222. package/transforms/SkipHandleFieldTransform.js.flow +45 -0
  223. package/transforms/SkipRedundantNodesTransform.js.flow +259 -0
  224. package/transforms/SkipSplitOperationTransform.js.flow +37 -0
  225. package/transforms/SkipUnreachableNodeTransform.js.flow +149 -0
  226. package/transforms/SkipUnusedVariablesTransform.js.flow +59 -0
  227. package/transforms/SplitModuleImportTransform.js.flow +101 -0
  228. package/transforms/TestOperationTransform.js.flow +143 -0
  229. package/transforms/TransformUtils.js.flow +26 -0
  230. package/transforms/ValidateGlobalVariablesTransform.js.flow +81 -0
  231. package/transforms/ValidateRequiredArgumentsTransform.js.flow +131 -0
  232. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +115 -0
  233. package/transforms/ValidateUnusedVariablesTransform.js.flow +89 -0
  234. package/transforms/query-generators/FetchableQueryGenerator.js.flow +189 -0
  235. package/transforms/query-generators/NodeQueryGenerator.js.flow +219 -0
  236. package/transforms/query-generators/QueryQueryGenerator.js.flow +57 -0
  237. package/transforms/query-generators/ViewerQueryGenerator.js.flow +97 -0
  238. package/transforms/query-generators/index.js.flow +90 -0
  239. package/transforms/query-generators/utils.js.flow +76 -0
  240. package/util/CodeMarker.js.flow +79 -0
  241. package/util/DefaultHandleKey.js.flow +17 -0
  242. package/util/RelayCompilerCache.js.flow +88 -0
  243. package/util/Rollout.js.flow +39 -0
  244. package/util/TimeReporter.js.flow +79 -0
  245. package/util/areEqualArgValues.js.flow +126 -0
  246. package/util/argumentContainsVariables.js.flow +38 -0
  247. package/util/dedupeJSONStringify.js.flow +152 -0
  248. package/util/generateAbstractTypeRefinementKey.js.flow +29 -0
  249. package/util/getDefinitionNodeHash.js.flow +25 -0
  250. package/util/getModuleName.js.flow +39 -0
  251. package/util/joinArgumentDefinitions.js.flow +105 -0
  252. package/util/md5.js.flow +22 -0
  253. package/util/murmurHash.js.flow +94 -0
  254. package/util/nullthrowsOSS.js.flow +25 -0
  255. package/util/orList.js.flow +37 -0
  256. package/util/partitionArray.js.flow +37 -0
@@ -0,0 +1,239 @@
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 CodeMarker = require('../util/CodeMarker');
16
+
17
+ const createPrintRequireModuleDependency = require('./createPrintRequireModuleDependency');
18
+ const dedupeJSONStringify = require('../util/dedupeJSONStringify');
19
+ const invariant = require('invariant');
20
+ const md5 = require('../util/md5');
21
+
22
+ const {RelayConcreteNode} = require('relay-runtime');
23
+
24
+ import type {GeneratedDefinition} from '../core/IR';
25
+ import type {Schema} from '../core/Schema';
26
+ import type {
27
+ FormatModule,
28
+ PluginInterface,
29
+ } from '../language/RelayLanguagePluginInterface';
30
+ import type CodegenDirectory from './CodegenDirectory';
31
+ import type {GeneratedNode, RequestParameters} from 'relay-runtime';
32
+
33
+ function getConcreteType(node: GeneratedNode): string {
34
+ switch (node.kind) {
35
+ case RelayConcreteNode.FRAGMENT:
36
+ return 'ReaderFragment';
37
+ case RelayConcreteNode.REQUEST:
38
+ return 'ConcreteRequest';
39
+ case RelayConcreteNode.SPLIT_OPERATION:
40
+ return 'NormalizationSplitOperation';
41
+ case RelayConcreteNode.INLINE_DATA_FRAGMENT:
42
+ return 'ReaderInlineDataFragment';
43
+ default:
44
+ (node: empty);
45
+ invariant(false, 'Unexpected GeneratedNode kind: `%s`.', node.kind);
46
+ }
47
+ }
48
+
49
+ function writeRelayGeneratedFile(
50
+ schema: Schema,
51
+ codegenDir: CodegenDirectory,
52
+ definition: GeneratedDefinition,
53
+ _generatedNode: GeneratedNode,
54
+ formatModule: FormatModule,
55
+ typeText: string,
56
+ _persistQuery: ?(text: string) => Promise<string>,
57
+ sourceHash: string,
58
+ extension: string,
59
+ printModuleDependency: (
60
+ moduleName: string,
61
+ ) => string = createPrintRequireModuleDependency(),
62
+ shouldRepersist: boolean,
63
+ writeQueryParameters: (
64
+ dir: CodegenDirectory,
65
+ filename: string,
66
+ moduleName: string,
67
+ params: RequestParameters,
68
+ ) => void,
69
+ languagePlugin: ?PluginInterface,
70
+ ): Promise<?GeneratedNode> {
71
+ let generatedNode: GeneratedNode = _generatedNode;
72
+ // Copy to const so Flow can refine.
73
+ const persistQuery = _persistQuery;
74
+ const operationName =
75
+ generatedNode.kind === 'Request'
76
+ ? generatedNode.params.name
77
+ : generatedNode.name;
78
+ const moduleName = languagePlugin?.getModuleName
79
+ ? languagePlugin.getModuleName(operationName)
80
+ : operationName + '.graphql';
81
+
82
+ const filename = moduleName + '.' + extension;
83
+ const queryParametersFilename =
84
+ generatedNode.kind === 'Request'
85
+ ? `${generatedNode.params.name}$Parameters.${extension}`
86
+ : null;
87
+
88
+ const typeName = getConcreteType(generatedNode);
89
+
90
+ let docText;
91
+ if (generatedNode.kind === RelayConcreteNode.REQUEST) {
92
+ docText =
93
+ generatedNode.params.text != null ? generatedNode.params.text : null;
94
+ }
95
+
96
+ // Use `Promise.resolve` to work around a Babel 7.8/7.9 issue.
97
+ return Promise.resolve().then(async () => {
98
+ let hash = null;
99
+ if (generatedNode.kind === RelayConcreteNode.REQUEST) {
100
+ invariant(
101
+ docText != null,
102
+ 'writeRelayGeneratedFile: Expected `text` for operations to be set.',
103
+ );
104
+
105
+ const {
106
+ isRefetchableQuery: _ignored,
107
+ derivedFrom: _ignored2,
108
+ ...nextMetadata
109
+ } = generatedNode.params.metadata;
110
+
111
+ let nextRequestParams;
112
+ if (persistQuery != null) {
113
+ hash = md5(docText);
114
+
115
+ let id = null;
116
+ if (!shouldRepersist) {
117
+ // Unless we `shouldRepersist` the query, check if the @relayHash matches
118
+ // the operation text of the current text and re-use the persisted
119
+ // operation id.
120
+ const oldContent = codegenDir.read(filename);
121
+ const oldHash = extractHash(oldContent);
122
+ const oldRequestID = extractRelayRequestID(oldContent);
123
+ if (hash === oldHash && oldRequestID != null) {
124
+ id = oldRequestID;
125
+ }
126
+ }
127
+ if (id == null) {
128
+ // $FlowFixMe[incompatible-call]
129
+ id = await persistQuery(docText);
130
+ }
131
+ nextRequestParams = {
132
+ id,
133
+ metadata: nextMetadata,
134
+ // $FlowFixMe[prop-missing]
135
+ // $FlowFixMe[incompatible-use]
136
+ name: generatedNode.params.name,
137
+ // $FlowFixMe[prop-missing]
138
+ // $FlowFixMe[incompatible-use]
139
+ operationKind: generatedNode.params.operationKind,
140
+ text: null,
141
+ };
142
+ } else {
143
+ nextRequestParams = {
144
+ cacheID: md5(docText),
145
+ id: null,
146
+ metadata: nextMetadata,
147
+ // $FlowFixMe[prop-missing]
148
+ // $FlowFixMe[incompatible-use]
149
+ name: generatedNode.params.name,
150
+ // $FlowFixMe[prop-missing]
151
+ // $FlowFixMe[incompatible-use]
152
+ operationKind: generatedNode.params.operationKind,
153
+ text: docText,
154
+ };
155
+ }
156
+ // $FlowFixMe[incompatible-type]
157
+ generatedNode = {
158
+ ...generatedNode,
159
+ // $FlowFixMe[incompatible-type]
160
+ params: nextRequestParams,
161
+ };
162
+ }
163
+
164
+ // Strip metadata only used within the compiler
165
+ if (
166
+ generatedNode.kind === RelayConcreteNode.SPLIT_OPERATION &&
167
+ generatedNode.metadata?.derivedFrom != null
168
+ ) {
169
+ const {derivedFrom: _ignored, ...metadata} = generatedNode.metadata;
170
+ // $FlowFixMe[incompatible-type]
171
+ generatedNode = {
172
+ ...generatedNode,
173
+ metadata,
174
+ };
175
+ }
176
+
177
+ const moduleText = formatModule({
178
+ moduleName,
179
+ documentType: typeName,
180
+ definition,
181
+ kind: generatedNode.kind,
182
+ docText,
183
+ typeText,
184
+ hash: hash != null ? `@relayHash ${hash}` : null,
185
+ concreteText: CodeMarker.postProcess(
186
+ dedupeJSONStringify(generatedNode),
187
+ printModuleDependency,
188
+ ),
189
+ sourceHash,
190
+ // $FlowFixMe[incompatible-call]
191
+ node: generatedNode,
192
+ schema,
193
+ });
194
+ codegenDir.writeFile(filename, moduleText, shouldRepersist);
195
+ if (
196
+ writeQueryParameters &&
197
+ queryParametersFilename != null &&
198
+ generatedNode.kind === RelayConcreteNode.REQUEST &&
199
+ // $FlowFixMe[incompatible-type]
200
+ generatedNode.params.operationKind === 'query'
201
+ ) {
202
+ writeQueryParameters(
203
+ codegenDir,
204
+ queryParametersFilename,
205
+ moduleName,
206
+ // $FlowFixMe[incompatible-call]
207
+ generatedNode.params,
208
+ );
209
+ }
210
+ // $FlowFixMe[incompatible-call]
211
+ return generatedNode;
212
+ });
213
+ }
214
+
215
+ function extractHash(text: ?string): ?string {
216
+ if (text == null || text.length === 0) {
217
+ return null;
218
+ }
219
+ if (/<<<<<|>>>>>/.test(text)) {
220
+ // looks like a merge conflict
221
+ return null;
222
+ }
223
+ const match = text.match(/@relayHash (\w{32})\b/m);
224
+ return match && match[1];
225
+ }
226
+
227
+ function extractRelayRequestID(text: ?string): ?string {
228
+ if (text == null || text.length === 0) {
229
+ return null;
230
+ }
231
+ if (/<<<<<|>>>>>/.test(text)) {
232
+ // looks like a merge conflict
233
+ return null;
234
+ }
235
+ const match = text.match(/@relayRequestID (.+)/);
236
+ return match ? match[1] : null;
237
+ }
238
+
239
+ module.exports = writeRelayGeneratedFile;
@@ -0,0 +1,74 @@
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 Profiler = require('./GraphQLCompilerProfiler');
16
+
17
+ // $FlowFixMe[untyped-import] : Immutable is not typed
18
+ const {Map: ImmutableMap} = require('immutable');
19
+
20
+ import type {File} from '../codegen/CodegenTypes';
21
+ import type {DocumentNode} from 'graphql';
22
+
23
+ type ParseFn = (baseDir: string, file: File) => ?DocumentNode;
24
+
25
+ class ASTCache {
26
+ _documents: Map<string, DocumentNode>;
27
+
28
+ _baseDir: string;
29
+ _parse: ParseFn;
30
+
31
+ constructor(config: {baseDir: string, parse: ParseFn, ...}) {
32
+ this._documents = new Map();
33
+ this._baseDir = config.baseDir;
34
+ this._parse = Profiler.instrument(config.parse, 'ASTCache.parseFn');
35
+ }
36
+
37
+ // Short-term: we don't do subscriptions/delta updates, instead always use all definitions
38
+ // $FlowFixMe[value-as-type]
39
+ documents(): ImmutableMap<string, DocumentNode> {
40
+ return ImmutableMap(this._documents);
41
+ }
42
+
43
+ // parse should return the set of changes
44
+ parseFiles(files: Set<File>): ImmutableMap<string, DocumentNode> {
45
+ let documents = ImmutableMap();
46
+
47
+ files.forEach(file => {
48
+ if (!file.exists) {
49
+ this._documents.delete(file.relPath);
50
+ return;
51
+ }
52
+
53
+ const doc = (() => {
54
+ try {
55
+ return this._parse(this._baseDir, file);
56
+ } catch (error) {
57
+ throw new Error(`Parse error: ${error} in "${file.relPath}"`);
58
+ }
59
+ })();
60
+
61
+ if (!doc) {
62
+ this._documents.delete(file.relPath);
63
+ return;
64
+ }
65
+
66
+ documents = documents.set(file.relPath, doc);
67
+ this._documents.set(file.relPath, doc);
68
+ });
69
+
70
+ return documents;
71
+ }
72
+ }
73
+
74
+ module.exports = ASTCache;
@@ -0,0 +1,233 @@
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 Profiler = require('./GraphQLCompilerProfiler');
16
+
17
+ const {
18
+ isExecutableDefinitionAST,
19
+ isSchemaDefinitionAST,
20
+ } = require('./SchemaUtils');
21
+ const {extendSchema, parse, print, visit} = require('graphql');
22
+
23
+ import type {Fragment, Root} from './IR';
24
+ import type {Schema} from './Schema';
25
+ import type {
26
+ DefinitionNode,
27
+ DocumentNode,
28
+ FragmentDefinitionNode,
29
+ FragmentSpreadNode,
30
+ GraphQLSchema,
31
+ OperationDefinitionNode,
32
+ TypeSystemDefinitionNode,
33
+ TypeSystemExtensionNode,
34
+ } from 'graphql';
35
+
36
+ type ASTDefinitionNode = FragmentDefinitionNode | OperationDefinitionNode;
37
+ type TransformFn = (
38
+ schema: Schema,
39
+ definitions: $ReadOnlyArray<ASTDefinitionNode>,
40
+ ) => $ReadOnlyArray<Root | Fragment>;
41
+
42
+ function convertASTDocuments(
43
+ schema: Schema,
44
+ documents: $ReadOnlyArray<DocumentNode>,
45
+ transform: TransformFn,
46
+ ): $ReadOnlyArray<Fragment | Root> {
47
+ return Profiler.run('ASTConvert.convertASTDocuments', () => {
48
+ const definitions = definitionsFromDocuments(documents);
49
+
50
+ const astDefinitions: Array<ASTDefinitionNode> = [];
51
+ documents.forEach(doc => {
52
+ doc.definitions.forEach(definition => {
53
+ if (isExecutableDefinitionAST(definition)) {
54
+ astDefinitions.push(definition);
55
+ }
56
+ });
57
+ });
58
+
59
+ return convertASTDefinitions(schema, definitions, transform);
60
+ });
61
+ }
62
+
63
+ function convertASTDocumentsWithBase(
64
+ schema: Schema,
65
+ baseDocuments: $ReadOnlyArray<DocumentNode>,
66
+ documents: $ReadOnlyArray<DocumentNode>,
67
+ transform: TransformFn,
68
+ ): $ReadOnlyArray<Fragment | Root> {
69
+ return Profiler.run('ASTConvert.convertASTDocumentsWithBase', () => {
70
+ const baseDefinitions = definitionsFromDocuments(baseDocuments);
71
+ const definitions = definitionsFromDocuments(documents);
72
+
73
+ const requiredDefinitions = new Map();
74
+ const baseMap: Map<string, ASTDefinitionNode> = new Map();
75
+ baseDefinitions.forEach(definition => {
76
+ if (isExecutableDefinitionAST(definition)) {
77
+ const definitionName = definition.name && definition.name.value;
78
+ // If there's no name, no reason to put in the map
79
+ if (definitionName != null) {
80
+ if (baseMap.has(definitionName)) {
81
+ throw new Error(`Duplicate definition of '${definitionName}'.`);
82
+ }
83
+ baseMap.set(definitionName, definition);
84
+ }
85
+ }
86
+ });
87
+
88
+ const definitionsToVisit: Array<ASTDefinitionNode> = [];
89
+ definitions.forEach(definition => {
90
+ if (isExecutableDefinitionAST(definition)) {
91
+ definitionsToVisit.push(definition);
92
+ }
93
+ });
94
+ while (definitionsToVisit.length > 0) {
95
+ const definition = definitionsToVisit.pop();
96
+ const name = definition.name && definition.name.value;
97
+ if (name == null) {
98
+ continue;
99
+ }
100
+ if (requiredDefinitions.has(name)) {
101
+ if (requiredDefinitions.get(name) !== definition) {
102
+ throw new Error(`Duplicate definition of '${name}'.`);
103
+ }
104
+ continue;
105
+ }
106
+ requiredDefinitions.set(name, definition);
107
+ visit(definition, {
108
+ FragmentSpread(spread: FragmentSpreadNode) {
109
+ const baseDefinition = baseMap.get(spread.name.value);
110
+ if (baseDefinition) {
111
+ // We only need to add those definitions not already included
112
+ // in definitions
113
+ definitionsToVisit.push(baseDefinition);
114
+ }
115
+ },
116
+ });
117
+ }
118
+
119
+ const definitionsToConvert = [];
120
+ requiredDefinitions.forEach(definition =>
121
+ definitionsToConvert.push(definition),
122
+ );
123
+ return convertASTDefinitions(schema, definitionsToConvert, transform);
124
+ });
125
+ }
126
+
127
+ function convertASTDefinitions(
128
+ schema: Schema,
129
+ definitions: $ReadOnlyArray<DefinitionNode>,
130
+ transform: TransformFn,
131
+ ): $ReadOnlyArray<Fragment | Root> {
132
+ const operationDefinitions: Array<ASTDefinitionNode> = [];
133
+ definitions.forEach(definition => {
134
+ if (isExecutableDefinitionAST(definition)) {
135
+ operationDefinitions.push(definition);
136
+ }
137
+ });
138
+ return transform(schema, operationDefinitions);
139
+ }
140
+
141
+ function definitionsFromDocuments(
142
+ documents: $ReadOnlyArray<DocumentNode>,
143
+ ): $ReadOnlyArray<DefinitionNode> {
144
+ const definitions = [];
145
+ documents.forEach(doc => {
146
+ doc.definitions.forEach(definition => definitions.push(definition));
147
+ });
148
+ return definitions;
149
+ }
150
+
151
+ /**
152
+ * Extends a GraphQLSchema with a list of schema extensions in string form.
153
+ */
154
+ function transformASTSchema(
155
+ schema: GraphQLSchema,
156
+ schemaExtensions: $ReadOnlyArray<string>,
157
+ ): GraphQLSchema {
158
+ return Profiler.run('ASTConvert.transformASTSchema', () => {
159
+ if (schemaExtensions.length === 0) {
160
+ return schema;
161
+ }
162
+ const extension = schemaExtensions.join('\n');
163
+ return cachedExtend(schema, extension, () =>
164
+ extendSchema(schema, parse(extension)),
165
+ );
166
+ });
167
+ }
168
+
169
+ /**
170
+ * Extends a GraphQLSchema with a list of schema extensions in AST form.
171
+ */
172
+ function extendASTSchema(
173
+ baseSchema: GraphQLSchema,
174
+ documents: $ReadOnlyArray<DocumentNode>,
175
+ ): GraphQLSchema {
176
+ return Profiler.run('ASTConvert.extendASTSchema', () => {
177
+ const schemaExtensions: Array<
178
+ TypeSystemDefinitionNode | TypeSystemExtensionNode,
179
+ > = [];
180
+ documents.forEach(doc => {
181
+ doc.definitions.forEach(definition => {
182
+ if (isSchemaDefinitionAST(definition)) {
183
+ schemaExtensions.push(definition);
184
+ }
185
+ });
186
+ });
187
+ if (schemaExtensions.length === 0) {
188
+ return baseSchema;
189
+ }
190
+ const key = schemaExtensions.map(print).join('\n');
191
+ return cachedExtend(baseSchema, key, () =>
192
+ extendSchema(
193
+ baseSchema,
194
+ {
195
+ kind: 'Document',
196
+ definitions: schemaExtensions,
197
+ },
198
+ // TODO T24511737 figure out if this is dangerous
199
+ {assumeValid: true},
200
+ ),
201
+ );
202
+ });
203
+ }
204
+
205
+ const extendedSchemas: Map<
206
+ GraphQLSchema,
207
+ {[key: string]: GraphQLSchema, ...},
208
+ > = new Map();
209
+
210
+ function cachedExtend(
211
+ schema: GraphQLSchema,
212
+ key: string,
213
+ compute: () => GraphQLSchema,
214
+ ): GraphQLSchema {
215
+ let cache = extendedSchemas.get(schema);
216
+ if (!cache) {
217
+ cache = {};
218
+ extendedSchemas.set(schema, cache);
219
+ }
220
+ let extendedSchema = cache[key];
221
+ if (!extendedSchema) {
222
+ extendedSchema = compute();
223
+ cache[key] = extendedSchema;
224
+ }
225
+ return extendedSchema;
226
+ }
227
+
228
+ module.exports = {
229
+ convertASTDocuments,
230
+ convertASTDocumentsWithBase,
231
+ extendASTSchema,
232
+ transformASTSchema,
233
+ };