relay-compiler 0.0.0-main-bfcb5c59 → 0.0.0-main-4467ae84

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 -168
  8. package/bin/RelayCompilerMain.js.flow +0 -513
  9. package/bin/__fixtures__/plugin-module.js.flow +0 -17
  10. package/bin/relay-compiler +0 -19066
  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 -565
  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 -1731
  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 -486
  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/transforms/ApplyFragmentArgumentTransform.js +0 -393
  130. package/lib/transforms/ClientExtensionsTransform.js +0 -221
  131. package/lib/transforms/ConnectionTransform.js +0 -639
  132. package/lib/transforms/DeclarativeConnectionMutationTransform.js +0 -218
  133. package/lib/transforms/DeferStreamTransform.js +0 -246
  134. package/lib/transforms/DisallowIdAsAlias.js +0 -40
  135. package/lib/transforms/DisallowTypenameOnRoot.js +0 -53
  136. package/lib/transforms/FieldHandleTransform.js +0 -79
  137. package/lib/transforms/FilterCompilerDirectivesTransform.js +0 -29
  138. package/lib/transforms/FilterDirectivesTransform.js +0 -42
  139. package/lib/transforms/FlattenTransform.js +0 -306
  140. package/lib/transforms/GenerateIDFieldTransform.js +0 -135
  141. package/lib/transforms/GenerateTypeNameTransform.js +0 -149
  142. package/lib/transforms/InlineDataFragmentTransform.js +0 -100
  143. package/lib/transforms/InlineFragmentsTransform.js +0 -61
  144. package/lib/transforms/MaskTransform.js +0 -117
  145. package/lib/transforms/MatchTransform.js +0 -434
  146. package/lib/transforms/ReactFlightComponentTransform.js +0 -158
  147. package/lib/transforms/RefetchableFragmentTransform.js +0 -249
  148. package/lib/transforms/RelayDirectiveTransform.js +0 -83
  149. package/lib/transforms/RequiredFieldTransform.js +0 -369
  150. package/lib/transforms/SkipClientExtensionsTransform.js +0 -46
  151. package/lib/transforms/SkipHandleFieldTransform.js +0 -45
  152. package/lib/transforms/SkipRedundantNodesTransform.js +0 -261
  153. package/lib/transforms/SkipSplitOperationTransform.js +0 -32
  154. package/lib/transforms/SkipUnreachableNodeTransform.js +0 -158
  155. package/lib/transforms/SkipUnusedVariablesTransform.js +0 -75
  156. package/lib/transforms/SplitModuleImportTransform.js +0 -82
  157. package/lib/transforms/TestOperationTransform.js +0 -144
  158. package/lib/transforms/TransformUtils.js +0 -21
  159. package/lib/transforms/ValidateGlobalVariablesTransform.js +0 -92
  160. package/lib/transforms/ValidateRequiredArgumentsTransform.js +0 -114
  161. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +0 -108
  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 -97
  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 -67
  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 -215
  192. package/runner/BufferedFilesystem.js.flow +0 -194
  193. package/runner/GraphQLASTNodeGroup.js.flow +0 -174
  194. package/runner/GraphQLASTUtils.js.flow +0 -26
  195. package/runner/GraphQLNodeMap.js.flow +0 -55
  196. package/runner/Sources.js.flow +0 -227
  197. package/runner/StrictMap.js.flow +0 -96
  198. package/runner/compileArtifacts.js.flow +0 -75
  199. package/runner/extractAST.js.flow +0 -98
  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 -524
  204. package/transforms/ClientExtensionsTransform.js.flow +0 -224
  205. package/transforms/ConnectionTransform.js.flow +0 -850
  206. package/transforms/DeclarativeConnectionMutationTransform.js.flow +0 -245
  207. package/transforms/DeferStreamTransform.js.flow +0 -263
  208. package/transforms/DisallowIdAsAlias.js.flow +0 -46
  209. package/transforms/DisallowTypenameOnRoot.js.flow +0 -44
  210. package/transforms/FieldHandleTransform.js.flow +0 -77
  211. package/transforms/FilterCompilerDirectivesTransform.js.flow +0 -33
  212. package/transforms/FilterDirectivesTransform.js.flow +0 -45
  213. package/transforms/FlattenTransform.js.flow +0 -458
  214. package/transforms/GenerateIDFieldTransform.js.flow +0 -151
  215. package/transforms/GenerateTypeNameTransform.js.flow +0 -159
  216. package/transforms/InlineDataFragmentTransform.js.flow +0 -123
  217. package/transforms/InlineFragmentsTransform.js.flow +0 -70
  218. package/transforms/MaskTransform.js.flow +0 -124
  219. package/transforms/MatchTransform.js.flow +0 -587
  220. package/transforms/ReactFlightComponentTransform.js.flow +0 -194
  221. package/transforms/RefetchableFragmentTransform.js.flow +0 -266
  222. package/transforms/RelayDirectiveTransform.js.flow +0 -96
  223. package/transforms/RequiredFieldTransform.js.flow +0 -413
  224. package/transforms/SkipClientExtensionsTransform.js.flow +0 -54
  225. package/transforms/SkipHandleFieldTransform.js.flow +0 -44
  226. package/transforms/SkipRedundantNodesTransform.js.flow +0 -255
  227. package/transforms/SkipSplitOperationTransform.js.flow +0 -37
  228. package/transforms/SkipUnreachableNodeTransform.js.flow +0 -148
  229. package/transforms/SkipUnusedVariablesTransform.js.flow +0 -59
  230. package/transforms/SplitModuleImportTransform.js.flow +0 -97
  231. package/transforms/TestOperationTransform.js.flow +0 -142
  232. package/transforms/TransformUtils.js.flow +0 -26
  233. package/transforms/ValidateGlobalVariablesTransform.js.flow +0 -80
  234. package/transforms/ValidateRequiredArgumentsTransform.js.flow +0 -126
  235. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +0 -111
  236. package/transforms/ValidateUnusedVariablesTransform.js.flow +0 -88
  237. package/transforms/query-generators/FetchableQueryGenerator.js.flow +0 -188
  238. package/transforms/query-generators/NodeQueryGenerator.js.flow +0 -217
  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 -89
  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 -86
  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 -24
  253. package/util/getModuleName.js.flow +0 -39
  254. package/util/joinArgumentDefinitions.js.flow +0 -105
  255. package/util/md5.js.flow +0 -19
  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,2035 +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
- import type {Field as IRField} from './IR';
17
- import type {
18
- DirectiveDefinitionNode,
19
- DirectiveLocationEnum,
20
- DocumentNode,
21
- EnumTypeDefinitionNode,
22
- FieldDefinitionNode,
23
- InputObjectTypeDefinitionNode,
24
- InterfaceTypeDefinitionNode,
25
- InterfaceTypeExtensionNode,
26
- ObjectTypeDefinitionNode,
27
- ObjectTypeExtensionNode,
28
- ScalarTypeDefinitionNode,
29
- SchemaDefinitionNode,
30
- Source,
31
- TypeNode,
32
- TypeSystemDefinitionNode,
33
- TypeSystemExtensionNode,
34
- UnionTypeDefinitionNode,
35
- ValueNode,
36
- } from 'graphql';
37
-
38
- const {createCompilerError} = require('./CompilerError');
39
- const {isSchemaDefinitionAST} = require('./SchemaUtils');
40
- const {
41
- GraphQLBoolean,
42
- GraphQLFloat,
43
- GraphQLID,
44
- GraphQLInt,
45
- GraphQLString,
46
- parse,
47
- parseType,
48
- print,
49
- valueFromASTUntyped,
50
- } = require('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(field: FieldID): {|
1202
- type: TypeID,
1203
- args: $ReadOnlyArray<Argument>,
1204
- |} {
1205
- return {
1206
- type: field.type,
1207
- args: Array.from(field.args.values()),
1208
- };
1209
- }
1210
-
1211
- getFieldName(field: FieldID): string {
1212
- return field.name;
1213
- }
1214
-
1215
- getFieldType(field: FieldID): TypeID {
1216
- return field.type;
1217
- }
1218
-
1219
- getFieldParentType(field: FieldID): TypeID {
1220
- return field.belongsTo;
1221
- }
1222
-
1223
- getFieldArgs(field: FieldID): $ReadOnlyArray<Argument> {
1224
- return Array.from(field.args.values());
1225
- }
1226
-
1227
- getFieldArgByName(field: FieldID, argName: string): ?Argument {
1228
- return field.args.get(argName);
1229
- }
1230
-
1231
- getEnumValues(type: EnumTypeID): $ReadOnlyArray<string> {
1232
- return type.values;
1233
- }
1234
-
1235
- getUnionTypes(type: UnionTypeID): $ReadOnlyArray<TypeID> {
1236
- return Array.from(this._typeMap.getPossibleTypeSet(type));
1237
- }
1238
-
1239
- getInterfaces(type: CompositeTypeID): $ReadOnlyArray<TypeID> {
1240
- if (type instanceof ObjectType) {
1241
- return this._typeMap.getInterfaces(type);
1242
- }
1243
- return [];
1244
- }
1245
-
1246
- getPossibleTypes(type: AbstractTypeID): $ReadOnlySet<ObjectTypeID> {
1247
- return this._typeMap.getPossibleTypeSet(type);
1248
- }
1249
-
1250
- getFetchableFieldName(type: ObjectTypeID): ?string {
1251
- return this._typeMap.getFetchableFieldName(type);
1252
- }
1253
-
1254
- parseLiteral(type: ScalarTypeID | EnumTypeID, valueNode: ValueNode): mixed {
1255
- if (type instanceof EnumType && valueNode.kind === 'EnumValue') {
1256
- return this.parseValue(type, valueNode.value);
1257
- } else if (type instanceof ScalarType) {
1258
- if (valueNode.kind === 'BooleanValue' && type.name === 'Boolean') {
1259
- return GraphQLBoolean.parseLiteral(valueNode);
1260
- } else if (valueNode.kind === 'FloatValue' && type.name === 'Float') {
1261
- return GraphQLFloat.parseLiteral(valueNode);
1262
- } else if (
1263
- valueNode.kind === 'IntValue' &&
1264
- (type.name === 'Int' || type.name === 'ID' || type.name === 'Float')
1265
- ) {
1266
- return GraphQLInt.parseLiteral(valueNode);
1267
- } else if (
1268
- valueNode.kind === 'StringValue' &&
1269
- (type.name === 'String' || type.name === 'ID')
1270
- ) {
1271
- return GraphQLString.parseLiteral(valueNode);
1272
- } else if (!isDefaultScalar(type.name)) {
1273
- return valueFromASTUntyped(valueNode);
1274
- }
1275
- }
1276
- }
1277
-
1278
- parseValue(type: ScalarTypeID | EnumTypeID, value: mixed): mixed {
1279
- if (type instanceof EnumType) {
1280
- return type.values.includes(value) ? value : undefined;
1281
- } else if (type instanceof ScalarType) {
1282
- switch (type.name) {
1283
- case 'Boolean':
1284
- return GraphQLBoolean.parseValue(value);
1285
- case 'Float':
1286
- return GraphQLFloat.parseValue(value);
1287
- case 'Int':
1288
- return GraphQLInt.parseValue(value);
1289
- case 'String':
1290
- return GraphQLString.parseValue(value);
1291
- case 'ID':
1292
- return GraphQLID.parseValue(value);
1293
- default:
1294
- return value;
1295
- }
1296
- }
1297
- }
1298
-
1299
- serialize(type: ScalarTypeID | EnumTypeID, value: mixed): mixed {
1300
- if (type instanceof EnumType) {
1301
- return type.values.includes(value) ? value : undefined;
1302
- } else if (type instanceof ScalarType) {
1303
- switch (type.name) {
1304
- case 'Boolean':
1305
- return GraphQLBoolean.serialize(value);
1306
- case 'Float':
1307
- return GraphQLFloat.serialize(value);
1308
- case 'Int':
1309
- return GraphQLInt.serialize(value);
1310
- case 'String':
1311
- return GraphQLString.serialize(value);
1312
- case 'ID':
1313
- return GraphQLID.serialize(value);
1314
- default:
1315
- return value;
1316
- }
1317
- }
1318
- }
1319
-
1320
- getDirectives(): $ReadOnlyArray<Directive> {
1321
- return Array.from(this._directiveMap.values());
1322
- }
1323
-
1324
- getDirective(directiveName: string): ?Directive {
1325
- return this._directiveMap.get(directiveName);
1326
- }
1327
-
1328
- isServerType(type: TypeID): boolean {
1329
- const unwrapped = unwrap(type);
1330
- return unwrapped.isClient === false;
1331
- }
1332
-
1333
- isServerField(field: FieldID): boolean {
1334
- return field.isClient === false;
1335
- }
1336
-
1337
- isServerDirective(directiveName: string): boolean {
1338
- const directive = this._directiveMap.get(directiveName);
1339
- return directive?.isClient === false;
1340
- }
1341
-
1342
- isServerDefinedField(type: CompositeTypeID, field: IRField): boolean {
1343
- return (
1344
- (this.isAbstractType(type) &&
1345
- field.directives.some(({name}) => name === 'fixme_fat_interface')) ||
1346
- (this.hasField(type, field.name) &&
1347
- this.isServerField(this.expectField(type, field.name)))
1348
- );
1349
- }
1350
-
1351
- isClientDefinedField(type: CompositeTypeID, field: IRField): boolean {
1352
- return !this.isServerDefinedField(type, field);
1353
- }
1354
-
1355
- extend(extensions: DocumentNode | $ReadOnlyArray<string>): Schema {
1356
- const doc = Array.isArray(extensions)
1357
- ? parse(extensions.join('\n'))
1358
- : extensions;
1359
-
1360
- const schemaExtensions = [];
1361
- doc.definitions.forEach(definition => {
1362
- if (isSchemaDefinitionAST(definition)) {
1363
- schemaExtensions.push(definition);
1364
- }
1365
- });
1366
- if (schemaExtensions.length > 0) {
1367
- return new Schema(this._typeMap.extend(schemaExtensions));
1368
- }
1369
- return this;
1370
- }
1371
- }
1372
-
1373
- class TypeMap {
1374
- _mutationTypeName: string;
1375
- _queryTypeName: string;
1376
- _subscriptionTypeName: string;
1377
- +_directives: InternalDirectiveMap;
1378
- +_extensions: $ReadOnlyArray<ExtensionNode>;
1379
- +_fetchable: Map<TypeID, Fetchable>;
1380
- +_fields: Map<InterfaceType | ObjectType, Map<string, FieldDefinition>>;
1381
- +_inputFields: Map<InputObjectType, Map<string, TypeNode>>;
1382
- +_interfaceImplementations: Map<InterfaceType, Set<ObjectType>>;
1383
- +_source: Source;
1384
- +_typeInterfaces: Map<TypeID, $ReadOnlyArray<InterfaceType>>;
1385
- +_types: Map<string, BaseType>;
1386
- +_unionTypes: Map<TypeID, Set<ObjectType>>;
1387
-
1388
- constructor(source: Source, extensions: $ReadOnlyArray<ExtensionNode>) {
1389
- this._types = new Map([
1390
- ['ID', new ScalarType('ID', false)],
1391
- ['String', new ScalarType('String', false)],
1392
- ['Boolean', new ScalarType('Boolean', false)],
1393
- ['Float', new ScalarType('Float', false)],
1394
- ['Int', new ScalarType('Int', false)],
1395
- ]);
1396
- this._typeInterfaces = new Map();
1397
- this._unionTypes = new Map();
1398
- this._interfaceImplementations = new Map();
1399
- this._fields = new Map();
1400
- this._inputFields = new Map();
1401
- this._directives = new Map([
1402
- [
1403
- 'include',
1404
- {
1405
- name: 'include',
1406
- isClient: false,
1407
- locations: ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'],
1408
- args: [
1409
- {
1410
- name: 'if',
1411
- typeNode: parseType('Boolean!'),
1412
- defaultValue: undefined,
1413
- },
1414
- ],
1415
- },
1416
- ],
1417
- [
1418
- 'skip',
1419
- {
1420
- name: 'skip',
1421
- isClient: false,
1422
- locations: ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'],
1423
- args: [
1424
- {
1425
- name: 'if',
1426
- typeNode: parseType('Boolean!'),
1427
- defaultValue: undefined,
1428
- },
1429
- ],
1430
- },
1431
- ],
1432
- [
1433
- 'deprecated',
1434
- {
1435
- name: 'deprecated',
1436
- isClient: false,
1437
- locations: ['FIELD_DEFINITION', 'ENUM_VALUE'],
1438
- args: [
1439
- {
1440
- name: 'reason',
1441
- typeNode: parseType('String'),
1442
- defaultValue: {
1443
- kind: 'StringValue',
1444
- value: 'No longer supported',
1445
- },
1446
- },
1447
- ],
1448
- },
1449
- ],
1450
- ]);
1451
- this._queryTypeName = 'Query';
1452
- this._mutationTypeName = 'Mutation';
1453
- this._subscriptionTypeName = 'Subscription';
1454
- this._source = source;
1455
- this._extensions = extensions;
1456
- this._fetchable = new Map();
1457
- this._parse(source);
1458
- this._extend(extensions);
1459
- }
1460
-
1461
- _parse(source: Source) {
1462
- const document = parse(source, {
1463
- noLocation: true,
1464
- });
1465
- document.definitions.forEach(definition => {
1466
- switch (definition.kind) {
1467
- case 'SchemaDefinition': {
1468
- this._parseSchemaDefinition(definition);
1469
- break;
1470
- }
1471
- case 'ScalarTypeDefinition': {
1472
- this._parseScalarNode(definition, false);
1473
- break;
1474
- }
1475
- case 'EnumTypeDefinition': {
1476
- this._parseEnumNode(definition, false);
1477
- break;
1478
- }
1479
- case 'ObjectTypeDefinition': {
1480
- this._parseObjectTypeNode(definition, false);
1481
- break;
1482
- }
1483
- case 'InputObjectTypeDefinition': {
1484
- this._parseInputObjectTypeNode(definition, false);
1485
- break;
1486
- }
1487
- case 'UnionTypeDefinition': {
1488
- this._parseUnionNode(definition, false);
1489
- break;
1490
- }
1491
- case 'InterfaceTypeDefinition': {
1492
- this._parseInterfaceNode(definition, false);
1493
- break;
1494
- }
1495
- case 'DirectiveDefinition': {
1496
- this._parseDirective(definition, false);
1497
- break;
1498
- }
1499
- }
1500
- });
1501
- }
1502
-
1503
- _parseSchemaDefinition(node: SchemaDefinitionNode) {
1504
- node.operationTypes.forEach(operationType => {
1505
- switch (operationType.operation) {
1506
- case 'query':
1507
- this._queryTypeName = operationType.type.name.value;
1508
- break;
1509
- case 'mutation':
1510
- this._mutationTypeName = operationType.type.name.value;
1511
- break;
1512
- case 'subscription':
1513
- this._subscriptionTypeName = operationType.type.name.value;
1514
- break;
1515
- }
1516
- });
1517
- }
1518
-
1519
- _parseScalarNode(node: ScalarTypeDefinitionNode, isClient: boolean) {
1520
- const name = node.name.value;
1521
- if (!isDefaultScalar(name) && this._types.has(name)) {
1522
- throw createCompilerError(
1523
- `_parseScalarNode: Duplicate definition for type ${name}.`,
1524
- null,
1525
- [node],
1526
- );
1527
- }
1528
- this._types.set(name, new ScalarType(name, isClient));
1529
- }
1530
-
1531
- _parseEnumNode(node: EnumTypeDefinitionNode, isClient: boolean) {
1532
- const name = node.name.value;
1533
- if (this._types.has(name)) {
1534
- throw createCompilerError(
1535
- `_parseEnumNode: Duplicate definition for type ${name}.`,
1536
- null,
1537
- [node],
1538
- );
1539
- }
1540
- // SDL doesn't have information about the actual ENUM values
1541
- const values = node.values
1542
- ? node.values.map(value => value.name.value)
1543
- : [];
1544
- this._types.set(name, new EnumType(name, values, isClient));
1545
- }
1546
-
1547
- _parseObjectTypeNode(node: ObjectTypeDefinitionNode, isClient: boolean) {
1548
- const name = node.name.value;
1549
- // Objects may be created by _parseUnionNode
1550
- const type = this._types.get(name) ?? new ObjectType(name, isClient);
1551
- if (!(type instanceof ObjectType)) {
1552
- throw createCompilerError(
1553
- `_parseObjectTypeNode: Expected object type, got ${String(type)}`,
1554
- null,
1555
- [node],
1556
- );
1557
- }
1558
- if (type.isClient !== isClient) {
1559
- throw createCompilerError(
1560
- `_parseObjectTypeNode: Cannot create object type '${name}' defined as a client type.`,
1561
- null,
1562
- [node],
1563
- );
1564
- }
1565
- const typeInterfaces: Array<InterfaceType> = [];
1566
- node.interfaces &&
1567
- node.interfaces.forEach(interfaceTypeNode => {
1568
- const interfaceName = interfaceTypeNode.name.value;
1569
- let interfaceType = this._types.get(interfaceName);
1570
- if (!interfaceType) {
1571
- interfaceType = new InterfaceType(interfaceName, isClient);
1572
- this._types.set(interfaceName, interfaceType);
1573
- }
1574
- if (!(interfaceType instanceof InterfaceType)) {
1575
- throw createCompilerError(
1576
- '_parseObjectTypeNode: Expected interface type',
1577
- null,
1578
- [interfaceTypeNode],
1579
- );
1580
- }
1581
- const implementations =
1582
- this._interfaceImplementations.get(interfaceType) ?? new Set();
1583
-
1584
- implementations.add(type);
1585
- this._interfaceImplementations.set(interfaceType, implementations);
1586
- typeInterfaces.push(interfaceType);
1587
- });
1588
- let fetchable = null;
1589
- node.directives &&
1590
- node.directives.forEach(directiveNode => {
1591
- if (directiveNode.name.value === 'fetchable') {
1592
- const field_name_arg =
1593
- directiveNode.arguments &&
1594
- directiveNode.arguments.find(
1595
- arg => arg.name.value === 'field_name',
1596
- );
1597
- if (
1598
- field_name_arg != null &&
1599
- field_name_arg.value.kind === 'StringValue'
1600
- ) {
1601
- fetchable = {field_name: field_name_arg.value.value};
1602
- }
1603
- }
1604
- });
1605
- this._typeInterfaces.set(type, typeInterfaces);
1606
- this._types.set(name, type);
1607
- if (fetchable != null) {
1608
- this._fetchable.set(type, fetchable);
1609
- }
1610
- node.fields && this._handleTypeFieldsStrict(type, node.fields, isClient);
1611
- }
1612
-
1613
- _parseInputObjectTypeNode(
1614
- node: InputObjectTypeDefinitionNode,
1615
- isClient: boolean,
1616
- ) {
1617
- const name = node.name.value;
1618
- if (this._types.has(name)) {
1619
- throw createCompilerError(
1620
- '_parseInputObjectTypeNode: Unable to parse schema file. Duplicate definition for object type',
1621
- null,
1622
- [node],
1623
- );
1624
- }
1625
- const type = new InputObjectType(name, isClient);
1626
- this._types.set(name, type);
1627
- this._parseInputObjectFields(type, node);
1628
- }
1629
-
1630
- _parseUnionNode(node: UnionTypeDefinitionNode, isClient: boolean) {
1631
- const name = node.name.value;
1632
- if (this._types.has(name)) {
1633
- throw createCompilerError(
1634
- '_parseUnionNode: Unable to parse schema file. Duplicate definition for object type',
1635
- null,
1636
- [node],
1637
- );
1638
- }
1639
- const union = new UnionType(name, isClient);
1640
- this._types.set(name, union);
1641
- this._unionTypes.set(
1642
- union,
1643
- new Set(
1644
- node.types
1645
- ? node.types.map(typeInUnion => {
1646
- const typeInUnionName = typeInUnion.name.value;
1647
- const object =
1648
- this._types.get(typeInUnionName) ??
1649
- new ObjectType(typeInUnionName, false);
1650
- if (!(object instanceof ObjectType)) {
1651
- throw createCompilerError(
1652
- '_parseUnionNode: Expected object type',
1653
- null,
1654
- [typeInUnion],
1655
- );
1656
- }
1657
- this._types.set(typeInUnionName, object);
1658
- return object;
1659
- })
1660
- : [],
1661
- ),
1662
- );
1663
- }
1664
-
1665
- _parseInterfaceNode(node: InterfaceTypeDefinitionNode, isClient: boolean) {
1666
- const name = node.name.value;
1667
- let type = this._types.get(name);
1668
- if (!type) {
1669
- type = new InterfaceType(name, isClient);
1670
- this._types.set(name, type);
1671
- }
1672
- if (!(type instanceof InterfaceType)) {
1673
- throw createCompilerError(
1674
- `_parseInterfaceNode: Expected interface type. Got ${String(type)}`,
1675
- null,
1676
- [node],
1677
- );
1678
- }
1679
- if (type.isClient !== isClient) {
1680
- throw createCompilerError(
1681
- `_parseInterfaceNode: Cannot create interface '${name}' defined as a client interface`,
1682
- null,
1683
- [node],
1684
- );
1685
- }
1686
- node.fields && this._handleTypeFieldsStrict(type, node.fields, isClient);
1687
- }
1688
-
1689
- _handleTypeFieldsStrict(
1690
- type: ObjectType | InterfaceType,
1691
- fields: $ReadOnlyArray<FieldDefinitionNode>,
1692
- isClient: boolean,
1693
- ) {
1694
- if (this._fields.has(type)) {
1695
- throw createCompilerError(
1696
- '_handleTypeFieldsStrict: Unable to parse schema file. Duplicate definition for object type',
1697
- );
1698
- }
1699
- this._handleTypeFields(type, fields, isClient);
1700
- }
1701
-
1702
- _handleTypeFields(
1703
- type: ObjectType | InterfaceType,
1704
- fields: $ReadOnlyArray<FieldDefinitionNode>,
1705
- isClient: boolean,
1706
- ) {
1707
- const fieldsMap = this._fields.get(type) ?? new Map();
1708
- fields.forEach(fieldNode => {
1709
- const fieldName = fieldNode.name.value;
1710
- if (fieldsMap.has(fieldName)) {
1711
- throw createCompilerError(
1712
- `_handleTypeFields: Duplicate definition for field '${fieldName}'.`,
1713
- );
1714
- }
1715
- fieldsMap.set(fieldName, {
1716
- arguments: fieldNode.arguments
1717
- ? fieldNode.arguments.map(arg => {
1718
- return {
1719
- name: arg.name.value,
1720
- typeNode: arg.type,
1721
- defaultValue: arg.defaultValue,
1722
- };
1723
- })
1724
- : [],
1725
- directives: fieldNode.directives
1726
- ? fieldNode.directives.map(directive => {
1727
- return {
1728
- name: directive.name.value,
1729
- args: directive.arguments
1730
- ? directive.arguments.map(arg => {
1731
- return {
1732
- name: arg.name.value,
1733
- value: arg.value,
1734
- };
1735
- })
1736
- : [],
1737
- };
1738
- })
1739
- : null,
1740
- type: fieldNode.type,
1741
- isClient: isClient,
1742
- });
1743
- });
1744
- this._fields.set(type, fieldsMap);
1745
- }
1746
-
1747
- _parseInputObjectFields(
1748
- type: InputObjectType,
1749
- node: InputObjectTypeDefinitionNode,
1750
- ) {
1751
- if (this._inputFields.has(type)) {
1752
- throw createCompilerError(
1753
- '_parseInputObjectFields: Unable to parse schema file. Duplicate definition for type',
1754
- null,
1755
- [node],
1756
- );
1757
- }
1758
- const fields = new Map();
1759
- if (node.fields) {
1760
- node.fields.forEach(fieldNode => {
1761
- fields.set(fieldNode.name.value, fieldNode.type);
1762
- });
1763
- }
1764
- this._inputFields.set(type, fields);
1765
- }
1766
-
1767
- _parseDirective(node: DirectiveDefinitionNode, isClient: boolean) {
1768
- const name = node.name.value;
1769
- this._directives.set(name, {
1770
- name,
1771
- args: node.arguments
1772
- ? node.arguments.map(arg => {
1773
- return {
1774
- name: arg.name.value,
1775
- typeNode: arg.type,
1776
- defaultValue: arg.defaultValue,
1777
- };
1778
- })
1779
- : [],
1780
-
1781
- locations: node.locations.map(location => {
1782
- switch (location.value) {
1783
- case 'QUERY':
1784
- case 'MUTATION':
1785
- case 'SUBSCRIPTION':
1786
- case 'FIELD':
1787
- case 'FRAGMENT_DEFINITION':
1788
- case 'FRAGMENT_SPREAD':
1789
- case 'INLINE_FRAGMENT':
1790
- case 'VARIABLE_DEFINITION':
1791
- case 'SCHEMA':
1792
- case 'SCALAR':
1793
- case 'OBJECT':
1794
- case 'FIELD_DEFINITION':
1795
- case 'ARGUMENT_DEFINITION':
1796
- case 'INTERFACE':
1797
- case 'UNION':
1798
- case 'ENUM':
1799
- case 'ENUM_VALUE':
1800
- case 'INPUT_OBJECT':
1801
- case 'INPUT_FIELD_DEFINITION':
1802
- return location.value;
1803
- default:
1804
- throw createCompilerError('Invalid directive location');
1805
- }
1806
- }),
1807
- isClient,
1808
- });
1809
- }
1810
-
1811
- _parseObjectTypeExtension(node: ObjectTypeExtensionNode) {
1812
- const type = this._types.get(node.name.value);
1813
- if (!(type instanceof ObjectType)) {
1814
- throw createCompilerError(
1815
- `_parseObjectTypeExtension: Expected to find type with the name '${node.name.value}'`,
1816
- null,
1817
- [node],
1818
- );
1819
- }
1820
- node.fields &&
1821
- this._handleTypeFields(type, node.fields, true /** client fields */);
1822
- }
1823
-
1824
- _parseInterfaceTypeExtension(node: InterfaceTypeExtensionNode) {
1825
- const type = this._types.get(node.name.value);
1826
- if (!(type instanceof InterfaceType)) {
1827
- throw createCompilerError(
1828
- '_parseInterfaceTypeExtension: Expected to have an interface type',
1829
- );
1830
- }
1831
- node.fields && this._handleTypeFields(type, node.fields, true);
1832
- }
1833
-
1834
- _extend(extensions: $ReadOnlyArray<ExtensionNode>) {
1835
- extensions.forEach(definition => {
1836
- if (definition.kind === 'ObjectTypeDefinition') {
1837
- this._parseObjectTypeNode(definition, true);
1838
- } else if (definition.kind === 'InterfaceTypeDefinition') {
1839
- this._parseInterfaceNode(definition, true);
1840
- } else if (definition.kind === 'ScalarTypeDefinition') {
1841
- this._parseScalarNode(definition, true);
1842
- } else if (definition.kind === 'EnumTypeDefinition') {
1843
- this._parseEnumNode(definition, true);
1844
- } else if (definition.kind === 'InterfaceTypeExtension') {
1845
- this._parseInterfaceTypeExtension(definition);
1846
- } else if (definition.kind === 'ObjectTypeExtension') {
1847
- this._parseObjectTypeExtension(definition);
1848
- } else if (definition.kind === 'DirectiveDefinition') {
1849
- this._parseDirective(definition, true /* client directive */);
1850
- } else {
1851
- throw createCompilerError(
1852
- `Unexpected extension kind: '${definition.kind}'`,
1853
- null,
1854
- [definition],
1855
- );
1856
- }
1857
- });
1858
- }
1859
-
1860
- getTypes(): $ReadOnlyArray<BaseType> {
1861
- return Array.from(this._types.values());
1862
- }
1863
-
1864
- getTypeByName(typename: string): ?BaseType {
1865
- return this._types.get(typename);
1866
- }
1867
-
1868
- getInterfaces(type: ObjectType): $ReadOnlyArray<InterfaceType> {
1869
- return this._typeInterfaces.get(type) ?? [];
1870
- }
1871
-
1872
- getPossibleTypeSet(
1873
- type: UnionType | InterfaceType,
1874
- ): $ReadOnlySet<ObjectType> {
1875
- let set;
1876
- if (type instanceof InterfaceType) {
1877
- set = this._interfaceImplementations.get(type) ?? new Set();
1878
- } else if (type instanceof UnionType) {
1879
- set = this._unionTypes.get(type) ?? new Set();
1880
- } else {
1881
- throw createCompilerError(
1882
- 'Invalid type supplied to "getPossibleTypeSet"',
1883
- );
1884
- }
1885
- if (!set) {
1886
- throw createCompilerError(
1887
- `Unable to find possible types for ${type.name}`,
1888
- );
1889
- }
1890
- return set;
1891
- }
1892
-
1893
- getFetchableFieldName(type: ObjectTypeID): ?string {
1894
- return this._fetchable.get(type)?.field_name ?? null;
1895
- }
1896
-
1897
- getQueryType(): ?BaseType {
1898
- return this._types.get(this._queryTypeName);
1899
- }
1900
-
1901
- getMutationType(): ?BaseType {
1902
- return this._types.get(this._mutationTypeName);
1903
- }
1904
-
1905
- getSubscriptionType(): ?BaseType {
1906
- return this._types.get(this._subscriptionTypeName);
1907
- }
1908
-
1909
- getField(
1910
- type: InterfaceType | ObjectType,
1911
- fieldName: string,
1912
- ): ?FieldDefinition {
1913
- const fields = this._fields.get(type);
1914
- if (fields) {
1915
- return fields.get(fieldName);
1916
- }
1917
- }
1918
-
1919
- getFieldMap(type: InterfaceType | ObjectType): ?Map<string, FieldDefinition> {
1920
- return this._fields.get(type);
1921
- }
1922
-
1923
- getInputField(type: InputObjectType, fieldName: string): ?TypeNode {
1924
- const inputFields = this._inputFields.get(type);
1925
- if (inputFields) {
1926
- return inputFields.get(fieldName);
1927
- }
1928
- }
1929
-
1930
- getInputFieldMap(type: InputObjectType): ?Map<string, TypeNode> {
1931
- return this._inputFields.get(type);
1932
- }
1933
-
1934
- getDirectives(): $ReadOnlyArray<InternalDirectiveStruct> {
1935
- return Array.from(this._directives.values());
1936
- }
1937
-
1938
- extend(extensions: $ReadOnlyArray<ExtensionNode>): TypeMap {
1939
- return new TypeMap(this._source, this._extensions.concat(extensions));
1940
- }
1941
- }
1942
-
1943
- function create(
1944
- baseSchema: Source,
1945
- schemaExtensionDocuments?: $ReadOnlyArray<DocumentNode>,
1946
- schemaExtensions?: $ReadOnlyArray<string>,
1947
- ): Schema {
1948
- const extensions: Array<ExtensionNode> = [];
1949
- schemaExtensions &&
1950
- schemaExtensions.forEach(source => {
1951
- const doc = parse(source, {
1952
- noLocation: true,
1953
- });
1954
- doc.definitions.forEach(definition => {
1955
- if (isSchemaDefinitionAST(definition)) {
1956
- extensions.push(definition);
1957
- }
1958
- });
1959
- });
1960
- schemaExtensionDocuments &&
1961
- schemaExtensionDocuments.forEach(doc => {
1962
- doc.definitions.forEach(definition => {
1963
- if (isSchemaDefinitionAST(definition)) {
1964
- extensions.push(definition);
1965
- }
1966
- });
1967
- });
1968
-
1969
- return new Schema(new TypeMap(baseSchema, extensions));
1970
- }
1971
-
1972
- function parseInputArgumentDefinitions(
1973
- schema: Schema,
1974
- args: $ReadOnlyArray<InternalArgumentStruct>,
1975
- ): $ReadOnlyArray<Argument> {
1976
- return args.map(arg => {
1977
- const argType = schema.assertInputType(
1978
- schema.expectTypeFromAST(arg.typeNode),
1979
- );
1980
- let defaultValue;
1981
- const defaultValueNode = arg.defaultValue;
1982
- if (defaultValueNode != null) {
1983
- const nullableType = schema.getNullableType(argType);
1984
- const isNullable = schema.isNonNull(argType) === false;
1985
- if (isNullable && defaultValueNode.kind === 'NullValue') {
1986
- defaultValue = null;
1987
- } else {
1988
- if (
1989
- nullableType instanceof ScalarType ||
1990
- nullableType instanceof EnumType
1991
- ) {
1992
- defaultValue = schema.parseLiteral(nullableType, defaultValueNode);
1993
- } else if (
1994
- (nullableType instanceof List &&
1995
- defaultValueNode.kind === 'ListValue') ||
1996
- (nullableType instanceof InputObjectType &&
1997
- defaultValueNode.kind === 'ObjectValue')
1998
- ) {
1999
- defaultValue = valueFromASTUntyped(defaultValueNode);
2000
- }
2001
- }
2002
- if (defaultValue === undefined) {
2003
- throw createCompilerError(
2004
- `parseInputArgumentDefinitions: Unexpected default value: ${String(
2005
- defaultValueNode,
2006
- )}. Expected to have a value of type ${String(nullableType)}.`,
2007
- );
2008
- }
2009
- }
2010
- return {
2011
- name: arg.name,
2012
- type: argType,
2013
- defaultValue,
2014
- };
2015
- });
2016
- }
2017
-
2018
- function parseInputArgumentDefinitionsMap(
2019
- schema: Schema,
2020
- args: $ReadOnlyArray<InternalArgumentStruct>,
2021
- ): $ReadOnlyMap<string, Argument> {
2022
- return new Map(
2023
- parseInputArgumentDefinitions(schema, args).map(arg => {
2024
- return [arg.name, arg];
2025
- }),
2026
- );
2027
- }
2028
-
2029
- function isDefaultScalar(name: string): boolean {
2030
- return new Set(['ID', 'String', 'Boolean', 'Int', 'Float']).has(name);
2031
- }
2032
-
2033
- module.exports = {
2034
- create,
2035
- };