relay-compiler 0.0.0-main-8ff54d69 → 0.0.0-main-4467ae84

Sign up to get free protection for your applications and to get access to all the features.
Files changed (263) hide show
  1. package/cli.js +23 -0
  2. package/index.js +19 -3
  3. package/linux-x64/relay +0 -0
  4. package/macos-x64/relay +0 -0
  5. package/package.json +2 -24
  6. package/win-x64/relay.exe +0 -0
  7. package/bin/RelayCompilerBin.js.flow +0 -168
  8. package/bin/RelayCompilerMain.js.flow +0 -515
  9. package/bin/__fixtures__/plugin-module.js.flow +0 -17
  10. package/bin/relay-compiler +0 -19068
  11. package/codegen/CodegenDirectory.js.flow +0 -372
  12. package/codegen/CodegenRunner.js.flow +0 -424
  13. package/codegen/CodegenTypes.js.flow +0 -28
  14. package/codegen/CodegenWatcher.js.flow +0 -250
  15. package/codegen/NormalizationCodeGenerator.js.flow +0 -566
  16. package/codegen/ReaderCodeGenerator.js.flow +0 -510
  17. package/codegen/RelayCodeGenerator.js.flow +0 -85
  18. package/codegen/RelayFileWriter.js.flow +0 -365
  19. package/codegen/SourceControl.js.flow +0 -58
  20. package/codegen/compileRelayArtifacts.js.flow +0 -181
  21. package/codegen/createPrintRequireModuleDependency.js.flow +0 -19
  22. package/codegen/sortObjectByKey.js.flow +0 -25
  23. package/codegen/writeRelayGeneratedFile.js.flow +0 -235
  24. package/core/ASTCache.js.flow +0 -73
  25. package/core/ASTConvert.js.flow +0 -230
  26. package/core/CompilerContext.js.flow +0 -189
  27. package/core/CompilerError.js.flow +0 -255
  28. package/core/DotGraphQLParser.js.flow +0 -37
  29. package/core/GraphQLCompilerProfiler.js.flow +0 -341
  30. package/core/GraphQLDerivedFromMetadata.js.flow +0 -36
  31. package/core/GraphQLWatchmanClient.js.flow +0 -109
  32. package/core/IR.js.flow +0 -326
  33. package/core/IRPrinter.js.flow +0 -472
  34. package/core/IRTransformer.js.flow +0 -376
  35. package/core/IRValidator.js.flow +0 -259
  36. package/core/IRVisitor.js.flow +0 -150
  37. package/core/JSModuleParser.js.flow +0 -24
  38. package/core/RelayCompilerScope.js.flow +0 -199
  39. package/core/RelayFindGraphQLTags.js.flow +0 -118
  40. package/core/RelayGraphQLEnumsGenerator.js.flow +0 -55
  41. package/core/RelayIRTransforms.js.flow +0 -138
  42. package/core/RelayParser.js.flow +0 -1741
  43. package/core/RelaySourceModuleParser.js.flow +0 -133
  44. package/core/Schema.js.flow +0 -2035
  45. package/core/SchemaUtils.js.flow +0 -120
  46. package/core/filterContextForNode.js.flow +0 -49
  47. package/core/getFieldDefinition.js.flow +0 -156
  48. package/core/getIdentifierForArgumentValue.js.flow +0 -49
  49. package/core/getIdentifierForSelection.js.flow +0 -68
  50. package/core/getLiteralArgumentValues.js.flow +0 -32
  51. package/core/getNormalizationOperationName.js.flow +0 -19
  52. package/core/inferRootArgumentDefinitions.js.flow +0 -322
  53. package/index.js.flow +0 -198
  54. package/language/RelayLanguagePluginInterface.js.flow +0 -283
  55. package/language/javascript/FindGraphQLTags.js.flow +0 -136
  56. package/language/javascript/RelayFlowBabelFactories.js.flow +0 -176
  57. package/language/javascript/RelayFlowGenerator.js.flow +0 -1096
  58. package/language/javascript/RelayFlowTypeTransformers.js.flow +0 -181
  59. package/language/javascript/RelayLanguagePluginJavaScript.js.flow +0 -33
  60. package/language/javascript/formatGeneratedModule.js.flow +0 -65
  61. package/lib/bin/RelayCompilerBin.js +0 -143
  62. package/lib/bin/RelayCompilerMain.js +0 -488
  63. package/lib/bin/__fixtures__/plugin-module.js +0 -16
  64. package/lib/codegen/CodegenDirectory.js +0 -335
  65. package/lib/codegen/CodegenRunner.js +0 -433
  66. package/lib/codegen/CodegenTypes.js +0 -11
  67. package/lib/codegen/CodegenWatcher.js +0 -271
  68. package/lib/codegen/NormalizationCodeGenerator.js +0 -487
  69. package/lib/codegen/ReaderCodeGenerator.js +0 -473
  70. package/lib/codegen/RelayCodeGenerator.js +0 -75
  71. package/lib/codegen/RelayFileWriter.js +0 -270
  72. package/lib/codegen/SourceControl.js +0 -60
  73. package/lib/codegen/compileRelayArtifacts.js +0 -157
  74. package/lib/codegen/createPrintRequireModuleDependency.js +0 -19
  75. package/lib/codegen/sortObjectByKey.js +0 -41
  76. package/lib/codegen/writeRelayGeneratedFile.js +0 -206
  77. package/lib/core/ASTCache.js +0 -70
  78. package/lib/core/ASTConvert.js +0 -198
  79. package/lib/core/CompilerContext.js +0 -165
  80. package/lib/core/CompilerError.js +0 -252
  81. package/lib/core/DotGraphQLParser.js +0 -40
  82. package/lib/core/GraphQLCompilerProfiler.js +0 -299
  83. package/lib/core/GraphQLDerivedFromMetadata.js +0 -31
  84. package/lib/core/GraphQLWatchmanClient.js +0 -150
  85. package/lib/core/IR.js +0 -11
  86. package/lib/core/IRPrinter.js +0 -388
  87. package/lib/core/IRTransformer.js +0 -345
  88. package/lib/core/IRValidator.js +0 -226
  89. package/lib/core/IRVisitor.js +0 -45
  90. package/lib/core/JSModuleParser.js +0 -18
  91. package/lib/core/RelayCompilerScope.js +0 -183
  92. package/lib/core/RelayFindGraphQLTags.js +0 -79
  93. package/lib/core/RelayGraphQLEnumsGenerator.js +0 -50
  94. package/lib/core/RelayIRTransforms.js +0 -109
  95. package/lib/core/RelayParser.js +0 -1381
  96. package/lib/core/RelaySourceModuleParser.js +0 -104
  97. package/lib/core/Schema.js +0 -1877
  98. package/lib/core/SchemaUtils.js +0 -98
  99. package/lib/core/filterContextForNode.js +0 -50
  100. package/lib/core/getFieldDefinition.js +0 -145
  101. package/lib/core/getIdentifierForArgumentValue.js +0 -54
  102. package/lib/core/getIdentifierForSelection.js +0 -49
  103. package/lib/core/getLiteralArgumentValues.js +0 -26
  104. package/lib/core/getNormalizationOperationName.js +0 -17
  105. package/lib/core/inferRootArgumentDefinitions.js +0 -351
  106. package/lib/index.js +0 -178
  107. package/lib/language/RelayLanguagePluginInterface.js +0 -26
  108. package/lib/language/javascript/FindGraphQLTags.js +0 -126
  109. package/lib/language/javascript/RelayFlowBabelFactories.js +0 -160
  110. package/lib/language/javascript/RelayFlowGenerator.js +0 -856
  111. package/lib/language/javascript/RelayFlowTypeTransformers.js +0 -119
  112. package/lib/language/javascript/RelayLanguagePluginJavaScript.js +0 -30
  113. package/lib/language/javascript/formatGeneratedModule.js +0 -36
  114. package/lib/reporters/ConsoleReporter.js +0 -61
  115. package/lib/reporters/MultiReporter.js +0 -45
  116. package/lib/reporters/Reporter.js +0 -11
  117. package/lib/runner/Artifacts.js +0 -323
  118. package/lib/runner/BufferedFilesystem.js +0 -262
  119. package/lib/runner/GraphQLASTNodeGroup.js +0 -256
  120. package/lib/runner/GraphQLASTUtils.js +0 -23
  121. package/lib/runner/GraphQLNodeMap.js +0 -81
  122. package/lib/runner/Sources.js +0 -271
  123. package/lib/runner/StrictMap.js +0 -134
  124. package/lib/runner/compileArtifacts.js +0 -39
  125. package/lib/runner/extractAST.js +0 -77
  126. package/lib/runner/getChangedNodeNames.js +0 -82
  127. package/lib/runner/getSchemaInstance.js +0 -30
  128. package/lib/runner/types.js +0 -12
  129. package/lib/test-utils/TestSchema.js +0 -27
  130. package/lib/test-utils/parseGraphQLText.js +0 -30
  131. package/lib/transforms/ApplyFragmentArgumentTransform.js +0 -393
  132. package/lib/transforms/ClientExtensionsTransform.js +0 -221
  133. package/lib/transforms/ConnectionTransform.js +0 -639
  134. package/lib/transforms/DeclarativeConnectionMutationTransform.js +0 -218
  135. package/lib/transforms/DeferStreamTransform.js +0 -246
  136. package/lib/transforms/DisallowIdAsAlias.js +0 -40
  137. package/lib/transforms/DisallowTypenameOnRoot.js +0 -53
  138. package/lib/transforms/FieldHandleTransform.js +0 -79
  139. package/lib/transforms/FilterCompilerDirectivesTransform.js +0 -29
  140. package/lib/transforms/FilterDirectivesTransform.js +0 -42
  141. package/lib/transforms/FlattenTransform.js +0 -306
  142. package/lib/transforms/GenerateIDFieldTransform.js +0 -135
  143. package/lib/transforms/GenerateTypeNameTransform.js +0 -149
  144. package/lib/transforms/InlineDataFragmentTransform.js +0 -100
  145. package/lib/transforms/InlineFragmentsTransform.js +0 -61
  146. package/lib/transforms/MaskTransform.js +0 -117
  147. package/lib/transforms/MatchTransform.js +0 -434
  148. package/lib/transforms/ReactFlightComponentTransform.js +0 -158
  149. package/lib/transforms/RefetchableFragmentTransform.js +0 -249
  150. package/lib/transforms/RelayDirectiveTransform.js +0 -83
  151. package/lib/transforms/RequiredFieldTransform.js +0 -369
  152. package/lib/transforms/SkipClientExtensionsTransform.js +0 -46
  153. package/lib/transforms/SkipHandleFieldTransform.js +0 -45
  154. package/lib/transforms/SkipRedundantNodesTransform.js +0 -261
  155. package/lib/transforms/SkipSplitOperationTransform.js +0 -32
  156. package/lib/transforms/SkipUnreachableNodeTransform.js +0 -158
  157. package/lib/transforms/SkipUnusedVariablesTransform.js +0 -75
  158. package/lib/transforms/SplitModuleImportTransform.js +0 -82
  159. package/lib/transforms/TestOperationTransform.js +0 -144
  160. package/lib/transforms/TransformUtils.js +0 -21
  161. package/lib/transforms/ValidateGlobalVariablesTransform.js +0 -92
  162. package/lib/transforms/ValidateRequiredArgumentsTransform.js +0 -114
  163. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +0 -108
  164. package/lib/transforms/ValidateUnusedVariablesTransform.js +0 -96
  165. package/lib/transforms/query-generators/FetchableQueryGenerator.js +0 -157
  166. package/lib/transforms/query-generators/NodeQueryGenerator.js +0 -166
  167. package/lib/transforms/query-generators/QueryQueryGenerator.js +0 -48
  168. package/lib/transforms/query-generators/ViewerQueryGenerator.js +0 -77
  169. package/lib/transforms/query-generators/index.js +0 -60
  170. package/lib/transforms/query-generators/utils.js +0 -92
  171. package/lib/util/CodeMarker.js +0 -80
  172. package/lib/util/DefaultHandleKey.js +0 -15
  173. package/lib/util/RelayCompilerCache.js +0 -97
  174. package/lib/util/Rollout.js +0 -40
  175. package/lib/util/TimeReporter.js +0 -83
  176. package/lib/util/areEqualArgValues.js +0 -135
  177. package/lib/util/argumentContainsVariables.js +0 -37
  178. package/lib/util/dedupeJSONStringify.js +0 -160
  179. package/lib/util/generateAbstractTypeRefinementKey.js +0 -24
  180. package/lib/util/getDefinitionNodeHash.js +0 -22
  181. package/lib/util/getModuleName.js +0 -32
  182. package/lib/util/joinArgumentDefinitions.js +0 -67
  183. package/lib/util/md5.js +0 -17
  184. package/lib/util/murmurHash.js +0 -86
  185. package/lib/util/nullthrowsOSS.js +0 -23
  186. package/lib/util/orList.js +0 -36
  187. package/lib/util/partitionArray.js +0 -35
  188. package/relay-compiler.js +0 -17
  189. package/relay-compiler.min.js +0 -22
  190. package/reporters/ConsoleReporter.js.flow +0 -81
  191. package/reporters/MultiReporter.js.flow +0 -43
  192. package/reporters/Reporter.js.flow +0 -19
  193. package/runner/Artifacts.js.flow +0 -215
  194. package/runner/BufferedFilesystem.js.flow +0 -194
  195. package/runner/GraphQLASTNodeGroup.js.flow +0 -174
  196. package/runner/GraphQLASTUtils.js.flow +0 -26
  197. package/runner/GraphQLNodeMap.js.flow +0 -55
  198. package/runner/Sources.js.flow +0 -227
  199. package/runner/StrictMap.js.flow +0 -96
  200. package/runner/compileArtifacts.js.flow +0 -75
  201. package/runner/extractAST.js.flow +0 -98
  202. package/runner/getChangedNodeNames.js.flow +0 -48
  203. package/runner/getSchemaInstance.js.flow +0 -36
  204. package/runner/types.js.flow +0 -37
  205. package/test-utils/TestSchema.js.flow +0 -30
  206. package/test-utils/parseGraphQLText.js.flow +0 -41
  207. package/transforms/ApplyFragmentArgumentTransform.js.flow +0 -524
  208. package/transforms/ClientExtensionsTransform.js.flow +0 -224
  209. package/transforms/ConnectionTransform.js.flow +0 -850
  210. package/transforms/DeclarativeConnectionMutationTransform.js.flow +0 -245
  211. package/transforms/DeferStreamTransform.js.flow +0 -263
  212. package/transforms/DisallowIdAsAlias.js.flow +0 -46
  213. package/transforms/DisallowTypenameOnRoot.js.flow +0 -44
  214. package/transforms/FieldHandleTransform.js.flow +0 -77
  215. package/transforms/FilterCompilerDirectivesTransform.js.flow +0 -33
  216. package/transforms/FilterDirectivesTransform.js.flow +0 -45
  217. package/transforms/FlattenTransform.js.flow +0 -458
  218. package/transforms/GenerateIDFieldTransform.js.flow +0 -151
  219. package/transforms/GenerateTypeNameTransform.js.flow +0 -159
  220. package/transforms/InlineDataFragmentTransform.js.flow +0 -123
  221. package/transforms/InlineFragmentsTransform.js.flow +0 -70
  222. package/transforms/MaskTransform.js.flow +0 -124
  223. package/transforms/MatchTransform.js.flow +0 -587
  224. package/transforms/ReactFlightComponentTransform.js.flow +0 -207
  225. package/transforms/RefetchableFragmentTransform.js.flow +0 -266
  226. package/transforms/RelayDirectiveTransform.js.flow +0 -96
  227. package/transforms/RequiredFieldTransform.js.flow +0 -413
  228. package/transforms/SkipClientExtensionsTransform.js.flow +0 -54
  229. package/transforms/SkipHandleFieldTransform.js.flow +0 -44
  230. package/transforms/SkipRedundantNodesTransform.js.flow +0 -277
  231. package/transforms/SkipSplitOperationTransform.js.flow +0 -37
  232. package/transforms/SkipUnreachableNodeTransform.js.flow +0 -148
  233. package/transforms/SkipUnusedVariablesTransform.js.flow +0 -59
  234. package/transforms/SplitModuleImportTransform.js.flow +0 -97
  235. package/transforms/TestOperationTransform.js.flow +0 -142
  236. package/transforms/TransformUtils.js.flow +0 -26
  237. package/transforms/ValidateGlobalVariablesTransform.js.flow +0 -80
  238. package/transforms/ValidateRequiredArgumentsTransform.js.flow +0 -130
  239. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +0 -128
  240. package/transforms/ValidateUnusedVariablesTransform.js.flow +0 -88
  241. package/transforms/query-generators/FetchableQueryGenerator.js.flow +0 -188
  242. package/transforms/query-generators/NodeQueryGenerator.js.flow +0 -217
  243. package/transforms/query-generators/QueryQueryGenerator.js.flow +0 -57
  244. package/transforms/query-generators/ViewerQueryGenerator.js.flow +0 -97
  245. package/transforms/query-generators/index.js.flow +0 -89
  246. package/transforms/query-generators/utils.js.flow +0 -76
  247. package/util/CodeMarker.js.flow +0 -79
  248. package/util/DefaultHandleKey.js.flow +0 -17
  249. package/util/RelayCompilerCache.js.flow +0 -86
  250. package/util/Rollout.js.flow +0 -39
  251. package/util/TimeReporter.js.flow +0 -79
  252. package/util/areEqualArgValues.js.flow +0 -126
  253. package/util/argumentContainsVariables.js.flow +0 -38
  254. package/util/dedupeJSONStringify.js.flow +0 -156
  255. package/util/generateAbstractTypeRefinementKey.js.flow +0 -29
  256. package/util/getDefinitionNodeHash.js.flow +0 -24
  257. package/util/getModuleName.js.flow +0 -39
  258. package/util/joinArgumentDefinitions.js.flow +0 -105
  259. package/util/md5.js.flow +0 -19
  260. package/util/murmurHash.js.flow +0 -94
  261. package/util/nullthrowsOSS.js.flow +0 -25
  262. package/util/orList.js.flow +0 -37
  263. package/util/partitionArray.js.flow +0 -37
@@ -1,1096 +0,0 @@
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
- import type {IRTransform} from '../../core/CompilerContext';
16
- import type {
17
- Directive,
18
- Fragment,
19
- Metadata,
20
- ModuleImport,
21
- Root,
22
- Selection as IRSelection,
23
- } from '../../core/IR';
24
- import type {NodeVisitor} from '../../core/IRVisitor';
25
- import type {EnumTypeID, Schema, TypeID} from '../../core/Schema';
26
- import type {RequiredDirectiveMetadata} from '../../transforms/RequiredFieldTransform';
27
- import type {TypeGeneratorOptions} from '../RelayLanguagePluginInterface';
28
-
29
- const Profiler = require('../../core/GraphQLCompilerProfiler');
30
- const IRVisitor = require('../../core/IRVisitor');
31
- const FlattenTransform = require('../../transforms/FlattenTransform');
32
- const MaskTransform = require('../../transforms/MaskTransform');
33
- const MatchTransform = require('../../transforms/MatchTransform');
34
- const RefetchableFragmentTransform = require('../../transforms/RefetchableFragmentTransform');
35
- const RelayDirectiveTransform = require('../../transforms/RelayDirectiveTransform');
36
- const RequiredFieldTransform = require('../../transforms/RequiredFieldTransform');
37
- const generateAbstractTypeRefinementKey = require('../../util/generateAbstractTypeRefinementKey');
38
- const partitionArray = require('../../util/partitionArray');
39
- const {
40
- anyTypeAlias,
41
- declareExportOpaqueType,
42
- exactObjectTypeAnnotation,
43
- exportType,
44
- exportTypes,
45
- importTypes,
46
- inexactObjectTypeAnnotation,
47
- intersectionTypeAnnotation,
48
- lineComments,
49
- readOnlyArrayOfType,
50
- readOnlyObjectTypeProperty,
51
- unionTypeAnnotation,
52
- } = require('./RelayFlowBabelFactories');
53
- const {
54
- transformInputType,
55
- transformScalarType,
56
- } = require('./RelayFlowTypeTransformers');
57
- const babelGenerator = require('@babel/generator').default;
58
- const t = require('@babel/types');
59
- const invariant = require('invariant');
60
- const nullthrows = require('nullthrows');
61
-
62
- export type State = {|
63
- ...TypeGeneratorOptions,
64
- +generatedFragments: Set<string>,
65
- +generatedInputObjectTypes: {[name: string]: TypeID | 'pending', ...},
66
- +usedEnums: {[name: string]: EnumTypeID, ...},
67
- +usedFragments: Set<string>,
68
- +matchFields: Map<string, mixed>,
69
- +runtimeImports: Set<string>,
70
- |};
71
-
72
- function generate(
73
- schema: Schema,
74
- node: Root | Fragment,
75
- options: TypeGeneratorOptions,
76
- ): string {
77
- const ast = IRVisitor.visit(node, createVisitor(schema, options));
78
- return babelGenerator(ast).code;
79
- }
80
-
81
- type Selection = {|
82
- +key: string,
83
- +schemaName?: string,
84
- +value?: any,
85
- +nodeType?: TypeID,
86
- +conditional?: boolean,
87
- +concreteType?: string,
88
- +ref?: string,
89
- +nodeSelections?: ?SelectionMap,
90
- +kind?: string,
91
- +documentName?: string,
92
- |};
93
-
94
- type SelectionMap = Map<string, Selection>;
95
-
96
- function makeProp(
97
- schema: Schema,
98
- {key, schemaName, value, conditional, nodeType, nodeSelections}: Selection,
99
- state: State,
100
- unmasked: boolean,
101
- concreteType?: string,
102
- ) {
103
- if (schemaName === '__typename' && concreteType) {
104
- value = t.stringLiteralTypeAnnotation(concreteType);
105
- } else if (nodeType) {
106
- value = transformScalarType(
107
- schema,
108
- nodeType,
109
- state,
110
- selectionsToBabel(
111
- schema,
112
- [Array.from(nullthrows(nodeSelections).values())],
113
- state,
114
- unmasked,
115
- ),
116
- );
117
- }
118
- const typeProperty = readOnlyObjectTypeProperty(key, value);
119
- if (conditional) {
120
- typeProperty.optional = true;
121
- }
122
- return typeProperty;
123
- }
124
-
125
- const isTypenameSelection = selection => selection.schemaName === '__typename';
126
- const hasTypenameSelection = selections => selections.some(isTypenameSelection);
127
- const onlySelectsTypename = selections => selections.every(isTypenameSelection);
128
-
129
- function selectionsToBabel(
130
- schema: Schema,
131
- selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>,
132
- state: State,
133
- unmasked: boolean,
134
- fragmentTypeName?: string,
135
- ) {
136
- const baseFields = new Map();
137
- const byConcreteType = {};
138
- flattenArray(selections).forEach(selection => {
139
- const {concreteType} = selection;
140
- if (concreteType) {
141
- byConcreteType[concreteType] = byConcreteType[concreteType] ?? [];
142
- byConcreteType[concreteType].push(selection);
143
- } else {
144
- const previousSel = baseFields.get(selection.key);
145
-
146
- baseFields.set(
147
- selection.key,
148
- previousSel ? mergeSelection(selection, previousSel) : selection,
149
- );
150
- }
151
- });
152
-
153
- const types = [];
154
-
155
- if (
156
- Object.keys(byConcreteType).length > 0 &&
157
- onlySelectsTypename(Array.from(baseFields.values())) &&
158
- (hasTypenameSelection(Array.from(baseFields.values())) ||
159
- Object.keys(byConcreteType).every(type =>
160
- hasTypenameSelection(byConcreteType[type]),
161
- ))
162
- ) {
163
- const typenameAliases = new Set();
164
- for (const concreteType in byConcreteType) {
165
- types.push(
166
- groupRefs([
167
- ...Array.from(baseFields.values()),
168
- ...byConcreteType[concreteType],
169
- ]).map(selection => {
170
- if (selection.schemaName === '__typename') {
171
- typenameAliases.add(selection.key);
172
- }
173
- return makeProp(schema, selection, state, unmasked, concreteType);
174
- }),
175
- );
176
- }
177
- // It might be some other type then the listed concrete types. Ideally, we
178
- // would set the type to diff(string, set of listed concrete types), but
179
- // this doesn't exist in Flow at the time.
180
- types.push(
181
- Array.from(typenameAliases).map(typenameAlias => {
182
- const otherProp = readOnlyObjectTypeProperty(
183
- typenameAlias,
184
- t.stringLiteralTypeAnnotation('%other'),
185
- );
186
- otherProp.leadingComments = lineComments(
187
- "This will never be '%other', but we need some",
188
- 'value in case none of the concrete values match.',
189
- );
190
- return otherProp;
191
- }),
192
- );
193
- } else {
194
- let selectionMap = selectionsToMap(Array.from(baseFields.values()));
195
- for (const concreteType in byConcreteType) {
196
- selectionMap = mergeSelections(
197
- selectionMap,
198
- selectionsToMap(
199
- byConcreteType[concreteType].map(sel => ({
200
- ...sel,
201
- conditional: true,
202
- })),
203
- ),
204
- );
205
- }
206
- const selectionMapValues = groupRefs(Array.from(selectionMap.values())).map(
207
- sel =>
208
- isTypenameSelection(sel) && sel.concreteType
209
- ? makeProp(
210
- schema,
211
- {...sel, conditional: false},
212
- state,
213
- unmasked,
214
- sel.concreteType,
215
- )
216
- : makeProp(schema, sel, state, unmasked),
217
- );
218
- types.push(selectionMapValues);
219
- }
220
-
221
- return unionTypeAnnotation(
222
- types.map(props => {
223
- if (fragmentTypeName) {
224
- props.push(
225
- readOnlyObjectTypeProperty(
226
- '$refType',
227
- t.genericTypeAnnotation(t.identifier(fragmentTypeName)),
228
- ),
229
- );
230
- }
231
- return unmasked
232
- ? inexactObjectTypeAnnotation(props)
233
- : exactObjectTypeAnnotation(props);
234
- }),
235
- );
236
- }
237
-
238
- function mergeSelection(
239
- a: ?Selection,
240
- b: Selection,
241
- shouldSetConditional: boolean = true,
242
- ): Selection {
243
- if (!a) {
244
- if (shouldSetConditional) {
245
- return {
246
- ...b,
247
- conditional: true,
248
- };
249
- }
250
- return b;
251
- }
252
- return {
253
- ...a,
254
- nodeSelections: a.nodeSelections
255
- ? mergeSelections(
256
- a.nodeSelections,
257
- nullthrows(b.nodeSelections),
258
- shouldSetConditional,
259
- )
260
- : null,
261
- conditional: a.conditional && b.conditional,
262
- };
263
- }
264
-
265
- function mergeSelections(
266
- a: SelectionMap,
267
- b: SelectionMap,
268
- shouldSetConditional: boolean = true,
269
- ): SelectionMap {
270
- const merged = new Map();
271
- for (const [key, value] of a.entries()) {
272
- merged.set(key, value);
273
- }
274
- for (const [key, value] of b.entries()) {
275
- merged.set(key, mergeSelection(a.get(key), value, shouldSetConditional));
276
- }
277
- return merged;
278
- }
279
-
280
- function isPlural(node: Fragment): boolean {
281
- return Boolean(node.metadata && node.metadata.plural);
282
- }
283
-
284
- function createVisitor(
285
- schema: Schema,
286
- options: TypeGeneratorOptions,
287
- ): NodeVisitor {
288
- const state = {
289
- customScalars: options.customScalars,
290
- enumsHasteModule: options.enumsHasteModule,
291
- generatedFragments: new Set(),
292
- generatedInputObjectTypes: {},
293
- optionalInputFields: options.optionalInputFields,
294
- usedEnums: {},
295
- usedFragments: new Set(),
296
- useHaste: options.useHaste,
297
- useSingleArtifactDirectory: options.useSingleArtifactDirectory,
298
- noFutureProofEnums: options.noFutureProofEnums,
299
- matchFields: new Map(),
300
- runtimeImports: new Set(),
301
- };
302
- return {
303
- leave: {
304
- Root(node: Root) {
305
- const inputVariablesType = generateInputVariablesType(
306
- schema,
307
- node,
308
- state,
309
- );
310
- const inputObjectTypes = generateInputObjectTypes(state);
311
-
312
- let responseTypeDefinition = selectionsToBabel(
313
- schema,
314
- /* $FlowFixMe: selections have already been transformed */
315
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
316
- state,
317
- false,
318
- );
319
-
320
- if (node.metadata?.childrenCanBubbleNull === true) {
321
- responseTypeDefinition = t.nullableTypeAnnotation(
322
- responseTypeDefinition,
323
- );
324
- }
325
-
326
- const responseType = exportType(
327
- `${node.name}Response`,
328
- responseTypeDefinition,
329
- );
330
-
331
- const operationTypes = [
332
- t.objectTypeProperty(
333
- t.identifier('variables'),
334
- t.genericTypeAnnotation(t.identifier(`${node.name}Variables`)),
335
- ),
336
- t.objectTypeProperty(
337
- t.identifier('response'),
338
- t.genericTypeAnnotation(t.identifier(`${node.name}Response`)),
339
- ),
340
- ];
341
-
342
- // Generate raw response type
343
- let rawResponseType;
344
- const {normalizationIR} = options;
345
- if (
346
- normalizationIR &&
347
- node.directives.some(d => d.name === DIRECTIVE_NAME)
348
- ) {
349
- rawResponseType = IRVisitor.visit(
350
- normalizationIR,
351
- createRawResponseTypeVisitor(schema, state),
352
- );
353
- }
354
- const refetchableFragmentName = getRefetchableQueryParentFragmentName(
355
- state,
356
- node.metadata,
357
- );
358
- if (refetchableFragmentName != null) {
359
- state.runtimeImports.add('FragmentReference');
360
- }
361
- const babelNodes = [];
362
- if (state.runtimeImports.size) {
363
- babelNodes.push(
364
- importTypes(
365
- Array.from(state.runtimeImports).sort(),
366
- 'relay-runtime',
367
- ),
368
- );
369
- }
370
- babelNodes.push(
371
- ...(refetchableFragmentName
372
- ? generateFragmentRefsForRefetchable(refetchableFragmentName)
373
- : getFragmentImports(state)),
374
- ...getEnumDefinitions(schema, state),
375
- ...inputObjectTypes,
376
- inputVariablesType,
377
- responseType,
378
- );
379
-
380
- if (rawResponseType) {
381
- for (const [key, ast] of state.matchFields) {
382
- babelNodes.push(exportType(key, ast));
383
- }
384
- operationTypes.push(
385
- t.objectTypeProperty(
386
- t.identifier('rawResponse'),
387
- t.genericTypeAnnotation(t.identifier(`${node.name}RawResponse`)),
388
- ),
389
- );
390
- babelNodes.push(rawResponseType);
391
- }
392
-
393
- babelNodes.push(
394
- exportType(node.name, exactObjectTypeAnnotation(operationTypes)),
395
- );
396
-
397
- return t.program(babelNodes);
398
- },
399
- Fragment(node) {
400
- let selections = flattenArray(
401
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
402
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
403
- );
404
- const numConecreteSelections = selections.filter(
405
- s => s.concreteType,
406
- ).length;
407
- selections = selections.map(selection => {
408
- if (
409
- numConecreteSelections <= 1 &&
410
- isTypenameSelection(selection) &&
411
- !schema.isAbstractType(node.type)
412
- ) {
413
- return [
414
- {
415
- ...selection,
416
- concreteType: schema.getTypeString(node.type),
417
- },
418
- ];
419
- }
420
- return [selection];
421
- });
422
- state.generatedFragments.add(node.name);
423
- const fragmentTypes = getFragmentTypes(
424
- node.name,
425
- getRefetchableQueryPath(state, node.directives),
426
- );
427
-
428
- const refTypeName = getRefTypeName(node.name);
429
- const refTypeDataProperty = readOnlyObjectTypeProperty(
430
- '$data',
431
- t.genericTypeAnnotation(t.identifier(`${node.name}$data`)),
432
- );
433
- refTypeDataProperty.optional = true;
434
- const refTypeFragmentRefProperty = readOnlyObjectTypeProperty(
435
- '$fragmentRefs',
436
- t.genericTypeAnnotation(
437
- t.identifier(getOldFragmentTypeName(node.name)),
438
- ),
439
- );
440
- const isPluralFragment = isPlural(node);
441
- const refType = inexactObjectTypeAnnotation([
442
- refTypeDataProperty,
443
- refTypeFragmentRefProperty,
444
- ]);
445
-
446
- const dataTypeName = getDataTypeName(node.name);
447
- const dataType = t.genericTypeAnnotation(t.identifier(node.name));
448
-
449
- const unmasked = node.metadata != null && node.metadata.mask === false;
450
- const baseType = selectionsToBabel(
451
- schema,
452
- selections,
453
- state,
454
- unmasked,
455
- unmasked ? undefined : getOldFragmentTypeName(node.name),
456
- );
457
- let type = isPluralFragment ? readOnlyArrayOfType(baseType) : baseType;
458
-
459
- if (node.metadata?.childrenCanBubbleNull === true) {
460
- type = t.nullableTypeAnnotation(type);
461
- }
462
-
463
- state.runtimeImports.add('FragmentReference');
464
-
465
- return t.program([
466
- ...getFragmentImports(state),
467
- ...getEnumDefinitions(schema, state),
468
- importTypes(Array.from(state.runtimeImports).sort(), 'relay-runtime'),
469
- ...fragmentTypes,
470
- exportType(node.name, type),
471
- exportType(dataTypeName, dataType),
472
- exportType(
473
- refTypeName,
474
- isPluralFragment ? readOnlyArrayOfType(refType) : refType,
475
- ),
476
- ]);
477
- },
478
- InlineFragment(node) {
479
- return flattenArray(
480
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
481
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
482
- ).map(typeSelection => {
483
- return schema.isAbstractType(node.typeCondition)
484
- ? {
485
- ...typeSelection,
486
- conditional: true,
487
- }
488
- : {
489
- ...typeSelection,
490
- concreteType: schema.getTypeString(node.typeCondition),
491
- };
492
- });
493
- },
494
- Condition(node) {
495
- return flattenArray(
496
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
497
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
498
- ).map(selection => {
499
- return {
500
- ...selection,
501
- conditional: true,
502
- };
503
- });
504
- },
505
- ScalarField(node) {
506
- return visitScalarField(schema, node, state);
507
- },
508
- LinkedField(node) {
509
- return visitLinkedField(schema, node);
510
- },
511
- ModuleImport(node) {
512
- return [
513
- {
514
- key: '__fragmentPropName',
515
- conditional: true,
516
- value: transformScalarType(
517
- schema,
518
- schema.expectStringType(),
519
- state,
520
- ),
521
- },
522
- {
523
- key: '__module_component',
524
- conditional: true,
525
- value: transformScalarType(
526
- schema,
527
- schema.expectStringType(),
528
- state,
529
- ),
530
- },
531
- {
532
- key: '__fragments_' + node.name,
533
- ref: node.name,
534
- },
535
- ];
536
- },
537
- FragmentSpread(node) {
538
- state.usedFragments.add(node.name);
539
- return [
540
- {
541
- key: '__fragments_' + node.name,
542
- ref: node.name,
543
- },
544
- ];
545
- },
546
- },
547
- };
548
- }
549
-
550
- function visitNodeWithSelectionsOnly(node) {
551
- return flattenArray(
552
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
553
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
554
- );
555
- }
556
-
557
- function visitScalarField(schema: Schema, node, state: State) {
558
- const requiredMetadata: ?RequiredDirectiveMetadata = (node.metadata
559
- ?.required: $FlowFixMe);
560
- const nodeType =
561
- requiredMetadata != null ? schema.getNonNullType(node.type) : node.type;
562
- return [
563
- {
564
- key: node.alias,
565
- schemaName: node.name,
566
- value: transformScalarType(schema, nodeType, state),
567
- },
568
- ];
569
- }
570
-
571
- function getLinkedFieldNodeType(schema: Schema, node) {
572
- const requiredMetadata: ?RequiredDirectiveMetadata = (node.metadata
573
- ?.required: $FlowFixMe);
574
-
575
- if (requiredMetadata != null) {
576
- return schema.getNonNullType(node.type);
577
- }
578
- if (node.metadata?.childrenCanBubbleNull === true) {
579
- if (schema.isList(node.type)) {
580
- // In a plural field, nulls bubble up to the item, resulting in a list of nullable items.
581
- return schema.mapListItemType(node.type, inner =>
582
- schema.getNullableType(inner),
583
- );
584
- } else if (schema.isNonNull(node.type)) {
585
- const nullable = schema.getNullableType(node.type);
586
- if (schema.isList(nullable)) {
587
- return schema.getNonNullType(
588
- schema.mapListItemType(nullable, inner =>
589
- schema.getNullableType(inner),
590
- ),
591
- );
592
- }
593
- return nullable;
594
- }
595
- return node.type;
596
- }
597
- return node.type;
598
- }
599
-
600
- function visitLinkedField(schema: Schema, node) {
601
- return [
602
- {
603
- key: node.alias,
604
- schemaName: node.name,
605
- nodeType: getLinkedFieldNodeType(schema, node),
606
- nodeSelections: selectionsToMap(
607
- flattenArray(
608
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
609
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
610
- ),
611
- /*
612
- * append concreteType to key so overlapping fields with different
613
- * concreteTypes don't get overwritten by each other
614
- */
615
- true,
616
- ),
617
- },
618
- ];
619
- }
620
-
621
- function makeRawResponseProp(
622
- schema: Schema,
623
- {
624
- key,
625
- schemaName,
626
- value,
627
- conditional,
628
- nodeType,
629
- nodeSelections,
630
- kind,
631
- }: Selection,
632
- state: State,
633
- concreteType: ?string,
634
- ) {
635
- if (kind === 'ModuleImport') {
636
- return t.objectTypeSpreadProperty(
637
- t.genericTypeAnnotation(t.identifier(key)),
638
- );
639
- }
640
- if (schemaName === '__typename' && concreteType) {
641
- value = t.stringLiteralTypeAnnotation(concreteType);
642
- } else if (nodeType) {
643
- value = transformScalarType(
644
- schema,
645
- nodeType,
646
- state,
647
- selectionsToRawResponseBabel(
648
- schema,
649
- [Array.from(nullthrows(nodeSelections).values())],
650
- state,
651
- schema.isAbstractType(nodeType) || schema.isWrapper(nodeType)
652
- ? null
653
- : schema.getTypeString(nodeType),
654
- ),
655
- );
656
- }
657
- const typeProperty = readOnlyObjectTypeProperty(key, value);
658
- if (conditional) {
659
- typeProperty.optional = true;
660
- }
661
- return typeProperty;
662
- }
663
-
664
- // Trasform the codegen IR selections into Babel flow types
665
- function selectionsToRawResponseBabel(
666
- schema: Schema,
667
- selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>,
668
- state: State,
669
- nodeTypeName: ?string,
670
- ) {
671
- const baseFields = [];
672
- const byConcreteType = {};
673
-
674
- flattenArray(selections).forEach(selection => {
675
- const {concreteType} = selection;
676
- if (concreteType) {
677
- byConcreteType[concreteType] = byConcreteType[concreteType] ?? [];
678
- byConcreteType[concreteType].push(selection);
679
- } else {
680
- baseFields.push(selection);
681
- }
682
- });
683
-
684
- const types = [];
685
- if (Object.keys(byConcreteType).length) {
686
- const baseFieldsMap = selectionsToMap(baseFields);
687
- for (const concreteType in byConcreteType) {
688
- const mergedSeletions = Array.from(
689
- mergeSelections(
690
- baseFieldsMap,
691
- selectionsToMap(byConcreteType[concreteType]),
692
- false,
693
- ).values(),
694
- );
695
- types.push(
696
- exactObjectTypeAnnotation(
697
- mergedSeletions.map(selection =>
698
- makeRawResponseProp(schema, selection, state, concreteType),
699
- ),
700
- ),
701
- );
702
- appendLocal3DPayload(types, mergedSeletions, schema, state, concreteType);
703
- }
704
- }
705
- if (baseFields.length > 0) {
706
- types.push(
707
- exactObjectTypeAnnotation(
708
- baseFields.map(selection =>
709
- makeRawResponseProp(schema, selection, state, nodeTypeName),
710
- ),
711
- ),
712
- );
713
- appendLocal3DPayload(types, baseFields, schema, state, nodeTypeName);
714
- }
715
- return unionTypeAnnotation(types);
716
- }
717
-
718
- function appendLocal3DPayload(
719
- types: Array<mixed>,
720
- selections: $ReadOnlyArray<Selection>,
721
- schema: Schema,
722
- state: State,
723
- currentType: ?string,
724
- ): void {
725
- const moduleImport = selections.find(sel => sel.kind === 'ModuleImport');
726
- if (moduleImport) {
727
- // Generate an extra opaque type for client 3D fields
728
- state.runtimeImports.add('Local3DPayload');
729
- types.push(
730
- t.genericTypeAnnotation(
731
- t.identifier('Local3DPayload'),
732
- t.typeParameterInstantiation([
733
- t.stringLiteralTypeAnnotation(nullthrows(moduleImport.documentName)),
734
- exactObjectTypeAnnotation(
735
- selections
736
- .filter(sel => sel.schemaName !== 'js')
737
- .map(selection =>
738
- makeRawResponseProp(schema, selection, state, currentType),
739
- ),
740
- ),
741
- ]),
742
- ),
743
- );
744
- }
745
- }
746
-
747
- // Visitor for generating raw response type
748
- function createRawResponseTypeVisitor(schema: Schema, state: State) {
749
- return {
750
- leave: {
751
- Root(node) {
752
- return exportType(
753
- `${node.name}RawResponse`,
754
- selectionsToRawResponseBabel(
755
- schema,
756
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
757
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
758
- state,
759
- null,
760
- ),
761
- );
762
- },
763
- InlineFragment(node) {
764
- const typeCondition = node.typeCondition;
765
- return flattenArray(
766
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
767
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
768
- ).map(typeSelection => {
769
- return schema.isAbstractType(typeCondition)
770
- ? typeSelection
771
- : {
772
- ...typeSelection,
773
- concreteType: schema.getTypeString(typeCondition),
774
- };
775
- });
776
- },
777
- ScalarField(node) {
778
- return visitScalarField(schema, node, state);
779
- },
780
- ClientExtension(node) {
781
- return flattenArray(
782
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
783
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>),
784
- ).map(sel => ({
785
- ...sel,
786
- conditional: true,
787
- }));
788
- },
789
- LinkedField(node) {
790
- return visitLinkedField(schema, node);
791
- },
792
- Condition: visitNodeWithSelectionsOnly,
793
- Defer: visitNodeWithSelectionsOnly,
794
- Stream: visitNodeWithSelectionsOnly,
795
- ModuleImport(node) {
796
- return visitRawResposneModuleImport(schema, node, state);
797
- },
798
- FragmentSpread(node) {
799
- invariant(
800
- false,
801
- 'A fragment spread is found when traversing the AST, ' +
802
- 'make sure you are passing the codegen IR',
803
- );
804
- },
805
- },
806
- };
807
- }
808
-
809
- // Dedupe the generated type of module selections to reduce file size
810
- function visitRawResposneModuleImport(
811
- schema: Schema,
812
- node: ModuleImport,
813
- state: State,
814
- ): $ReadOnlyArray<Selection> {
815
- const {selections, name: key} = node;
816
- const moduleSelections = selections
817
- .filter(
818
- // $FlowFixMe[prop-missing] selections have already been transformed
819
- sel => sel.length && sel[0].schemaName === 'js',
820
- )
821
- .map(arr => arr[0]);
822
- if (!state.matchFields.has(key)) {
823
- const ast = selectionsToRawResponseBabel(
824
- schema,
825
- // $FlowFixMe[incompatible-cast] : selections have already been transformed
826
- (node.selections: $ReadOnlyArray<$ReadOnlyArray<Selection>>).filter(
827
- sel => sel.length > 1 || sel[0].schemaName !== 'js',
828
- ),
829
- state,
830
- null,
831
- );
832
- state.matchFields.set(key, ast);
833
- }
834
- return [
835
- ...moduleSelections,
836
- {
837
- key,
838
- kind: 'ModuleImport',
839
- documentName: node.key,
840
- },
841
- ];
842
- }
843
-
844
- function selectionsToMap(
845
- selections: $ReadOnlyArray<Selection>,
846
- appendType?: boolean,
847
- ): SelectionMap {
848
- const map = new Map();
849
- selections.forEach(selection => {
850
- const key =
851
- appendType && selection.concreteType
852
- ? `${selection.key}::${selection.concreteType}`
853
- : selection.key;
854
- const previousSel = map.get(key);
855
- map.set(
856
- key,
857
- previousSel ? mergeSelection(previousSel, selection) : selection,
858
- );
859
- });
860
- return map;
861
- }
862
-
863
- function flattenArray(
864
- arrayOfArrays: $ReadOnlyArray<$ReadOnlyArray<Selection>>,
865
- ): $ReadOnlyArray<Selection> {
866
- const result = [];
867
- arrayOfArrays.forEach(array => {
868
- result.push(...array);
869
- });
870
- return result;
871
- }
872
-
873
- function generateInputObjectTypes(state: State) {
874
- return Object.keys(state.generatedInputObjectTypes).map(typeIdentifier => {
875
- const inputObjectType = state.generatedInputObjectTypes[typeIdentifier];
876
- invariant(
877
- typeof inputObjectType !== 'string',
878
- 'RelayCompilerFlowGenerator: Expected input object type to have been' +
879
- ' defined before calling `generateInputObjectTypes`',
880
- );
881
- return exportType(typeIdentifier, inputObjectType);
882
- });
883
- }
884
-
885
- function generateInputVariablesType(schema: Schema, node: Root, state: State) {
886
- return exportType(
887
- `${node.name}Variables`,
888
- exactObjectTypeAnnotation(
889
- node.argumentDefinitions.map(arg => {
890
- const property = t.objectTypeProperty(
891
- t.identifier(arg.name),
892
- transformInputType(schema, arg.type, state),
893
- );
894
- if (!schema.isNonNull(arg.type)) {
895
- property.optional = true;
896
- }
897
- return property;
898
- }),
899
- ),
900
- );
901
- }
902
-
903
- function groupRefs(props): $ReadOnlyArray<Selection> {
904
- const result = [];
905
- const refs = [];
906
- props.forEach(prop => {
907
- if (prop.ref) {
908
- refs.push(prop.ref);
909
- } else {
910
- result.push(prop);
911
- }
912
- });
913
- if (refs.length > 0) {
914
- const value = intersectionTypeAnnotation(
915
- refs.map(ref =>
916
- t.genericTypeAnnotation(t.identifier(getOldFragmentTypeName(ref))),
917
- ),
918
- );
919
- result.push({
920
- key: '$fragmentRefs',
921
- conditional: false,
922
- value,
923
- });
924
- }
925
- return result;
926
- }
927
-
928
- function getFragmentImports(state: State) {
929
- const imports = [];
930
- if (state.usedFragments.size > 0) {
931
- const usedFragments = Array.from(state.usedFragments).sort();
932
- for (const usedFragment of usedFragments) {
933
- const fragmentTypeName = getOldFragmentTypeName(usedFragment);
934
- if (!state.generatedFragments.has(usedFragment)) {
935
- if (state.useHaste) {
936
- // TODO(T22653277) support non-haste environments when importing
937
- // fragments
938
- imports.push(
939
- importTypes([fragmentTypeName], usedFragment + '.graphql'),
940
- );
941
- } else if (state.useSingleArtifactDirectory) {
942
- imports.push(
943
- importTypes([fragmentTypeName], './' + usedFragment + '.graphql'),
944
- );
945
- } else {
946
- imports.push(anyTypeAlias(fragmentTypeName));
947
- }
948
- }
949
- }
950
- }
951
- return imports;
952
- }
953
-
954
- function getEnumDefinitions(
955
- schema: Schema,
956
- {enumsHasteModule, usedEnums, noFutureProofEnums}: State,
957
- ) {
958
- const enumNames = Object.keys(usedEnums).sort();
959
- if (enumNames.length === 0) {
960
- return [];
961
- }
962
- if (typeof enumsHasteModule === 'string') {
963
- return [importTypes(enumNames, enumsHasteModule)];
964
- }
965
- if (typeof enumsHasteModule === 'function') {
966
- return enumNames.map(enumName =>
967
- importTypes([enumName], enumsHasteModule(enumName)),
968
- );
969
- }
970
- return enumNames.map(name => {
971
- const values = [].concat(schema.getEnumValues(usedEnums[name]));
972
- values.sort();
973
- if (!noFutureProofEnums) {
974
- values.push('%future added value');
975
- }
976
- return exportType(
977
- name,
978
- t.unionTypeAnnotation(
979
- values.map(value => t.stringLiteralTypeAnnotation(value)),
980
- ),
981
- );
982
- });
983
- }
984
-
985
- // If it's a @refetchable fragment, we generate the $fragmentRef in generated
986
- // query, and import it in the fragment to avoid circular dependencies
987
- function getRefetchableQueryParentFragmentName(
988
- state: State,
989
- metadata: Metadata,
990
- ): ?string {
991
- if (
992
- !metadata?.isRefetchableQuery ||
993
- (!state.useHaste && !state.useSingleArtifactDirectory)
994
- ) {
995
- return null;
996
- }
997
- const derivedFrom = metadata?.derivedFrom;
998
- if (derivedFrom != null && typeof derivedFrom === 'string') {
999
- return derivedFrom;
1000
- }
1001
- return null;
1002
- }
1003
-
1004
- function getRefetchableQueryPath(
1005
- state: State,
1006
- directives: $ReadOnlyArray<Directive>,
1007
- ): ?string {
1008
- let refetchableQuery: ?string;
1009
- if (!state.useHaste && !state.useSingleArtifactDirectory) {
1010
- return;
1011
- }
1012
- const refetchableArgs = directives.find(d => d.name === 'refetchable')?.args;
1013
- if (!refetchableArgs) {
1014
- return;
1015
- }
1016
- const argument = refetchableArgs.find(
1017
- arg => arg.kind === 'Argument' && arg.name === 'queryName',
1018
- );
1019
- if (
1020
- argument &&
1021
- argument.value &&
1022
- argument.value.kind === 'Literal' &&
1023
- typeof argument.value.value === 'string'
1024
- ) {
1025
- refetchableQuery = argument.value.value;
1026
- if (!state.useHaste) {
1027
- refetchableQuery = './' + refetchableQuery;
1028
- }
1029
- refetchableQuery += '.graphql';
1030
- }
1031
- return refetchableQuery;
1032
- }
1033
-
1034
- function generateFragmentRefsForRefetchable(name: string) {
1035
- const oldFragmentTypeName = getOldFragmentTypeName(name);
1036
- const newFragmentTypeName = getNewFragmentTypeName(name);
1037
- return [
1038
- declareExportOpaqueType(oldFragmentTypeName, 'FragmentReference'),
1039
- declareExportOpaqueType(newFragmentTypeName, oldFragmentTypeName),
1040
- ];
1041
- }
1042
-
1043
- function getFragmentTypes(name: string, refetchableQueryPath: ?string) {
1044
- const oldFragmentTypeName = getOldFragmentTypeName(name);
1045
- const newFragmentTypeName = getNewFragmentTypeName(name);
1046
- if (refetchableQueryPath) {
1047
- return [
1048
- importTypes(
1049
- [oldFragmentTypeName, newFragmentTypeName],
1050
- refetchableQueryPath,
1051
- ),
1052
- exportTypes([oldFragmentTypeName, newFragmentTypeName]),
1053
- ];
1054
- }
1055
- return [
1056
- declareExportOpaqueType(oldFragmentTypeName, 'FragmentReference'),
1057
- declareExportOpaqueType(newFragmentTypeName, oldFragmentTypeName),
1058
- ];
1059
- }
1060
-
1061
- function getOldFragmentTypeName(name: string) {
1062
- return `${name}$ref`;
1063
- }
1064
-
1065
- function getNewFragmentTypeName(name: string) {
1066
- return `${name}$fragmentType`;
1067
- }
1068
-
1069
- function getRefTypeName(name: string): string {
1070
- return `${name}$key`;
1071
- }
1072
-
1073
- function getDataTypeName(name: string): string {
1074
- return `${name}$data`;
1075
- }
1076
-
1077
- const FLOW_TRANSFORMS: $ReadOnlyArray<IRTransform> = [
1078
- RelayDirectiveTransform.transform,
1079
- MaskTransform.transform,
1080
- MatchTransform.transform,
1081
- RequiredFieldTransform.transform,
1082
- FlattenTransform.transformWithOptions({}),
1083
- RefetchableFragmentTransform.transform,
1084
- ];
1085
-
1086
- const DIRECTIVE_NAME = 'raw_response_type';
1087
-
1088
- module.exports = {
1089
- generate: (Profiler.instrument(generate, 'RelayFlowGenerator.generate'): (
1090
- schema: Schema,
1091
- node: Root | Fragment,
1092
- options: TypeGeneratorOptions,
1093
- ) => string),
1094
- transforms: FLOW_TRANSFORMS,
1095
- SCHEMA_EXTENSION: `directive @${DIRECTIVE_NAME} on QUERY | MUTATION | SUBSCRIPTION`,
1096
- };