relay-compiler 12.0.0 → 13.0.0-rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (259) 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 -26
  6. package/win-x64/relay.exe +0 -0
  7. package/bin/RelayCompilerBin.js.flow +0 -169
  8. package/bin/RelayCompilerMain.js.flow +0 -515
  9. package/bin/__fixtures__/plugin-module.js.flow +0 -17
  10. package/bin/relay-compiler +0 -19066
  11. package/codegen/CodegenDirectory.js.flow +0 -375
  12. package/codegen/CodegenRunner.js.flow +0 -432
  13. package/codegen/CodegenTypes.js.flow +0 -28
  14. package/codegen/CodegenWatcher.js.flow +0 -254
  15. package/codegen/NormalizationCodeGenerator.js.flow +0 -566
  16. package/codegen/ReaderCodeGenerator.js.flow +0 -512
  17. package/codegen/RelayCodeGenerator.js.flow +0 -85
  18. package/codegen/RelayFileWriter.js.flow +0 -367
  19. package/codegen/SourceControl.js.flow +0 -58
  20. package/codegen/compileRelayArtifacts.js.flow +0 -182
  21. package/codegen/createPrintRequireModuleDependency.js.flow +0 -19
  22. package/codegen/sortObjectByKey.js.flow +0 -25
  23. package/codegen/writeRelayGeneratedFile.js.flow +0 -239
  24. package/core/ASTCache.js.flow +0 -74
  25. package/core/ASTConvert.js.flow +0 -233
  26. package/core/CompilerContext.js.flow +0 -191
  27. package/core/CompilerError.js.flow +0 -255
  28. package/core/DotGraphQLParser.js.flow +0 -39
  29. package/core/GraphQLCompilerProfiler.js.flow +0 -341
  30. package/core/GraphQLDerivedFromMetadata.js.flow +0 -36
  31. package/core/GraphQLWatchmanClient.js.flow +0 -111
  32. package/core/IR.js.flow +0 -326
  33. package/core/IRPrinter.js.flow +0 -478
  34. package/core/IRTransformer.js.flow +0 -377
  35. package/core/IRValidator.js.flow +0 -260
  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 -119
  40. package/core/RelayGraphQLEnumsGenerator.js.flow +0 -55
  41. package/core/RelayIRTransforms.js.flow +0 -138
  42. package/core/RelayParser.js.flow +0 -1734
  43. package/core/RelaySourceModuleParser.js.flow +0 -135
  44. package/core/Schema.js.flow +0 -2037
  45. package/core/SchemaUtils.js.flow +0 -120
  46. package/core/filterContextForNode.js.flow +0 -50
  47. package/core/getFieldDefinition.js.flow +0 -156
  48. package/core/getIdentifierForArgumentValue.js.flow +0 -49
  49. package/core/getIdentifierForSelection.js.flow +0 -69
  50. package/core/getLiteralArgumentValues.js.flow +0 -32
  51. package/core/getNormalizationOperationName.js.flow +0 -19
  52. package/core/inferRootArgumentDefinitions.js.flow +0 -323
  53. package/index.js.flow +0 -200
  54. package/language/RelayLanguagePluginInterface.js.flow +0 -283
  55. package/language/javascript/FindGraphQLTags.js.flow +0 -137
  56. package/language/javascript/RelayFlowBabelFactories.js.flow +0 -176
  57. package/language/javascript/RelayFlowGenerator.js.flow +0 -1100
  58. package/language/javascript/RelayFlowTypeTransformers.js.flow +0 -184
  59. package/language/javascript/RelayLanguagePluginJavaScript.js.flow +0 -34
  60. package/language/javascript/formatGeneratedModule.js.flow +0 -65
  61. package/lib/bin/RelayCompilerBin.js +0 -143
  62. package/lib/bin/RelayCompilerMain.js +0 -486
  63. package/lib/bin/__fixtures__/plugin-module.js +0 -16
  64. package/lib/codegen/CodegenDirectory.js +0 -336
  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 -480
  69. package/lib/codegen/ReaderCodeGenerator.js +0 -472
  70. package/lib/codegen/RelayCodeGenerator.js +0 -68
  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 -208
  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 -251
  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 -389
  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 -149
  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 -1382
  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 -49
  100. package/lib/core/getFieldDefinition.js +0 -145
  101. package/lib/core/getIdentifierForArgumentValue.js +0 -53
  102. package/lib/core/getIdentifierForSelection.js +0 -48
  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 -14
  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 -857
  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 -261
  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/transforms/ApplyFragmentArgumentTransform.js +0 -393
  130. package/lib/transforms/ClientExtensionsTransform.js +0 -222
  131. package/lib/transforms/ConnectionTransform.js +0 -643
  132. package/lib/transforms/DeclarativeConnectionMutationTransform.js +0 -221
  133. package/lib/transforms/DeferStreamTransform.js +0 -247
  134. package/lib/transforms/DisallowIdAsAlias.js +0 -41
  135. package/lib/transforms/DisallowTypenameOnRoot.js +0 -53
  136. package/lib/transforms/FieldHandleTransform.js +0 -81
  137. package/lib/transforms/FilterCompilerDirectivesTransform.js +0 -29
  138. package/lib/transforms/FilterDirectivesTransform.js +0 -41
  139. package/lib/transforms/FlattenTransform.js +0 -308
  140. package/lib/transforms/GenerateIDFieldTransform.js +0 -137
  141. package/lib/transforms/GenerateTypeNameTransform.js +0 -155
  142. package/lib/transforms/InlineDataFragmentTransform.js +0 -104
  143. package/lib/transforms/InlineFragmentsTransform.js +0 -63
  144. package/lib/transforms/MaskTransform.js +0 -121
  145. package/lib/transforms/MatchTransform.js +0 -438
  146. package/lib/transforms/ReactFlightComponentTransform.js +0 -161
  147. package/lib/transforms/RefetchableFragmentTransform.js +0 -249
  148. package/lib/transforms/RelayDirectiveTransform.js +0 -85
  149. package/lib/transforms/RequiredFieldTransform.js +0 -373
  150. package/lib/transforms/SkipClientExtensionsTransform.js +0 -49
  151. package/lib/transforms/SkipHandleFieldTransform.js +0 -45
  152. package/lib/transforms/SkipRedundantNodesTransform.js +0 -255
  153. package/lib/transforms/SkipSplitOperationTransform.js +0 -32
  154. package/lib/transforms/SkipUnreachableNodeTransform.js +0 -158
  155. package/lib/transforms/SkipUnusedVariablesTransform.js +0 -74
  156. package/lib/transforms/SplitModuleImportTransform.js +0 -85
  157. package/lib/transforms/TestOperationTransform.js +0 -145
  158. package/lib/transforms/TransformUtils.js +0 -21
  159. package/lib/transforms/ValidateGlobalVariablesTransform.js +0 -91
  160. package/lib/transforms/ValidateRequiredArgumentsTransform.js +0 -118
  161. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +0 -111
  162. package/lib/transforms/ValidateUnusedVariablesTransform.js +0 -96
  163. package/lib/transforms/query-generators/FetchableQueryGenerator.js +0 -157
  164. package/lib/transforms/query-generators/NodeQueryGenerator.js +0 -166
  165. package/lib/transforms/query-generators/QueryQueryGenerator.js +0 -48
  166. package/lib/transforms/query-generators/ViewerQueryGenerator.js +0 -77
  167. package/lib/transforms/query-generators/index.js +0 -60
  168. package/lib/transforms/query-generators/utils.js +0 -92
  169. package/lib/util/CodeMarker.js +0 -80
  170. package/lib/util/DefaultHandleKey.js +0 -15
  171. package/lib/util/RelayCompilerCache.js +0 -98
  172. package/lib/util/Rollout.js +0 -40
  173. package/lib/util/TimeReporter.js +0 -83
  174. package/lib/util/areEqualArgValues.js +0 -135
  175. package/lib/util/argumentContainsVariables.js +0 -37
  176. package/lib/util/dedupeJSONStringify.js +0 -160
  177. package/lib/util/generateAbstractTypeRefinementKey.js +0 -24
  178. package/lib/util/getDefinitionNodeHash.js +0 -22
  179. package/lib/util/getModuleName.js +0 -32
  180. package/lib/util/joinArgumentDefinitions.js +0 -66
  181. package/lib/util/md5.js +0 -17
  182. package/lib/util/murmurHash.js +0 -86
  183. package/lib/util/nullthrowsOSS.js +0 -23
  184. package/lib/util/orList.js +0 -36
  185. package/lib/util/partitionArray.js +0 -35
  186. package/relay-compiler.js +0 -17
  187. package/relay-compiler.min.js +0 -22
  188. package/reporters/ConsoleReporter.js.flow +0 -81
  189. package/reporters/MultiReporter.js.flow +0 -43
  190. package/reporters/Reporter.js.flow +0 -19
  191. package/runner/Artifacts.js.flow +0 -219
  192. package/runner/BufferedFilesystem.js.flow +0 -194
  193. package/runner/GraphQLASTNodeGroup.js.flow +0 -176
  194. package/runner/GraphQLASTUtils.js.flow +0 -26
  195. package/runner/GraphQLNodeMap.js.flow +0 -55
  196. package/runner/Sources.js.flow +0 -228
  197. package/runner/StrictMap.js.flow +0 -96
  198. package/runner/compileArtifacts.js.flow +0 -76
  199. package/runner/extractAST.js.flow +0 -100
  200. package/runner/getChangedNodeNames.js.flow +0 -48
  201. package/runner/getSchemaInstance.js.flow +0 -36
  202. package/runner/types.js.flow +0 -37
  203. package/transforms/ApplyFragmentArgumentTransform.js.flow +0 -526
  204. package/transforms/ClientExtensionsTransform.js.flow +0 -226
  205. package/transforms/ConnectionTransform.js.flow +0 -859
  206. package/transforms/DeclarativeConnectionMutationTransform.js.flow +0 -250
  207. package/transforms/DeferStreamTransform.js.flow +0 -266
  208. package/transforms/DisallowIdAsAlias.js.flow +0 -48
  209. package/transforms/DisallowTypenameOnRoot.js.flow +0 -45
  210. package/transforms/FieldHandleTransform.js.flow +0 -81
  211. package/transforms/FilterCompilerDirectivesTransform.js.flow +0 -33
  212. package/transforms/FilterDirectivesTransform.js.flow +0 -45
  213. package/transforms/FlattenTransform.js.flow +0 -462
  214. package/transforms/GenerateIDFieldTransform.js.flow +0 -154
  215. package/transforms/GenerateTypeNameTransform.js.flow +0 -167
  216. package/transforms/InlineDataFragmentTransform.js.flow +0 -129
  217. package/transforms/InlineFragmentsTransform.js.flow +0 -73
  218. package/transforms/MaskTransform.js.flow +0 -130
  219. package/transforms/MatchTransform.js.flow +0 -593
  220. package/transforms/ReactFlightComponentTransform.js.flow +0 -198
  221. package/transforms/RefetchableFragmentTransform.js.flow +0 -272
  222. package/transforms/RelayDirectiveTransform.js.flow +0 -99
  223. package/transforms/RequiredFieldTransform.js.flow +0 -419
  224. package/transforms/SkipClientExtensionsTransform.js.flow +0 -57
  225. package/transforms/SkipHandleFieldTransform.js.flow +0 -45
  226. package/transforms/SkipRedundantNodesTransform.js.flow +0 -259
  227. package/transforms/SkipSplitOperationTransform.js.flow +0 -37
  228. package/transforms/SkipUnreachableNodeTransform.js.flow +0 -149
  229. package/transforms/SkipUnusedVariablesTransform.js.flow +0 -59
  230. package/transforms/SplitModuleImportTransform.js.flow +0 -101
  231. package/transforms/TestOperationTransform.js.flow +0 -143
  232. package/transforms/TransformUtils.js.flow +0 -26
  233. package/transforms/ValidateGlobalVariablesTransform.js.flow +0 -81
  234. package/transforms/ValidateRequiredArgumentsTransform.js.flow +0 -131
  235. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +0 -115
  236. package/transforms/ValidateUnusedVariablesTransform.js.flow +0 -89
  237. package/transforms/query-generators/FetchableQueryGenerator.js.flow +0 -189
  238. package/transforms/query-generators/NodeQueryGenerator.js.flow +0 -219
  239. package/transforms/query-generators/QueryQueryGenerator.js.flow +0 -57
  240. package/transforms/query-generators/ViewerQueryGenerator.js.flow +0 -97
  241. package/transforms/query-generators/index.js.flow +0 -90
  242. package/transforms/query-generators/utils.js.flow +0 -76
  243. package/util/CodeMarker.js.flow +0 -79
  244. package/util/DefaultHandleKey.js.flow +0 -17
  245. package/util/RelayCompilerCache.js.flow +0 -88
  246. package/util/Rollout.js.flow +0 -39
  247. package/util/TimeReporter.js.flow +0 -79
  248. package/util/areEqualArgValues.js.flow +0 -126
  249. package/util/argumentContainsVariables.js.flow +0 -38
  250. package/util/dedupeJSONStringify.js.flow +0 -152
  251. package/util/generateAbstractTypeRefinementKey.js.flow +0 -29
  252. package/util/getDefinitionNodeHash.js.flow +0 -25
  253. package/util/getModuleName.js.flow +0 -39
  254. package/util/joinArgumentDefinitions.js.flow +0 -105
  255. package/util/md5.js.flow +0 -22
  256. package/util/murmurHash.js.flow +0 -94
  257. package/util/nullthrowsOSS.js.flow +0 -25
  258. package/util/orList.js.flow +0 -37
  259. package/util/partitionArray.js.flow +0 -37
@@ -1,2037 +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 strict
8
- * @format
9
- * @emails oncall+relay
10
- */
11
-
12
- // flowlint ambiguous-object-type:error
13
-
14
- 'use strict';
15
-
16
- const {createCompilerError} = require('./CompilerError');
17
- const {isSchemaDefinitionAST} = require('./SchemaUtils');
18
- const {
19
- GraphQLFloat,
20
- GraphQLInt,
21
- GraphQLBoolean,
22
- GraphQLString,
23
- GraphQLID,
24
- parse,
25
- parseType,
26
- print,
27
- valueFromASTUntyped,
28
- } = require('graphql');
29
-
30
- import type {Field as IRField} from './IR';
31
- import type {
32
- DirectiveLocationEnum,
33
- DocumentNode,
34
- Source,
35
- TypeNode,
36
- ValueNode,
37
- ObjectTypeDefinitionNode,
38
- InterfaceTypeDefinitionNode,
39
- InputObjectTypeDefinitionNode,
40
- SchemaDefinitionNode,
41
- ScalarTypeDefinitionNode,
42
- EnumTypeDefinitionNode,
43
- UnionTypeDefinitionNode,
44
- DirectiveDefinitionNode,
45
- TypeSystemDefinitionNode,
46
- TypeSystemExtensionNode,
47
- ObjectTypeExtensionNode,
48
- InterfaceTypeExtensionNode,
49
- FieldDefinitionNode,
50
- } from 'graphql';
51
-
52
- type ExtensionNode =
53
- | TypeSystemDefinitionNode
54
- | TypeSystemExtensionNode
55
- | DirectiveDefinitionNode;
56
-
57
- export opaque type TypeID = BaseType | BaseList | BaseNonNull;
58
-
59
- type BaseType =
60
- | ScalarType
61
- | EnumType
62
- | UnionType
63
- | ObjectType
64
- | InputObjectType
65
- | InterfaceType;
66
-
67
- type BaseList = List<TypeID>;
68
- type BaseNonNull = NonNull<BaseType | BaseList>;
69
-
70
- export opaque type ScalarTypeID: ScalarFieldTypeID = ScalarType;
71
- export opaque type EnumTypeID: ScalarFieldTypeID = EnumType;
72
- export opaque type UnionTypeID: CompositeTypeID = UnionType;
73
- export opaque type InterfaceTypeID: CompositeTypeID = InterfaceType;
74
- export opaque type ObjectTypeID: CompositeTypeID = ObjectType;
75
- export opaque type InputObjectTypeID: TypeID = InputObjectType;
76
- export opaque type CompositeTypeID: LinkedFieldTypeID = CompositeType;
77
- export opaque type AbstractTypeID: CompositeTypeID = UnionType | InterfaceType;
78
-
79
- export opaque type ScalarFieldTypeID: TypeID =
80
- | ScalarFieldBaseType
81
- | ScalarFieldList
82
- | ScalarFieldNonNull;
83
-
84
- export opaque type LinkedFieldTypeID: TypeID =
85
- | LinkedFieldBaseType
86
- | LinkedFieldList
87
- | LinkedFieldNonNull;
88
-
89
- export opaque type InputTypeID: TypeID =
90
- | InputBaseType
91
- | InputTypeList
92
- | InputTypeNonNull;
93
-
94
- type ScalarFieldBaseType = ScalarType | EnumType;
95
- type ScalarFieldList = List<ScalarFieldTypeID>;
96
- type ScalarFieldNonNull = NonNull<ScalarFieldBaseType | ScalarFieldList>;
97
-
98
- type CompositeType = ObjectType | InterfaceType | UnionType;
99
- type LinkedFieldBaseType = CompositeType;
100
- type LinkedFieldList = List<LinkedFieldTypeID>;
101
- type LinkedFieldNonNull = NonNull<LinkedFieldBaseType | LinkedFieldList>;
102
-
103
- type InputBaseType = InputObjectType | ScalarType | EnumType;
104
- type InputTypeList = List<InputTypeID>;
105
- type InputTypeNonNull = NonNull<InputBaseType | InputTypeList>;
106
-
107
- type Fetchable = $ReadOnly<{|
108
- field_name: string,
109
- |}>;
110
-
111
- export opaque type FieldID = Field;
112
-
113
- export type Argument = $ReadOnly<{|
114
- name: string,
115
- type: InputTypeID,
116
- defaultValue: mixed,
117
- |}>;
118
-
119
- export type Directive = $ReadOnly<{|
120
- args: $ReadOnlyArray<Argument>,
121
- isClient: boolean,
122
- locations: $ReadOnlyArray<DirectiveLocationEnum>,
123
- name: string,
124
- |}>;
125
-
126
- type DirectiveMap = Map<string, Directive>;
127
-
128
- type InternalArgumentStruct = $ReadOnly<{|
129
- name: string,
130
- typeNode: TypeNode,
131
- defaultValue: ?ValueNode,
132
- |}>;
133
-
134
- type FieldDefinition = {|
135
- +arguments: $ReadOnlyArray<InternalArgumentStruct>,
136
- +directives: ?$ReadOnlyArray<DirectiveInvocation>,
137
- +type: TypeNode,
138
- +isClient: boolean,
139
- |};
140
-
141
- type DirectiveInvocation = {|
142
- +name: string,
143
- +args: $ReadOnlyArray<ArgumentValue>,
144
- |};
145
-
146
- type ArgumentValue = {|
147
- +name: string,
148
- +value: ValueNode,
149
- |};
150
-
151
- type InternalDirectiveMap = Map<string, InternalDirectiveStruct>;
152
-
153
- type InternalDirectiveStruct = $ReadOnly<{|
154
- name: string,
155
- isClient: boolean,
156
- locations: $ReadOnlyArray<DirectiveLocationEnum>,
157
- args: $ReadOnlyArray<InternalArgumentStruct>,
158
- |}>;
159
-
160
- export type {Schema};
161
-
162
- type FieldsMap = Map<string, Field>;
163
- type TypeMapKey = string | symbol;
164
-
165
- /**
166
- * @private
167
- */
168
- class Type {
169
- +name: string;
170
- +isClient: boolean;
171
- constructor(name: string, isClient: boolean) {
172
- this.name = name;
173
- this.isClient = isClient;
174
- }
175
- toString(): string {
176
- return this.name;
177
- }
178
- toJSON(): string {
179
- return String(this);
180
- }
181
- }
182
-
183
- /**
184
- * @private
185
- */
186
- class ScalarType extends Type {}
187
-
188
- /**
189
- * @private
190
- */
191
- class EnumType extends Type {
192
- +values: $ReadOnlyArray<string>;
193
- constructor(name: string, values: $ReadOnlyArray<string>, isClient: boolean) {
194
- super(name, isClient);
195
- this.values = values;
196
- }
197
- }
198
-
199
- /**
200
- * @private
201
- */
202
- class UnionType extends Type {}
203
-
204
- /**
205
- * @private
206
- */
207
- class ObjectType extends Type {}
208
- /**
209
- * @private
210
- */
211
- class InputObjectType extends Type {}
212
-
213
- /**
214
- * @private
215
- */
216
- class InterfaceType extends Type {}
217
-
218
- /**
219
- * @private
220
- */
221
- class List<+T> {
222
- +ofType: T;
223
- +_typeString: string;
224
-
225
- constructor(type: T) {
226
- this.ofType = type;
227
- this._typeString = `[${String(this.ofType)}]`;
228
- }
229
-
230
- toString(): string {
231
- return this._typeString;
232
- }
233
-
234
- toJSON(): string {
235
- return this.toString();
236
- }
237
- }
238
-
239
- /**
240
- * @private
241
- */
242
- class NonNull<+T> {
243
- +ofType: T;
244
- +_typeString: string;
245
-
246
- constructor(type: T) {
247
- this.ofType = type;
248
- this._typeString = `${String(this.ofType)}!`;
249
- }
250
-
251
- toString(): string {
252
- return this._typeString;
253
- }
254
-
255
- toJSON(): string {
256
- return this.toString();
257
- }
258
- }
259
-
260
- /**
261
- * @private
262
- */
263
- class Field {
264
- +args: $ReadOnlyMap<string, Argument>;
265
- +directives: ?$ReadOnlyArray<DirectiveInvocation>;
266
- +belongsTo: CompositeType | InputObjectType;
267
- +name: string;
268
- +type: TypeID;
269
- +isClient: boolean;
270
-
271
- constructor(
272
- schema: Schema,
273
- name: string,
274
- type: TypeID,
275
- belongsTo: CompositeType | InputObjectType,
276
- args: $ReadOnlyArray<InternalArgumentStruct>,
277
- directives: ?$ReadOnlyArray<DirectiveInvocation>,
278
- isClient: boolean,
279
- ) {
280
- this.name = name;
281
- this.type = type;
282
- this.belongsTo = belongsTo;
283
- this.isClient = isClient;
284
- this.args = parseInputArgumentDefinitionsMap(schema, args);
285
- this.directives = directives;
286
- }
287
- }
288
-
289
- /**
290
- * @private
291
- */
292
- function unwrap(type: TypeID): BaseType {
293
- if (type instanceof NonNull || type instanceof List) {
294
- return unwrap(type.ofType);
295
- }
296
- return type;
297
- }
298
-
299
- /**
300
- * @private
301
- */
302
- function hasConcreteTypeThatImplements(
303
- schema: Schema,
304
- type: TypeID,
305
- interfaceType: InterfaceTypeID,
306
- ): boolean {
307
- return (
308
- isAbstractType(type) &&
309
- getConcreteTypes(schema, type).some(concreteType =>
310
- schema.implementsInterface(
311
- schema.assertCompositeType(concreteType),
312
- interfaceType,
313
- ),
314
- )
315
- );
316
- }
317
-
318
- /**
319
- * @private
320
- */
321
- function getConcreteTypes(
322
- schema: Schema,
323
- type: AbstractTypeID,
324
- ): $ReadOnlyArray<ObjectTypeID> {
325
- const concreteTypes = new Set();
326
- schema.getPossibleTypes(type).forEach(possibleType => {
327
- if (isObject(possibleType)) {
328
- concreteTypes.add(possibleType);
329
- }
330
- });
331
- return Array.from(concreteTypes);
332
- }
333
-
334
- const TYPENAME_FIELD = '__typename';
335
- const CLIENT_ID_FIELD = '__id';
336
- const QUERY_TYPE_KEY = Symbol('Query');
337
- const MUTATION_TYPE_KEY = Symbol('Mutation');
338
- const SUBSCRIPTION_TYPE_KEY = Symbol('Subscription');
339
-
340
- function isScalar(type: mixed): boolean %checks {
341
- return type instanceof ScalarType;
342
- }
343
-
344
- function isObject(type: mixed): boolean %checks {
345
- return type instanceof ObjectType;
346
- }
347
-
348
- function isEnum(type: mixed): boolean %checks {
349
- return type instanceof EnumType;
350
- }
351
-
352
- function isUnion(type: mixed): boolean %checks {
353
- return type instanceof UnionType;
354
- }
355
-
356
- function isInputObject(type: mixed): boolean %checks {
357
- return type instanceof InputObjectType;
358
- }
359
-
360
- function isInterface(type: mixed): boolean %checks {
361
- return type instanceof InterfaceType;
362
- }
363
-
364
- function isWrapper(type: mixed): boolean %checks {
365
- return type instanceof List || type instanceof NonNull;
366
- }
367
-
368
- function isBaseType(type: mixed): boolean %checks {
369
- return (
370
- type instanceof ScalarType ||
371
- type instanceof ObjectType ||
372
- type instanceof EnumType ||
373
- type instanceof UnionType ||
374
- type instanceof InputObjectType ||
375
- type instanceof InterfaceType
376
- );
377
- }
378
-
379
- function isAbstractType(type: mixed): boolean %checks {
380
- return type instanceof UnionType || type instanceof InterfaceType;
381
- }
382
-
383
- function isCompositeType(type: mixed): boolean %checks {
384
- return (
385
- type instanceof ObjectType ||
386
- type instanceof UnionType ||
387
- type instanceof InterfaceType
388
- );
389
- }
390
-
391
- function isInputType(type: mixed): boolean %checks {
392
- return (
393
- type instanceof InputObjectType ||
394
- type instanceof ScalarType ||
395
- type instanceof EnumType
396
- );
397
- }
398
-
399
- class Schema {
400
- +_typeMap: TypeMap;
401
- +_directiveMap: DirectiveMap;
402
- +_fieldsMap: Map<Type, FieldsMap>;
403
- +_typeWrappersMap: Map<TypeMapKey, TypeID>;
404
- +_typeNameMap: Map<Type, Field>;
405
- +_clientIdMap: Map<Type, Field>;
406
-
407
- /**
408
- * @private
409
- */
410
- constructor(typeMap: TypeMap) {
411
- this._typeMap = typeMap;
412
- this._typeWrappersMap = new Map();
413
- this._fieldsMap = new Map();
414
- this._typeNameMap = new Map();
415
- this._clientIdMap = new Map();
416
- this._directiveMap = new Map(
417
- typeMap.getDirectives().map(directive => {
418
- return [
419
- directive.name,
420
- {
421
- locations: directive.locations,
422
- args: parseInputArgumentDefinitions(this, directive.args),
423
- name: directive.name,
424
- isClient: directive.isClient,
425
- },
426
- ];
427
- }),
428
- );
429
- }
430
-
431
- getTypes(): $ReadOnlyArray<TypeID> {
432
- return this._typeMap.getTypes();
433
- }
434
-
435
- getTypeFromAST(typeNode: TypeNode): ?TypeID {
436
- if (typeNode.kind === 'NonNullType') {
437
- const innerType = this.getTypeFromAST(typeNode.type);
438
- if (!innerType) {
439
- return;
440
- }
441
- if (innerType instanceof NonNull) {
442
- throw createCompilerError(
443
- 'Unable to wrap non-nullable type with non-null wrapper.',
444
- );
445
- }
446
- const cacheKey = `${this.getTypeString(innerType)}!`;
447
- let type = this._typeWrappersMap.get(cacheKey);
448
- if (type) {
449
- return type;
450
- }
451
- type = new NonNull(innerType);
452
- this._typeWrappersMap.set(cacheKey, type);
453
- return type;
454
- } else if (typeNode.kind === 'ListType') {
455
- const innerType = this.getTypeFromAST(typeNode.type);
456
- if (!innerType) {
457
- return;
458
- }
459
- const cacheKey = `[${this.getTypeString(innerType)}]`;
460
- let type = this._typeWrappersMap.get(cacheKey);
461
- if (type) {
462
- return type;
463
- }
464
- type = new List(innerType);
465
- this._typeWrappersMap.set(cacheKey, type);
466
- return type;
467
- }
468
- return this._typeMap.getTypeByName(typeNode.name.value);
469
- }
470
-
471
- _getRawType(typeName: TypeMapKey): ?TypeID {
472
- const type = this._typeWrappersMap.get(typeName);
473
- if (type) {
474
- return type;
475
- }
476
- if (typeof typeName === 'string') {
477
- return this.getTypeFromAST(parseType(typeName));
478
- } else {
479
- let operationType;
480
- if (typeName === QUERY_TYPE_KEY) {
481
- operationType = this._typeMap.getQueryType();
482
- } else if (typeName === MUTATION_TYPE_KEY) {
483
- operationType = this._typeMap.getMutationType();
484
- } else if (typeName === SUBSCRIPTION_TYPE_KEY) {
485
- operationType = this._typeMap.getSubscriptionType();
486
- }
487
- if (operationType instanceof ObjectType) {
488
- return operationType;
489
- }
490
- }
491
- }
492
-
493
- getTypeFromString(typeName: string): ?TypeID {
494
- return this._getRawType(typeName);
495
- }
496
-
497
- expectTypeFromString(typeName: string): TypeID {
498
- const type = this.getTypeFromString(typeName);
499
- if (type == null) {
500
- throw createCompilerError(`Unknown type: '${typeName}'.`);
501
- }
502
- return type;
503
- }
504
-
505
- expectTypeFromAST(ast: TypeNode): TypeID {
506
- const type = this.getTypeFromAST(ast);
507
- if (type == null) {
508
- throw createCompilerError(`Unknown type: '${print(ast)}'.`, null, [ast]);
509
- }
510
- return type;
511
- }
512
-
513
- getNonNullType(type: TypeID): TypeID {
514
- if (type instanceof NonNull) {
515
- return type;
516
- }
517
- const cacheKey = `${String(type)}!`;
518
- let nonNullType = this._typeWrappersMap.get(cacheKey);
519
- if (nonNullType) {
520
- return nonNullType;
521
- }
522
- nonNullType = new NonNull(type);
523
- this._typeWrappersMap.set(cacheKey, nonNullType);
524
- return nonNullType;
525
- }
526
-
527
- getRawType(type: TypeID): TypeID {
528
- return unwrap(type);
529
- }
530
-
531
- getNullableType(type: TypeID): TypeID {
532
- if (type instanceof NonNull) {
533
- return type.ofType;
534
- }
535
- return type;
536
- }
537
-
538
- getListItemType(type: TypeID): TypeID {
539
- if (type instanceof List) {
540
- return type.ofType;
541
- }
542
- return type;
543
- }
544
-
545
- mapListItemType(type: TypeID, mapper: (inner: TypeID) => TypeID): TypeID {
546
- if (!(type instanceof List)) {
547
- throw createCompilerError('Expected List type');
548
- }
549
- const innerType = mapper(type.ofType);
550
- const cacheKey = `[${this.getTypeString(innerType)}]`;
551
- let newType = this._typeWrappersMap.get(cacheKey);
552
- if (newType) {
553
- return newType;
554
- }
555
- newType = new List(innerType);
556
- this._typeWrappersMap.set(cacheKey, newType);
557
- return newType;
558
- }
559
-
560
- areEqualTypes(typeA: TypeID, typeB: TypeID): boolean {
561
- if (typeA === typeB) {
562
- return true;
563
- }
564
- if (typeA instanceof NonNull && typeB instanceof NonNull) {
565
- return this.areEqualTypes(typeA.ofType, typeB.ofType);
566
- }
567
- if (typeA instanceof List && typeB instanceof List) {
568
- return this.areEqualTypes(typeA.ofType, typeB.ofType);
569
- }
570
- if (isBaseType(typeA) && isBaseType(typeB)) {
571
- return typeA.name === typeB.name;
572
- }
573
- return false;
574
- }
575
-
576
- /**
577
- * Determine if the given type may implement the named type:
578
- * - it is the named type
579
- * - it implements the named interface
580
- * - it is an abstract type and *some* of its concrete types may
581
- * implement the named type
582
- */
583
- mayImplement(type: CompositeTypeID, interfaceType: InterfaceTypeID): boolean {
584
- return (
585
- this.areEqualTypes(type, interfaceType) ||
586
- this.implementsInterface(type, interfaceType) ||
587
- (this.isAbstractType(type) &&
588
- hasConcreteTypeThatImplements(this, type, interfaceType))
589
- );
590
- }
591
-
592
- implementsInterface(
593
- type: CompositeTypeID,
594
- interfaceType: InterfaceTypeID,
595
- ): boolean {
596
- return this.getInterfaces(type).some(typeInterface =>
597
- this.areEqualTypes(typeInterface, interfaceType),
598
- );
599
- }
600
-
601
- canHaveSelections(type: TypeID): boolean {
602
- return this.isObject(type) || this.isInterface(type);
603
- }
604
-
605
- getTypeString(type: TypeID): string {
606
- return type.toString();
607
- }
608
-
609
- isTypeSubTypeOf(maybeSubType: TypeID, superType: TypeID): boolean {
610
- // Equivalent type is a valid subtype
611
- if (maybeSubType === superType) {
612
- return true;
613
- }
614
-
615
- // If superType is non-null, maybeSubType must also be non-null.
616
- if (superType instanceof NonNull) {
617
- if (maybeSubType instanceof NonNull) {
618
- return this.isTypeSubTypeOf(maybeSubType.ofType, superType.ofType);
619
- }
620
- return false;
621
- }
622
- if (maybeSubType instanceof NonNull) {
623
- // If superType is nullable, maybeSubType may be non-null or nullable.
624
- return this.isTypeSubTypeOf(maybeSubType.ofType, superType);
625
- }
626
-
627
- // If superType type is a list, maybeSubType type must also be a list.
628
- if (superType instanceof List) {
629
- if (maybeSubType instanceof List) {
630
- return this.isTypeSubTypeOf(maybeSubType.ofType, superType.ofType);
631
- }
632
- return false;
633
- }
634
- if (maybeSubType instanceof List) {
635
- // If superType is not a list, maybeSubType must also be not a list.
636
- return false;
637
- }
638
-
639
- // If superType type is an abstract type, maybeSubType type may be a currently
640
- // possible object type.
641
- if (
642
- this.isAbstractType(superType) &&
643
- this.isObject(maybeSubType) &&
644
- this.isPossibleType(
645
- this.assertAbstractType(superType),
646
- this.assertObjectType(maybeSubType),
647
- )
648
- ) {
649
- return true;
650
- }
651
-
652
- // Otherwise, maybeSubType is not a valid subtype of the superType.
653
- return false;
654
- }
655
-
656
- /**
657
- * Provided two composite types, determine if they "overlap". Two composite
658
- * types overlap when the Sets of possible concrete types for each intersect.
659
- *
660
- * This is often used to determine if a fragment of a given type could possibly
661
- * be visited in a context of another type.
662
- *
663
- * This function is commutative.
664
- */
665
- doTypesOverlap(typeA: CompositeTypeID, typeB: CompositeTypeID): boolean {
666
- // Equivalent types overlap
667
- if (typeA === typeB) {
668
- return true;
669
- }
670
-
671
- if (isAbstractType(typeA)) {
672
- if (isAbstractType(typeB)) {
673
- // If both types are abstract, then determine if there is any intersection
674
- // between possible concrete types of each.
675
- return Array.from(this.getPossibleTypes(typeA)).some(type => {
676
- if (isObject(type)) {
677
- return this.isPossibleType(typeB, type);
678
- }
679
- });
680
- }
681
- // Determine if the latter type is a possible concrete type of the former.
682
- return this.isPossibleType(typeA, typeB);
683
- }
684
-
685
- if (isAbstractType(typeB)) {
686
- // Determine if the former type is a possible concrete type of the latter.
687
- return this.isPossibleType(typeB, typeA);
688
- }
689
-
690
- // Otherwise the types do not overlap.
691
- return false;
692
- }
693
-
694
- isPossibleType(
695
- superType: AbstractTypeID,
696
- maybeSubType: ObjectTypeID,
697
- ): boolean {
698
- return this._typeMap.getPossibleTypeSet(superType).has(maybeSubType);
699
- }
700
-
701
- assertScalarFieldType(type: mixed): ScalarFieldTypeID {
702
- // Scalar type fields can be wrappers / or can be scalars/enums
703
- if (
704
- (isWrapper(type) && !isScalar(unwrap(type)) && !isEnum(unwrap(type))) ||
705
- (!isWrapper(type) && !isScalar(type) && !isEnum(type))
706
- ) {
707
- throw createCompilerError(
708
- `Expected ${String(type)} to be a Scalar or Enum type.`,
709
- );
710
- }
711
- return type;
712
- }
713
-
714
- assertLinkedFieldType(type: mixed): LinkedFieldTypeID {
715
- // Linked Field types can be wrappers / or can be composite types
716
- if (
717
- (isWrapper(type) && !isCompositeType(unwrap(type))) ||
718
- (!isWrapper(type) && !isCompositeType(type))
719
- ) {
720
- throw createCompilerError(
721
- `Expected ${String(type)} to be a Object, Interface or a Union Type.`,
722
- );
723
- }
724
- return type;
725
- }
726
-
727
- assertInputType(type: mixed): InputTypeID {
728
- // Input type fields can be wrappers / or can be scalars/enums
729
- if (
730
- (isWrapper(type) && !isInputType(unwrap(type))) ||
731
- (!isWrapper(type) && !isInputType(type))
732
- ) {
733
- throw createCompilerError(
734
- `Expected ${String(type)} to be a Input, Scalar or Enum type.`,
735
- );
736
- }
737
- return type;
738
- }
739
-
740
- asCompositeType(type: mixed): ?CompositeTypeID {
741
- if (isCompositeType(type)) {
742
- return type;
743
- }
744
- }
745
-
746
- asInputType(type: mixed): ?InputTypeID {
747
- if (
748
- (isWrapper(type) && isInputType(unwrap(type))) ||
749
- (!isWrapper(type) && isInputType(type))
750
- ) {
751
- return type;
752
- }
753
- }
754
-
755
- asScalarFieldType(type: mixed): ?ScalarFieldTypeID {
756
- if (isScalar(type) || isEnum(type)) {
757
- return type;
758
- }
759
- }
760
-
761
- assertScalarType(type: TypeID): ScalarTypeID {
762
- if (!isScalar(type)) {
763
- throw createCompilerError(
764
- `Expected ${this.getTypeString(
765
- type,
766
- )} to be a scalar type, got ${this.getTypeString(type)}.`,
767
- );
768
- }
769
- return type;
770
- }
771
-
772
- assertObjectType(type: TypeID): ObjectTypeID {
773
- if (!isObject(type)) {
774
- throw createCompilerError(
775
- `Expected ${this.getTypeString(type)} to be an object type.`,
776
- );
777
- }
778
- return type;
779
- }
780
-
781
- assertInputObjectType(type: TypeID): InputObjectTypeID {
782
- if (!isInputObject(type)) {
783
- throw createCompilerError(
784
- `Expected ${this.getTypeString(type)} to be an input type.`,
785
- );
786
- }
787
- return type;
788
- }
789
-
790
- asInputObjectType(type: TypeID): ?InputObjectTypeID {
791
- if (!isInputObject(type)) {
792
- return null;
793
- }
794
- return type;
795
- }
796
-
797
- assertInterfaceType(type: TypeID): InterfaceTypeID {
798
- if (!isInterface(type)) {
799
- throw createCompilerError(
800
- `Expected ${this.getTypeString(type)} to be an interface type.`,
801
- );
802
- }
803
- return type;
804
- }
805
-
806
- assertCompositeType(type: TypeID): CompositeTypeID {
807
- if (!isCompositeType(type)) {
808
- throw createCompilerError(
809
- `Expected ${this.getTypeString(type)} to be a composite type.`,
810
- );
811
- }
812
- return type;
813
- }
814
-
815
- assertAbstractType(type: TypeID): AbstractTypeID {
816
- if (!isAbstractType(type)) {
817
- throw createCompilerError(
818
- `Expected ${this.getTypeString(type)} to be an abstract type.`,
819
- );
820
- }
821
- return type;
822
- }
823
-
824
- assertLeafType(type: TypeID): TypeID {
825
- if (!this.isLeafType(type)) {
826
- throw createCompilerError(
827
- `Expected ${this.getTypeString(type)} to be a leaf type.`,
828
- );
829
- }
830
- return type;
831
- }
832
-
833
- assertUnionType(type: TypeID): UnionTypeID {
834
- if (!isUnion(type)) {
835
- throw createCompilerError(
836
- `Expected ${this.getTypeString(type)} to be a union type.`,
837
- );
838
- }
839
- return type;
840
- }
841
-
842
- assertEnumType(type: TypeID): EnumTypeID {
843
- if (!isEnum(type)) {
844
- throw createCompilerError(`Expected ${String(type)} to be an enum type.`);
845
- }
846
- return type;
847
- }
848
-
849
- assertIntType(type: TypeID): ScalarTypeID {
850
- if (!isScalar(type) || !this.isInt(type)) {
851
- throw createCompilerError(
852
- `Expected ${String(type)} to be an 'Int' type.`,
853
- );
854
- }
855
- return type;
856
- }
857
-
858
- assertFloatType(type: TypeID): ScalarTypeID {
859
- if (!isScalar(type) || !this.isFloat(type)) {
860
- throw createCompilerError(
861
- `Expected ${this.getTypeString(type)} to be a 'Float' type.`,
862
- );
863
- }
864
- return type;
865
- }
866
-
867
- assertBooleanType(type: TypeID): ScalarTypeID {
868
- if (!isScalar(type) || !this.isBoolean(type)) {
869
- throw createCompilerError(
870
- `Expected ${this.getTypeString(type)} to be a 'Boolean' type.`,
871
- );
872
- }
873
- return type;
874
- }
875
-
876
- assertStringType(type: TypeID): ScalarTypeID {
877
- if (!isScalar(type) || !this.isString(type)) {
878
- throw createCompilerError(
879
- `Expected ${this.getTypeString(type)} to be a 'String' type.`,
880
- );
881
- }
882
- return type;
883
- }
884
-
885
- assertIdType(type: TypeID): ScalarTypeID {
886
- if (!isScalar(type) || !this.isId(type)) {
887
- throw createCompilerError(
888
- `Expected ${this.getTypeString(type)} to be an ID type.`,
889
- );
890
- }
891
- return type;
892
- }
893
-
894
- expectBooleanType(): ScalarTypeID {
895
- return this.assertScalarType(this.expectTypeFromString('Boolean'));
896
- }
897
-
898
- expectIntType(): ScalarTypeID {
899
- return this.assertScalarType(this.expectTypeFromString('Int'));
900
- }
901
-
902
- expectFloatType(): ScalarTypeID {
903
- return this.assertScalarType(this.expectTypeFromString('Float'));
904
- }
905
-
906
- expectStringType(): ScalarTypeID {
907
- return this.assertScalarType(this.expectTypeFromString('String'));
908
- }
909
-
910
- expectIdType(): ScalarTypeID {
911
- return this.assertScalarType(this.expectTypeFromString('ID'));
912
- }
913
-
914
- getQueryType(): ?ObjectTypeID {
915
- const queryType = this._getRawType(QUERY_TYPE_KEY);
916
- if (queryType && isObject(queryType)) {
917
- return queryType;
918
- }
919
- }
920
-
921
- getMutationType(): ?ObjectTypeID {
922
- const mutationType = this._getRawType(MUTATION_TYPE_KEY);
923
- if (mutationType && isObject(mutationType)) {
924
- return mutationType;
925
- }
926
- }
927
-
928
- getSubscriptionType(): ?ObjectTypeID {
929
- const subscriptionType = this._getRawType(SUBSCRIPTION_TYPE_KEY);
930
- if (subscriptionType && isObject(subscriptionType)) {
931
- return subscriptionType;
932
- }
933
- }
934
-
935
- expectQueryType(): ObjectTypeID {
936
- const queryType = this.getQueryType();
937
- if (queryType == null) {
938
- throw createCompilerError('Query type is not defined on the Schema');
939
- }
940
- return queryType;
941
- }
942
-
943
- expectMutationType(): ObjectTypeID {
944
- const mutationType = this.getMutationType();
945
- if (mutationType == null) {
946
- throw createCompilerError('Mutation type is not defined the Schema');
947
- }
948
- return mutationType;
949
- }
950
-
951
- expectSubscriptionType(): ObjectTypeID {
952
- const subscriptionType = this.getSubscriptionType();
953
- if (subscriptionType == null) {
954
- throw createCompilerError('Subscription type is not defined the Schema');
955
- }
956
- return subscriptionType;
957
- }
958
-
959
- isNonNull(type: TypeID): boolean {
960
- return type instanceof NonNull;
961
- }
962
-
963
- isList(type: TypeID): boolean {
964
- return type instanceof List;
965
- }
966
-
967
- isWrapper(type: TypeID): boolean {
968
- return isWrapper(type);
969
- }
970
-
971
- isScalar(type: TypeID): boolean {
972
- return isScalar(type);
973
- }
974
-
975
- isObject(type: TypeID): boolean {
976
- return isObject(type);
977
- }
978
-
979
- isEnum(type: TypeID): boolean {
980
- return isEnum(type);
981
- }
982
-
983
- isUnion(type: TypeID): boolean {
984
- return isUnion(type);
985
- }
986
-
987
- isInputObject(type: TypeID): boolean {
988
- return isInputObject(type);
989
- }
990
-
991
- isInterface(type: TypeID): boolean {
992
- return isInterface(type);
993
- }
994
-
995
- isInputType(type: TypeID): boolean {
996
- // Wrappers can be input types (so it's save to check unwrapped type here)
997
- return isInputType(type) || (isWrapper(type) && isInputType(unwrap(type)));
998
- }
999
-
1000
- isCompositeType(type: TypeID): boolean {
1001
- return isCompositeType(type);
1002
- }
1003
-
1004
- isAbstractType(type: TypeID): boolean {
1005
- return isAbstractType(type);
1006
- }
1007
-
1008
- isLeafType(type: TypeID): boolean {
1009
- return this.isScalar(type) || this.isEnum(type);
1010
- }
1011
-
1012
- isId(type: TypeID): boolean {
1013
- if (type instanceof ScalarType) {
1014
- return type.name === 'ID';
1015
- }
1016
- return false;
1017
- }
1018
-
1019
- isInt(type: TypeID): boolean {
1020
- if (type instanceof ScalarType) {
1021
- return type.name === 'Int';
1022
- }
1023
- return false;
1024
- }
1025
-
1026
- isFloat(type: TypeID): boolean {
1027
- if (type instanceof ScalarType) {
1028
- return type.name === 'Float';
1029
- }
1030
- return false;
1031
- }
1032
-
1033
- isBoolean(type: TypeID): boolean {
1034
- if (type instanceof ScalarType) {
1035
- return type.name === 'Boolean';
1036
- }
1037
- return false;
1038
- }
1039
-
1040
- isString(type: TypeID): boolean {
1041
- if (type instanceof ScalarType) {
1042
- return type.name === 'String';
1043
- }
1044
- return false;
1045
- }
1046
-
1047
- hasField(
1048
- type: CompositeTypeID | InputObjectTypeID,
1049
- fieldName: string,
1050
- ): boolean {
1051
- const canHaveTypename = this.isObject(type) || this.isAbstractType(type);
1052
- // Special case for __typename field
1053
- if (
1054
- canHaveTypename &&
1055
- (fieldName === TYPENAME_FIELD || fieldName === CLIENT_ID_FIELD)
1056
- ) {
1057
- return true;
1058
- }
1059
- if (type instanceof ObjectType || type instanceof InterfaceType) {
1060
- return this._typeMap.getField(type, fieldName) != null;
1061
- } else if (type instanceof InputObjectType) {
1062
- return this._typeMap.getInputField(type, fieldName) != null;
1063
- }
1064
- return false;
1065
- }
1066
-
1067
- hasId(type: CompositeTypeID): boolean {
1068
- if (!this.hasField(type, 'id')) {
1069
- return false;
1070
- }
1071
- const idField = this.expectField(type, 'id');
1072
- return this.areEqualTypes(
1073
- this.getNullableType(this.getFieldType(idField)),
1074
- this.expectIdType(),
1075
- );
1076
- }
1077
-
1078
- getFields(
1079
- type: CompositeTypeID | InputObjectTypeID,
1080
- ): $ReadOnlyArray<FieldID> {
1081
- const fieldsMap = this._getFieldsMap(type);
1082
- return Array.from(fieldsMap.values());
1083
- }
1084
-
1085
- _getFieldsMap(type: CompositeTypeID | InputObjectTypeID): FieldsMap {
1086
- const cachedMap = this._fieldsMap.get(type);
1087
- if (cachedMap != null) {
1088
- return cachedMap;
1089
- }
1090
-
1091
- const fieldsMap = new Map();
1092
- if (type instanceof ObjectType || type instanceof InterfaceType) {
1093
- const fields = this._typeMap.getFieldMap(type);
1094
- if (fields) {
1095
- for (const [fieldName, fieldDefinition] of fields) {
1096
- const fieldType = this.expectTypeFromAST(fieldDefinition.type);
1097
- fieldsMap.set(
1098
- fieldName,
1099
- new Field(
1100
- this,
1101
- fieldName,
1102
- fieldType,
1103
- this.assertCompositeType(type),
1104
- fieldDefinition.arguments,
1105
- fieldDefinition.directives,
1106
- fieldDefinition.isClient,
1107
- ),
1108
- );
1109
- }
1110
- }
1111
- } else if (type instanceof InputObjectType) {
1112
- const fields = this._typeMap.getInputFieldMap(type);
1113
- if (fields) {
1114
- for (const [fieldName, typeNode] of fields) {
1115
- const fieldType = this.expectTypeFromAST(typeNode);
1116
- fieldsMap.set(
1117
- fieldName,
1118
- new Field(this, fieldName, fieldType, type, [], null, false),
1119
- );
1120
- }
1121
- }
1122
- }
1123
- if (fieldsMap.size === 0) {
1124
- throw createCompilerError(
1125
- `_getFieldsMap: Type '${type.name}' should have fields.`,
1126
- );
1127
- }
1128
- this._fieldsMap.set(type, fieldsMap);
1129
- return fieldsMap;
1130
- }
1131
-
1132
- getFieldByName(
1133
- type: CompositeTypeID | InputObjectTypeID,
1134
- fieldName: string,
1135
- ): ?FieldID {
1136
- if (!this.hasField(type, fieldName)) {
1137
- return;
1138
- }
1139
-
1140
- // A "special" case for __typename and __id fields - which should
1141
- // not be in the list of type fields, but should be fine to select
1142
- if (fieldName === TYPENAME_FIELD) {
1143
- let typename = this._typeNameMap.get(type);
1144
- if (!typename) {
1145
- typename = new Field(
1146
- this,
1147
- TYPENAME_FIELD,
1148
- this.getNonNullType(this.expectStringType()),
1149
- type,
1150
- [],
1151
- null,
1152
- false, // isClient === false
1153
- );
1154
- this._typeNameMap.set(type, typename);
1155
- }
1156
- return typename;
1157
- }
1158
-
1159
- if (fieldName === CLIENT_ID_FIELD) {
1160
- let clientId = this._clientIdMap.get(type);
1161
- if (!clientId) {
1162
- clientId = new Field(
1163
- this,
1164
- CLIENT_ID_FIELD,
1165
- this.getNonNullType(this.expectIdType()),
1166
- type,
1167
- [],
1168
- null,
1169
- true, // isClient === true
1170
- );
1171
- this._clientIdMap.set(type, clientId);
1172
- }
1173
- return clientId;
1174
- }
1175
-
1176
- if (isUnion(type)) {
1177
- throw createCompilerError(
1178
- `Unexpected union type '${this.getTypeString(
1179
- type,
1180
- )}' in the 'getFieldByName(...)'. Expected type with fields`,
1181
- );
1182
- }
1183
-
1184
- const fieldsMap = this._getFieldsMap(type);
1185
- return fieldsMap.get(fieldName);
1186
- }
1187
-
1188
- expectField(
1189
- type: CompositeTypeID | InputObjectTypeID,
1190
- fieldName: string,
1191
- ): FieldID {
1192
- const field = this.getFieldByName(type, fieldName);
1193
- if (!field) {
1194
- throw createCompilerError(
1195
- `Unknown field '${fieldName}' on type '${this.getTypeString(type)}'.`,
1196
- );
1197
- }
1198
- return field;
1199
- }
1200
-
1201
- getFieldConfig(
1202
- field: FieldID,
1203
- ): {|
1204
- type: TypeID,
1205
- args: $ReadOnlyArray<Argument>,
1206
- |} {
1207
- return {
1208
- type: field.type,
1209
- args: Array.from(field.args.values()),
1210
- };
1211
- }
1212
-
1213
- getFieldName(field: FieldID): string {
1214
- return field.name;
1215
- }
1216
-
1217
- getFieldType(field: FieldID): TypeID {
1218
- return field.type;
1219
- }
1220
-
1221
- getFieldParentType(field: FieldID): TypeID {
1222
- return field.belongsTo;
1223
- }
1224
-
1225
- getFieldArgs(field: FieldID): $ReadOnlyArray<Argument> {
1226
- return Array.from(field.args.values());
1227
- }
1228
-
1229
- getFieldArgByName(field: FieldID, argName: string): ?Argument {
1230
- return field.args.get(argName);
1231
- }
1232
-
1233
- getEnumValues(type: EnumTypeID): $ReadOnlyArray<string> {
1234
- return type.values;
1235
- }
1236
-
1237
- getUnionTypes(type: UnionTypeID): $ReadOnlyArray<TypeID> {
1238
- return Array.from(this._typeMap.getPossibleTypeSet(type));
1239
- }
1240
-
1241
- getInterfaces(type: CompositeTypeID): $ReadOnlyArray<TypeID> {
1242
- if (type instanceof ObjectType) {
1243
- return this._typeMap.getInterfaces(type);
1244
- }
1245
- return [];
1246
- }
1247
-
1248
- getPossibleTypes(type: AbstractTypeID): $ReadOnlySet<ObjectTypeID> {
1249
- return this._typeMap.getPossibleTypeSet(type);
1250
- }
1251
-
1252
- getFetchableFieldName(type: ObjectTypeID): ?string {
1253
- return this._typeMap.getFetchableFieldName(type);
1254
- }
1255
-
1256
- parseLiteral(type: ScalarTypeID | EnumTypeID, valueNode: ValueNode): mixed {
1257
- if (type instanceof EnumType && valueNode.kind === 'EnumValue') {
1258
- return this.parseValue(type, valueNode.value);
1259
- } else if (type instanceof ScalarType) {
1260
- if (valueNode.kind === 'BooleanValue' && type.name === 'Boolean') {
1261
- return GraphQLBoolean.parseLiteral(valueNode);
1262
- } else if (valueNode.kind === 'FloatValue' && type.name === 'Float') {
1263
- return GraphQLFloat.parseLiteral(valueNode);
1264
- } else if (
1265
- valueNode.kind === 'IntValue' &&
1266
- (type.name === 'Int' || type.name === 'ID' || type.name === 'Float')
1267
- ) {
1268
- return GraphQLInt.parseLiteral(valueNode);
1269
- } else if (
1270
- valueNode.kind === 'StringValue' &&
1271
- (type.name === 'String' || type.name === 'ID')
1272
- ) {
1273
- return GraphQLString.parseLiteral(valueNode);
1274
- } else if (!isDefaultScalar(type.name)) {
1275
- return valueFromASTUntyped(valueNode);
1276
- }
1277
- }
1278
- }
1279
-
1280
- parseValue(type: ScalarTypeID | EnumTypeID, value: mixed): mixed {
1281
- if (type instanceof EnumType) {
1282
- return type.values.includes(value) ? value : undefined;
1283
- } else if (type instanceof ScalarType) {
1284
- switch (type.name) {
1285
- case 'Boolean':
1286
- return GraphQLBoolean.parseValue(value);
1287
- case 'Float':
1288
- return GraphQLFloat.parseValue(value);
1289
- case 'Int':
1290
- return GraphQLInt.parseValue(value);
1291
- case 'String':
1292
- return GraphQLString.parseValue(value);
1293
- case 'ID':
1294
- return GraphQLID.parseValue(value);
1295
- default:
1296
- return value;
1297
- }
1298
- }
1299
- }
1300
-
1301
- serialize(type: ScalarTypeID | EnumTypeID, value: mixed): mixed {
1302
- if (type instanceof EnumType) {
1303
- return type.values.includes(value) ? value : undefined;
1304
- } else if (type instanceof ScalarType) {
1305
- switch (type.name) {
1306
- case 'Boolean':
1307
- return GraphQLBoolean.serialize(value);
1308
- case 'Float':
1309
- return GraphQLFloat.serialize(value);
1310
- case 'Int':
1311
- return GraphQLInt.serialize(value);
1312
- case 'String':
1313
- return GraphQLString.serialize(value);
1314
- case 'ID':
1315
- return GraphQLID.serialize(value);
1316
- default:
1317
- return value;
1318
- }
1319
- }
1320
- }
1321
-
1322
- getDirectives(): $ReadOnlyArray<Directive> {
1323
- return Array.from(this._directiveMap.values());
1324
- }
1325
-
1326
- getDirective(directiveName: string): ?Directive {
1327
- return this._directiveMap.get(directiveName);
1328
- }
1329
-
1330
- isServerType(type: TypeID): boolean {
1331
- const unwrapped = unwrap(type);
1332
- return unwrapped.isClient === false;
1333
- }
1334
-
1335
- isServerField(field: FieldID): boolean {
1336
- return field.isClient === false;
1337
- }
1338
-
1339
- isServerDirective(directiveName: string): boolean {
1340
- const directive = this._directiveMap.get(directiveName);
1341
- return directive?.isClient === false;
1342
- }
1343
-
1344
- isServerDefinedField(type: CompositeTypeID, field: IRField): boolean {
1345
- return (
1346
- (this.isAbstractType(type) &&
1347
- field.directives.some(({name}) => name === 'fixme_fat_interface')) ||
1348
- (this.hasField(type, field.name) &&
1349
- this.isServerField(this.expectField(type, field.name)))
1350
- );
1351
- }
1352
-
1353
- isClientDefinedField(type: CompositeTypeID, field: IRField): boolean {
1354
- return !this.isServerDefinedField(type, field);
1355
- }
1356
-
1357
- extend(extensions: DocumentNode | $ReadOnlyArray<string>): Schema {
1358
- const doc = Array.isArray(extensions)
1359
- ? parse(extensions.join('\n'))
1360
- : extensions;
1361
-
1362
- const schemaExtensions = [];
1363
- doc.definitions.forEach(definition => {
1364
- if (isSchemaDefinitionAST(definition)) {
1365
- schemaExtensions.push(definition);
1366
- }
1367
- });
1368
- if (schemaExtensions.length > 0) {
1369
- return new Schema(this._typeMap.extend(schemaExtensions));
1370
- }
1371
- return this;
1372
- }
1373
- }
1374
-
1375
- class TypeMap {
1376
- _mutationTypeName: string;
1377
- _queryTypeName: string;
1378
- _subscriptionTypeName: string;
1379
- +_directives: InternalDirectiveMap;
1380
- +_extensions: $ReadOnlyArray<ExtensionNode>;
1381
- +_fetchable: Map<TypeID, Fetchable>;
1382
- +_fields: Map<InterfaceType | ObjectType, Map<string, FieldDefinition>>;
1383
- +_inputFields: Map<InputObjectType, Map<string, TypeNode>>;
1384
- +_interfaceImplementations: Map<InterfaceType, Set<ObjectType>>;
1385
- +_source: Source;
1386
- +_typeInterfaces: Map<TypeID, $ReadOnlyArray<InterfaceType>>;
1387
- +_types: Map<string, BaseType>;
1388
- +_unionTypes: Map<TypeID, Set<ObjectType>>;
1389
-
1390
- constructor(source: Source, extensions: $ReadOnlyArray<ExtensionNode>) {
1391
- this._types = new Map([
1392
- ['ID', new ScalarType('ID', false)],
1393
- ['String', new ScalarType('String', false)],
1394
- ['Boolean', new ScalarType('Boolean', false)],
1395
- ['Float', new ScalarType('Float', false)],
1396
- ['Int', new ScalarType('Int', false)],
1397
- ]);
1398
- this._typeInterfaces = new Map();
1399
- this._unionTypes = new Map();
1400
- this._interfaceImplementations = new Map();
1401
- this._fields = new Map();
1402
- this._inputFields = new Map();
1403
- this._directives = new Map([
1404
- [
1405
- 'include',
1406
- {
1407
- name: 'include',
1408
- isClient: false,
1409
- locations: ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'],
1410
- args: [
1411
- {
1412
- name: 'if',
1413
- typeNode: parseType('Boolean!'),
1414
- defaultValue: undefined,
1415
- },
1416
- ],
1417
- },
1418
- ],
1419
- [
1420
- 'skip',
1421
- {
1422
- name: 'skip',
1423
- isClient: false,
1424
- locations: ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'],
1425
- args: [
1426
- {
1427
- name: 'if',
1428
- typeNode: parseType('Boolean!'),
1429
- defaultValue: undefined,
1430
- },
1431
- ],
1432
- },
1433
- ],
1434
- [
1435
- 'deprecated',
1436
- {
1437
- name: 'deprecated',
1438
- isClient: false,
1439
- locations: ['FIELD_DEFINITION', 'ENUM_VALUE'],
1440
- args: [
1441
- {
1442
- name: 'reason',
1443
- typeNode: parseType('String'),
1444
- defaultValue: {
1445
- kind: 'StringValue',
1446
- value: 'No longer supported',
1447
- },
1448
- },
1449
- ],
1450
- },
1451
- ],
1452
- ]);
1453
- this._queryTypeName = 'Query';
1454
- this._mutationTypeName = 'Mutation';
1455
- this._subscriptionTypeName = 'Subscription';
1456
- this._source = source;
1457
- this._extensions = extensions;
1458
- this._fetchable = new Map();
1459
- this._parse(source);
1460
- this._extend(extensions);
1461
- }
1462
-
1463
- _parse(source: Source) {
1464
- const document = parse(source, {
1465
- noLocation: true,
1466
- });
1467
- document.definitions.forEach(definition => {
1468
- switch (definition.kind) {
1469
- case 'SchemaDefinition': {
1470
- this._parseSchemaDefinition(definition);
1471
- break;
1472
- }
1473
- case 'ScalarTypeDefinition': {
1474
- this._parseScalarNode(definition, false);
1475
- break;
1476
- }
1477
- case 'EnumTypeDefinition': {
1478
- this._parseEnumNode(definition, false);
1479
- break;
1480
- }
1481
- case 'ObjectTypeDefinition': {
1482
- this._parseObjectTypeNode(definition, false);
1483
- break;
1484
- }
1485
- case 'InputObjectTypeDefinition': {
1486
- this._parseInputObjectTypeNode(definition, false);
1487
- break;
1488
- }
1489
- case 'UnionTypeDefinition': {
1490
- this._parseUnionNode(definition, false);
1491
- break;
1492
- }
1493
- case 'InterfaceTypeDefinition': {
1494
- this._parseInterfaceNode(definition, false);
1495
- break;
1496
- }
1497
- case 'DirectiveDefinition': {
1498
- this._parseDirective(definition, false);
1499
- break;
1500
- }
1501
- }
1502
- });
1503
- }
1504
-
1505
- _parseSchemaDefinition(node: SchemaDefinitionNode) {
1506
- node.operationTypes.forEach(operationType => {
1507
- switch (operationType.operation) {
1508
- case 'query':
1509
- this._queryTypeName = operationType.type.name.value;
1510
- break;
1511
- case 'mutation':
1512
- this._mutationTypeName = operationType.type.name.value;
1513
- break;
1514
- case 'subscription':
1515
- this._subscriptionTypeName = operationType.type.name.value;
1516
- break;
1517
- }
1518
- });
1519
- }
1520
-
1521
- _parseScalarNode(node: ScalarTypeDefinitionNode, isClient: boolean) {
1522
- const name = node.name.value;
1523
- if (!isDefaultScalar(name) && this._types.has(name)) {
1524
- throw createCompilerError(
1525
- `_parseScalarNode: Duplicate definition for type ${name}.`,
1526
- null,
1527
- [node],
1528
- );
1529
- }
1530
- this._types.set(name, new ScalarType(name, isClient));
1531
- }
1532
-
1533
- _parseEnumNode(node: EnumTypeDefinitionNode, isClient: boolean) {
1534
- const name = node.name.value;
1535
- if (this._types.has(name)) {
1536
- throw createCompilerError(
1537
- `_parseEnumNode: Duplicate definition for type ${name}.`,
1538
- null,
1539
- [node],
1540
- );
1541
- }
1542
- // SDL doesn't have information about the actual ENUM values
1543
- const values = node.values
1544
- ? node.values.map(value => value.name.value)
1545
- : [];
1546
- this._types.set(name, new EnumType(name, values, isClient));
1547
- }
1548
-
1549
- _parseObjectTypeNode(node: ObjectTypeDefinitionNode, isClient: boolean) {
1550
- const name = node.name.value;
1551
- // Objects may be created by _parseUnionNode
1552
- const type = this._types.get(name) ?? new ObjectType(name, isClient);
1553
- if (!(type instanceof ObjectType)) {
1554
- throw createCompilerError(
1555
- `_parseObjectTypeNode: Expected object type, got ${String(type)}`,
1556
- null,
1557
- [node],
1558
- );
1559
- }
1560
- if (type.isClient !== isClient) {
1561
- throw createCompilerError(
1562
- `_parseObjectTypeNode: Cannot create object type '${name}' defined as a client type.`,
1563
- null,
1564
- [node],
1565
- );
1566
- }
1567
- const typeInterfaces: Array<InterfaceType> = [];
1568
- node.interfaces &&
1569
- node.interfaces.forEach(interfaceTypeNode => {
1570
- const interfaceName = interfaceTypeNode.name.value;
1571
- let interfaceType = this._types.get(interfaceName);
1572
- if (!interfaceType) {
1573
- interfaceType = new InterfaceType(interfaceName, isClient);
1574
- this._types.set(interfaceName, interfaceType);
1575
- }
1576
- if (!(interfaceType instanceof InterfaceType)) {
1577
- throw createCompilerError(
1578
- '_parseObjectTypeNode: Expected interface type',
1579
- null,
1580
- [interfaceTypeNode],
1581
- );
1582
- }
1583
- const implementations =
1584
- this._interfaceImplementations.get(interfaceType) ?? new Set();
1585
-
1586
- implementations.add(type);
1587
- this._interfaceImplementations.set(interfaceType, implementations);
1588
- typeInterfaces.push(interfaceType);
1589
- });
1590
- let fetchable = null;
1591
- node.directives &&
1592
- node.directives.forEach(directiveNode => {
1593
- if (directiveNode.name.value === 'fetchable') {
1594
- const field_name_arg =
1595
- directiveNode.arguments &&
1596
- directiveNode.arguments.find(
1597
- arg => arg.name.value === 'field_name',
1598
- );
1599
- if (
1600
- field_name_arg != null &&
1601
- field_name_arg.value.kind === 'StringValue'
1602
- ) {
1603
- fetchable = {field_name: field_name_arg.value.value};
1604
- }
1605
- }
1606
- });
1607
- this._typeInterfaces.set(type, typeInterfaces);
1608
- this._types.set(name, type);
1609
- if (fetchable != null) {
1610
- this._fetchable.set(type, fetchable);
1611
- }
1612
- node.fields && this._handleTypeFieldsStrict(type, node.fields, isClient);
1613
- }
1614
-
1615
- _parseInputObjectTypeNode(
1616
- node: InputObjectTypeDefinitionNode,
1617
- isClient: boolean,
1618
- ) {
1619
- const name = node.name.value;
1620
- if (this._types.has(name)) {
1621
- throw createCompilerError(
1622
- '_parseInputObjectTypeNode: Unable to parse schema file. Duplicate definition for object type',
1623
- null,
1624
- [node],
1625
- );
1626
- }
1627
- const type = new InputObjectType(name, isClient);
1628
- this._types.set(name, type);
1629
- this._parseInputObjectFields(type, node);
1630
- }
1631
-
1632
- _parseUnionNode(node: UnionTypeDefinitionNode, isClient: boolean) {
1633
- const name = node.name.value;
1634
- if (this._types.has(name)) {
1635
- throw createCompilerError(
1636
- '_parseUnionNode: Unable to parse schema file. Duplicate definition for object type',
1637
- null,
1638
- [node],
1639
- );
1640
- }
1641
- const union = new UnionType(name, isClient);
1642
- this._types.set(name, union);
1643
- this._unionTypes.set(
1644
- union,
1645
- new Set(
1646
- node.types
1647
- ? node.types.map(typeInUnion => {
1648
- const typeInUnionName = typeInUnion.name.value;
1649
- const object =
1650
- this._types.get(typeInUnionName) ??
1651
- new ObjectType(typeInUnionName, false);
1652
- if (!(object instanceof ObjectType)) {
1653
- throw createCompilerError(
1654
- '_parseUnionNode: Expected object type',
1655
- null,
1656
- [typeInUnion],
1657
- );
1658
- }
1659
- this._types.set(typeInUnionName, object);
1660
- return object;
1661
- })
1662
- : [],
1663
- ),
1664
- );
1665
- }
1666
-
1667
- _parseInterfaceNode(node: InterfaceTypeDefinitionNode, isClient: boolean) {
1668
- const name = node.name.value;
1669
- let type = this._types.get(name);
1670
- if (!type) {
1671
- type = new InterfaceType(name, isClient);
1672
- this._types.set(name, type);
1673
- }
1674
- if (!(type instanceof InterfaceType)) {
1675
- throw createCompilerError(
1676
- `_parseInterfaceNode: Expected interface type. Got ${String(type)}`,
1677
- null,
1678
- [node],
1679
- );
1680
- }
1681
- if (type.isClient !== isClient) {
1682
- throw createCompilerError(
1683
- `_parseInterfaceNode: Cannot create interface '${name}' defined as a client interface`,
1684
- null,
1685
- [node],
1686
- );
1687
- }
1688
- node.fields && this._handleTypeFieldsStrict(type, node.fields, isClient);
1689
- }
1690
-
1691
- _handleTypeFieldsStrict(
1692
- type: ObjectType | InterfaceType,
1693
- fields: $ReadOnlyArray<FieldDefinitionNode>,
1694
- isClient: boolean,
1695
- ) {
1696
- if (this._fields.has(type)) {
1697
- throw createCompilerError(
1698
- '_handleTypeFieldsStrict: Unable to parse schema file. Duplicate definition for object type',
1699
- );
1700
- }
1701
- this._handleTypeFields(type, fields, isClient);
1702
- }
1703
-
1704
- _handleTypeFields(
1705
- type: ObjectType | InterfaceType,
1706
- fields: $ReadOnlyArray<FieldDefinitionNode>,
1707
- isClient: boolean,
1708
- ) {
1709
- const fieldsMap = this._fields.get(type) ?? new Map();
1710
- fields.forEach(fieldNode => {
1711
- const fieldName = fieldNode.name.value;
1712
- if (fieldsMap.has(fieldName)) {
1713
- throw createCompilerError(
1714
- `_handleTypeFields: Duplicate definition for field '${fieldName}'.`,
1715
- );
1716
- }
1717
- fieldsMap.set(fieldName, {
1718
- arguments: fieldNode.arguments
1719
- ? fieldNode.arguments.map(arg => {
1720
- return {
1721
- name: arg.name.value,
1722
- typeNode: arg.type,
1723
- defaultValue: arg.defaultValue,
1724
- };
1725
- })
1726
- : [],
1727
- directives: fieldNode.directives
1728
- ? fieldNode.directives.map(directive => {
1729
- return {
1730
- name: directive.name.value,
1731
- args: directive.arguments
1732
- ? directive.arguments.map(arg => {
1733
- return {
1734
- name: arg.name.value,
1735
- value: arg.value,
1736
- };
1737
- })
1738
- : [],
1739
- };
1740
- })
1741
- : null,
1742
- type: fieldNode.type,
1743
- isClient: isClient,
1744
- });
1745
- });
1746
- this._fields.set(type, fieldsMap);
1747
- }
1748
-
1749
- _parseInputObjectFields(
1750
- type: InputObjectType,
1751
- node: InputObjectTypeDefinitionNode,
1752
- ) {
1753
- if (this._inputFields.has(type)) {
1754
- throw createCompilerError(
1755
- '_parseInputObjectFields: Unable to parse schema file. Duplicate definition for type',
1756
- null,
1757
- [node],
1758
- );
1759
- }
1760
- const fields = new Map();
1761
- if (node.fields) {
1762
- node.fields.forEach(fieldNode => {
1763
- fields.set(fieldNode.name.value, fieldNode.type);
1764
- });
1765
- }
1766
- this._inputFields.set(type, fields);
1767
- }
1768
-
1769
- _parseDirective(node: DirectiveDefinitionNode, isClient: boolean) {
1770
- const name = node.name.value;
1771
- this._directives.set(name, {
1772
- name,
1773
- args: node.arguments
1774
- ? node.arguments.map(arg => {
1775
- return {
1776
- name: arg.name.value,
1777
- typeNode: arg.type,
1778
- defaultValue: arg.defaultValue,
1779
- };
1780
- })
1781
- : [],
1782
-
1783
- locations: node.locations.map(location => {
1784
- switch (location.value) {
1785
- case 'QUERY':
1786
- case 'MUTATION':
1787
- case 'SUBSCRIPTION':
1788
- case 'FIELD':
1789
- case 'FRAGMENT_DEFINITION':
1790
- case 'FRAGMENT_SPREAD':
1791
- case 'INLINE_FRAGMENT':
1792
- case 'VARIABLE_DEFINITION':
1793
- case 'SCHEMA':
1794
- case 'SCALAR':
1795
- case 'OBJECT':
1796
- case 'FIELD_DEFINITION':
1797
- case 'ARGUMENT_DEFINITION':
1798
- case 'INTERFACE':
1799
- case 'UNION':
1800
- case 'ENUM':
1801
- case 'ENUM_VALUE':
1802
- case 'INPUT_OBJECT':
1803
- case 'INPUT_FIELD_DEFINITION':
1804
- return location.value;
1805
- default:
1806
- throw createCompilerError('Invalid directive location');
1807
- }
1808
- }),
1809
- isClient,
1810
- });
1811
- }
1812
-
1813
- _parseObjectTypeExtension(node: ObjectTypeExtensionNode) {
1814
- const type = this._types.get(node.name.value);
1815
- if (!(type instanceof ObjectType)) {
1816
- throw createCompilerError(
1817
- `_parseObjectTypeExtension: Expected to find type with the name '${node.name.value}'`,
1818
- null,
1819
- [node],
1820
- );
1821
- }
1822
- node.fields &&
1823
- this._handleTypeFields(type, node.fields, true /** client fields */);
1824
- }
1825
-
1826
- _parseInterfaceTypeExtension(node: InterfaceTypeExtensionNode) {
1827
- const type = this._types.get(node.name.value);
1828
- if (!(type instanceof InterfaceType)) {
1829
- throw createCompilerError(
1830
- '_parseInterfaceTypeExtension: Expected to have an interface type',
1831
- );
1832
- }
1833
- node.fields && this._handleTypeFields(type, node.fields, true);
1834
- }
1835
-
1836
- _extend(extensions: $ReadOnlyArray<ExtensionNode>) {
1837
- extensions.forEach(definition => {
1838
- if (definition.kind === 'ObjectTypeDefinition') {
1839
- this._parseObjectTypeNode(definition, true);
1840
- } else if (definition.kind === 'InterfaceTypeDefinition') {
1841
- this._parseInterfaceNode(definition, true);
1842
- } else if (definition.kind === 'ScalarTypeDefinition') {
1843
- this._parseScalarNode(definition, true);
1844
- } else if (definition.kind === 'EnumTypeDefinition') {
1845
- this._parseEnumNode(definition, true);
1846
- } else if (definition.kind === 'InterfaceTypeExtension') {
1847
- this._parseInterfaceTypeExtension(definition);
1848
- } else if (definition.kind === 'ObjectTypeExtension') {
1849
- this._parseObjectTypeExtension(definition);
1850
- } else if (definition.kind === 'DirectiveDefinition') {
1851
- this._parseDirective(definition, true /* client directive */);
1852
- } else {
1853
- throw createCompilerError(
1854
- `Unexpected extension kind: '${definition.kind}'`,
1855
- null,
1856
- [definition],
1857
- );
1858
- }
1859
- });
1860
- }
1861
-
1862
- getTypes(): $ReadOnlyArray<BaseType> {
1863
- return Array.from(this._types.values());
1864
- }
1865
-
1866
- getTypeByName(typename: string): ?BaseType {
1867
- return this._types.get(typename);
1868
- }
1869
-
1870
- getInterfaces(type: ObjectType): $ReadOnlyArray<InterfaceType> {
1871
- return this._typeInterfaces.get(type) ?? [];
1872
- }
1873
-
1874
- getPossibleTypeSet(
1875
- type: UnionType | InterfaceType,
1876
- ): $ReadOnlySet<ObjectType> {
1877
- let set;
1878
- if (type instanceof InterfaceType) {
1879
- set = this._interfaceImplementations.get(type) ?? new Set();
1880
- } else if (type instanceof UnionType) {
1881
- set = this._unionTypes.get(type) ?? new Set();
1882
- } else {
1883
- throw createCompilerError(
1884
- 'Invalid type supplied to "getPossibleTypeSet"',
1885
- );
1886
- }
1887
- if (!set) {
1888
- throw createCompilerError(
1889
- `Unable to find possible types for ${type.name}`,
1890
- );
1891
- }
1892
- return set;
1893
- }
1894
-
1895
- getFetchableFieldName(type: ObjectTypeID): ?string {
1896
- return this._fetchable.get(type)?.field_name ?? null;
1897
- }
1898
-
1899
- getQueryType(): ?BaseType {
1900
- return this._types.get(this._queryTypeName);
1901
- }
1902
-
1903
- getMutationType(): ?BaseType {
1904
- return this._types.get(this._mutationTypeName);
1905
- }
1906
-
1907
- getSubscriptionType(): ?BaseType {
1908
- return this._types.get(this._subscriptionTypeName);
1909
- }
1910
-
1911
- getField(
1912
- type: InterfaceType | ObjectType,
1913
- fieldName: string,
1914
- ): ?FieldDefinition {
1915
- const fields = this._fields.get(type);
1916
- if (fields) {
1917
- return fields.get(fieldName);
1918
- }
1919
- }
1920
-
1921
- getFieldMap(type: InterfaceType | ObjectType): ?Map<string, FieldDefinition> {
1922
- return this._fields.get(type);
1923
- }
1924
-
1925
- getInputField(type: InputObjectType, fieldName: string): ?TypeNode {
1926
- const inputFields = this._inputFields.get(type);
1927
- if (inputFields) {
1928
- return inputFields.get(fieldName);
1929
- }
1930
- }
1931
-
1932
- getInputFieldMap(type: InputObjectType): ?Map<string, TypeNode> {
1933
- return this._inputFields.get(type);
1934
- }
1935
-
1936
- getDirectives(): $ReadOnlyArray<InternalDirectiveStruct> {
1937
- return Array.from(this._directives.values());
1938
- }
1939
-
1940
- extend(extensions: $ReadOnlyArray<ExtensionNode>): TypeMap {
1941
- return new TypeMap(this._source, this._extensions.concat(extensions));
1942
- }
1943
- }
1944
-
1945
- function create(
1946
- baseSchema: Source,
1947
- schemaExtensionDocuments?: $ReadOnlyArray<DocumentNode>,
1948
- schemaExtensions?: $ReadOnlyArray<string>,
1949
- ): Schema {
1950
- const extensions: Array<ExtensionNode> = [];
1951
- schemaExtensions &&
1952
- schemaExtensions.forEach(source => {
1953
- const doc = parse(source, {
1954
- noLocation: true,
1955
- });
1956
- doc.definitions.forEach(definition => {
1957
- if (isSchemaDefinitionAST(definition)) {
1958
- extensions.push(definition);
1959
- }
1960
- });
1961
- });
1962
- schemaExtensionDocuments &&
1963
- schemaExtensionDocuments.forEach(doc => {
1964
- doc.definitions.forEach(definition => {
1965
- if (isSchemaDefinitionAST(definition)) {
1966
- extensions.push(definition);
1967
- }
1968
- });
1969
- });
1970
-
1971
- return new Schema(new TypeMap(baseSchema, extensions));
1972
- }
1973
-
1974
- function parseInputArgumentDefinitions(
1975
- schema: Schema,
1976
- args: $ReadOnlyArray<InternalArgumentStruct>,
1977
- ): $ReadOnlyArray<Argument> {
1978
- return args.map(arg => {
1979
- const argType = schema.assertInputType(
1980
- schema.expectTypeFromAST(arg.typeNode),
1981
- );
1982
- let defaultValue;
1983
- const defaultValueNode = arg.defaultValue;
1984
- if (defaultValueNode != null) {
1985
- const nullableType = schema.getNullableType(argType);
1986
- const isNullable = schema.isNonNull(argType) === false;
1987
- if (isNullable && defaultValueNode.kind === 'NullValue') {
1988
- defaultValue = null;
1989
- } else {
1990
- if (
1991
- nullableType instanceof ScalarType ||
1992
- nullableType instanceof EnumType
1993
- ) {
1994
- defaultValue = schema.parseLiteral(nullableType, defaultValueNode);
1995
- } else if (
1996
- (nullableType instanceof List &&
1997
- defaultValueNode.kind === 'ListValue') ||
1998
- (nullableType instanceof InputObjectType &&
1999
- defaultValueNode.kind === 'ObjectValue')
2000
- ) {
2001
- defaultValue = valueFromASTUntyped(defaultValueNode);
2002
- }
2003
- }
2004
- if (defaultValue === undefined) {
2005
- throw createCompilerError(
2006
- `parseInputArgumentDefinitions: Unexpected default value: ${String(
2007
- defaultValueNode,
2008
- )}. Expected to have a value of type ${String(nullableType)}.`,
2009
- );
2010
- }
2011
- }
2012
- return {
2013
- name: arg.name,
2014
- type: argType,
2015
- defaultValue,
2016
- };
2017
- });
2018
- }
2019
-
2020
- function parseInputArgumentDefinitionsMap(
2021
- schema: Schema,
2022
- args: $ReadOnlyArray<InternalArgumentStruct>,
2023
- ): $ReadOnlyMap<string, Argument> {
2024
- return new Map(
2025
- parseInputArgumentDefinitions(schema, args).map(arg => {
2026
- return [arg.name, arg];
2027
- }),
2028
- );
2029
- }
2030
-
2031
- function isDefaultScalar(name: string): boolean {
2032
- return new Set(['ID', 'String', 'Boolean', 'Int', 'Float']).has(name);
2033
- }
2034
-
2035
- module.exports = {
2036
- create,
2037
- };