relay-compiler 0.0.0-main-8ff54d69 → 0.0.0-main-38f1c96e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/cli.js +23 -0
  2. package/index.js +19 -3
  3. package/linux-x64/relay +0 -0
  4. package/macos-x64/relay +0 -0
  5. package/package.json +2 -24
  6. package/win-x64/relay.exe +0 -0
  7. package/bin/RelayCompilerBin.js.flow +0 -168
  8. package/bin/RelayCompilerMain.js.flow +0 -515
  9. package/bin/__fixtures__/plugin-module.js.flow +0 -17
  10. package/bin/relay-compiler +0 -19068
  11. package/codegen/CodegenDirectory.js.flow +0 -372
  12. package/codegen/CodegenRunner.js.flow +0 -424
  13. package/codegen/CodegenTypes.js.flow +0 -28
  14. package/codegen/CodegenWatcher.js.flow +0 -250
  15. package/codegen/NormalizationCodeGenerator.js.flow +0 -566
  16. package/codegen/ReaderCodeGenerator.js.flow +0 -510
  17. package/codegen/RelayCodeGenerator.js.flow +0 -85
  18. package/codegen/RelayFileWriter.js.flow +0 -365
  19. package/codegen/SourceControl.js.flow +0 -58
  20. package/codegen/compileRelayArtifacts.js.flow +0 -181
  21. package/codegen/createPrintRequireModuleDependency.js.flow +0 -19
  22. package/codegen/sortObjectByKey.js.flow +0 -25
  23. package/codegen/writeRelayGeneratedFile.js.flow +0 -235
  24. package/core/ASTCache.js.flow +0 -73
  25. package/core/ASTConvert.js.flow +0 -230
  26. package/core/CompilerContext.js.flow +0 -189
  27. package/core/CompilerError.js.flow +0 -255
  28. package/core/DotGraphQLParser.js.flow +0 -37
  29. package/core/GraphQLCompilerProfiler.js.flow +0 -341
  30. package/core/GraphQLDerivedFromMetadata.js.flow +0 -36
  31. package/core/GraphQLWatchmanClient.js.flow +0 -109
  32. package/core/IR.js.flow +0 -326
  33. package/core/IRPrinter.js.flow +0 -472
  34. package/core/IRTransformer.js.flow +0 -376
  35. package/core/IRValidator.js.flow +0 -259
  36. package/core/IRVisitor.js.flow +0 -150
  37. package/core/JSModuleParser.js.flow +0 -24
  38. package/core/RelayCompilerScope.js.flow +0 -199
  39. package/core/RelayFindGraphQLTags.js.flow +0 -118
  40. package/core/RelayGraphQLEnumsGenerator.js.flow +0 -55
  41. package/core/RelayIRTransforms.js.flow +0 -138
  42. package/core/RelayParser.js.flow +0 -1741
  43. package/core/RelaySourceModuleParser.js.flow +0 -133
  44. package/core/Schema.js.flow +0 -2035
  45. package/core/SchemaUtils.js.flow +0 -120
  46. package/core/filterContextForNode.js.flow +0 -49
  47. package/core/getFieldDefinition.js.flow +0 -156
  48. package/core/getIdentifierForArgumentValue.js.flow +0 -49
  49. package/core/getIdentifierForSelection.js.flow +0 -68
  50. package/core/getLiteralArgumentValues.js.flow +0 -32
  51. package/core/getNormalizationOperationName.js.flow +0 -19
  52. package/core/inferRootArgumentDefinitions.js.flow +0 -322
  53. package/index.js.flow +0 -198
  54. package/language/RelayLanguagePluginInterface.js.flow +0 -283
  55. package/language/javascript/FindGraphQLTags.js.flow +0 -136
  56. package/language/javascript/RelayFlowBabelFactories.js.flow +0 -176
  57. package/language/javascript/RelayFlowGenerator.js.flow +0 -1096
  58. package/language/javascript/RelayFlowTypeTransformers.js.flow +0 -181
  59. package/language/javascript/RelayLanguagePluginJavaScript.js.flow +0 -33
  60. package/language/javascript/formatGeneratedModule.js.flow +0 -65
  61. package/lib/bin/RelayCompilerBin.js +0 -143
  62. package/lib/bin/RelayCompilerMain.js +0 -488
  63. package/lib/bin/__fixtures__/plugin-module.js +0 -16
  64. package/lib/codegen/CodegenDirectory.js +0 -335
  65. package/lib/codegen/CodegenRunner.js +0 -433
  66. package/lib/codegen/CodegenTypes.js +0 -11
  67. package/lib/codegen/CodegenWatcher.js +0 -271
  68. package/lib/codegen/NormalizationCodeGenerator.js +0 -487
  69. package/lib/codegen/ReaderCodeGenerator.js +0 -473
  70. package/lib/codegen/RelayCodeGenerator.js +0 -75
  71. package/lib/codegen/RelayFileWriter.js +0 -270
  72. package/lib/codegen/SourceControl.js +0 -60
  73. package/lib/codegen/compileRelayArtifacts.js +0 -157
  74. package/lib/codegen/createPrintRequireModuleDependency.js +0 -19
  75. package/lib/codegen/sortObjectByKey.js +0 -41
  76. package/lib/codegen/writeRelayGeneratedFile.js +0 -206
  77. package/lib/core/ASTCache.js +0 -70
  78. package/lib/core/ASTConvert.js +0 -198
  79. package/lib/core/CompilerContext.js +0 -165
  80. package/lib/core/CompilerError.js +0 -252
  81. package/lib/core/DotGraphQLParser.js +0 -40
  82. package/lib/core/GraphQLCompilerProfiler.js +0 -299
  83. package/lib/core/GraphQLDerivedFromMetadata.js +0 -31
  84. package/lib/core/GraphQLWatchmanClient.js +0 -150
  85. package/lib/core/IR.js +0 -11
  86. package/lib/core/IRPrinter.js +0 -388
  87. package/lib/core/IRTransformer.js +0 -345
  88. package/lib/core/IRValidator.js +0 -226
  89. package/lib/core/IRVisitor.js +0 -45
  90. package/lib/core/JSModuleParser.js +0 -18
  91. package/lib/core/RelayCompilerScope.js +0 -183
  92. package/lib/core/RelayFindGraphQLTags.js +0 -79
  93. package/lib/core/RelayGraphQLEnumsGenerator.js +0 -50
  94. package/lib/core/RelayIRTransforms.js +0 -109
  95. package/lib/core/RelayParser.js +0 -1381
  96. package/lib/core/RelaySourceModuleParser.js +0 -104
  97. package/lib/core/Schema.js +0 -1877
  98. package/lib/core/SchemaUtils.js +0 -98
  99. package/lib/core/filterContextForNode.js +0 -50
  100. package/lib/core/getFieldDefinition.js +0 -145
  101. package/lib/core/getIdentifierForArgumentValue.js +0 -54
  102. package/lib/core/getIdentifierForSelection.js +0 -49
  103. package/lib/core/getLiteralArgumentValues.js +0 -26
  104. package/lib/core/getNormalizationOperationName.js +0 -17
  105. package/lib/core/inferRootArgumentDefinitions.js +0 -351
  106. package/lib/index.js +0 -178
  107. package/lib/language/RelayLanguagePluginInterface.js +0 -26
  108. package/lib/language/javascript/FindGraphQLTags.js +0 -126
  109. package/lib/language/javascript/RelayFlowBabelFactories.js +0 -160
  110. package/lib/language/javascript/RelayFlowGenerator.js +0 -856
  111. package/lib/language/javascript/RelayFlowTypeTransformers.js +0 -119
  112. package/lib/language/javascript/RelayLanguagePluginJavaScript.js +0 -30
  113. package/lib/language/javascript/formatGeneratedModule.js +0 -36
  114. package/lib/reporters/ConsoleReporter.js +0 -61
  115. package/lib/reporters/MultiReporter.js +0 -45
  116. package/lib/reporters/Reporter.js +0 -11
  117. package/lib/runner/Artifacts.js +0 -323
  118. package/lib/runner/BufferedFilesystem.js +0 -262
  119. package/lib/runner/GraphQLASTNodeGroup.js +0 -256
  120. package/lib/runner/GraphQLASTUtils.js +0 -23
  121. package/lib/runner/GraphQLNodeMap.js +0 -81
  122. package/lib/runner/Sources.js +0 -271
  123. package/lib/runner/StrictMap.js +0 -134
  124. package/lib/runner/compileArtifacts.js +0 -39
  125. package/lib/runner/extractAST.js +0 -77
  126. package/lib/runner/getChangedNodeNames.js +0 -82
  127. package/lib/runner/getSchemaInstance.js +0 -30
  128. package/lib/runner/types.js +0 -12
  129. package/lib/test-utils/TestSchema.js +0 -27
  130. package/lib/test-utils/parseGraphQLText.js +0 -30
  131. package/lib/transforms/ApplyFragmentArgumentTransform.js +0 -393
  132. package/lib/transforms/ClientExtensionsTransform.js +0 -221
  133. package/lib/transforms/ConnectionTransform.js +0 -639
  134. package/lib/transforms/DeclarativeConnectionMutationTransform.js +0 -218
  135. package/lib/transforms/DeferStreamTransform.js +0 -246
  136. package/lib/transforms/DisallowIdAsAlias.js +0 -40
  137. package/lib/transforms/DisallowTypenameOnRoot.js +0 -53
  138. package/lib/transforms/FieldHandleTransform.js +0 -79
  139. package/lib/transforms/FilterCompilerDirectivesTransform.js +0 -29
  140. package/lib/transforms/FilterDirectivesTransform.js +0 -42
  141. package/lib/transforms/FlattenTransform.js +0 -306
  142. package/lib/transforms/GenerateIDFieldTransform.js +0 -135
  143. package/lib/transforms/GenerateTypeNameTransform.js +0 -149
  144. package/lib/transforms/InlineDataFragmentTransform.js +0 -100
  145. package/lib/transforms/InlineFragmentsTransform.js +0 -61
  146. package/lib/transforms/MaskTransform.js +0 -117
  147. package/lib/transforms/MatchTransform.js +0 -434
  148. package/lib/transforms/ReactFlightComponentTransform.js +0 -158
  149. package/lib/transforms/RefetchableFragmentTransform.js +0 -249
  150. package/lib/transforms/RelayDirectiveTransform.js +0 -83
  151. package/lib/transforms/RequiredFieldTransform.js +0 -369
  152. package/lib/transforms/SkipClientExtensionsTransform.js +0 -46
  153. package/lib/transforms/SkipHandleFieldTransform.js +0 -45
  154. package/lib/transforms/SkipRedundantNodesTransform.js +0 -261
  155. package/lib/transforms/SkipSplitOperationTransform.js +0 -32
  156. package/lib/transforms/SkipUnreachableNodeTransform.js +0 -158
  157. package/lib/transforms/SkipUnusedVariablesTransform.js +0 -75
  158. package/lib/transforms/SplitModuleImportTransform.js +0 -82
  159. package/lib/transforms/TestOperationTransform.js +0 -144
  160. package/lib/transforms/TransformUtils.js +0 -21
  161. package/lib/transforms/ValidateGlobalVariablesTransform.js +0 -92
  162. package/lib/transforms/ValidateRequiredArgumentsTransform.js +0 -114
  163. package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +0 -108
  164. package/lib/transforms/ValidateUnusedVariablesTransform.js +0 -96
  165. package/lib/transforms/query-generators/FetchableQueryGenerator.js +0 -157
  166. package/lib/transforms/query-generators/NodeQueryGenerator.js +0 -166
  167. package/lib/transforms/query-generators/QueryQueryGenerator.js +0 -48
  168. package/lib/transforms/query-generators/ViewerQueryGenerator.js +0 -77
  169. package/lib/transforms/query-generators/index.js +0 -60
  170. package/lib/transforms/query-generators/utils.js +0 -92
  171. package/lib/util/CodeMarker.js +0 -80
  172. package/lib/util/DefaultHandleKey.js +0 -15
  173. package/lib/util/RelayCompilerCache.js +0 -97
  174. package/lib/util/Rollout.js +0 -40
  175. package/lib/util/TimeReporter.js +0 -83
  176. package/lib/util/areEqualArgValues.js +0 -135
  177. package/lib/util/argumentContainsVariables.js +0 -37
  178. package/lib/util/dedupeJSONStringify.js +0 -160
  179. package/lib/util/generateAbstractTypeRefinementKey.js +0 -24
  180. package/lib/util/getDefinitionNodeHash.js +0 -22
  181. package/lib/util/getModuleName.js +0 -32
  182. package/lib/util/joinArgumentDefinitions.js +0 -67
  183. package/lib/util/md5.js +0 -17
  184. package/lib/util/murmurHash.js +0 -86
  185. package/lib/util/nullthrowsOSS.js +0 -23
  186. package/lib/util/orList.js +0 -36
  187. package/lib/util/partitionArray.js +0 -35
  188. package/relay-compiler.js +0 -17
  189. package/relay-compiler.min.js +0 -22
  190. package/reporters/ConsoleReporter.js.flow +0 -81
  191. package/reporters/MultiReporter.js.flow +0 -43
  192. package/reporters/Reporter.js.flow +0 -19
  193. package/runner/Artifacts.js.flow +0 -215
  194. package/runner/BufferedFilesystem.js.flow +0 -194
  195. package/runner/GraphQLASTNodeGroup.js.flow +0 -174
  196. package/runner/GraphQLASTUtils.js.flow +0 -26
  197. package/runner/GraphQLNodeMap.js.flow +0 -55
  198. package/runner/Sources.js.flow +0 -227
  199. package/runner/StrictMap.js.flow +0 -96
  200. package/runner/compileArtifacts.js.flow +0 -75
  201. package/runner/extractAST.js.flow +0 -98
  202. package/runner/getChangedNodeNames.js.flow +0 -48
  203. package/runner/getSchemaInstance.js.flow +0 -36
  204. package/runner/types.js.flow +0 -37
  205. package/test-utils/TestSchema.js.flow +0 -30
  206. package/test-utils/parseGraphQLText.js.flow +0 -41
  207. package/transforms/ApplyFragmentArgumentTransform.js.flow +0 -524
  208. package/transforms/ClientExtensionsTransform.js.flow +0 -224
  209. package/transforms/ConnectionTransform.js.flow +0 -850
  210. package/transforms/DeclarativeConnectionMutationTransform.js.flow +0 -245
  211. package/transforms/DeferStreamTransform.js.flow +0 -263
  212. package/transforms/DisallowIdAsAlias.js.flow +0 -46
  213. package/transforms/DisallowTypenameOnRoot.js.flow +0 -44
  214. package/transforms/FieldHandleTransform.js.flow +0 -77
  215. package/transforms/FilterCompilerDirectivesTransform.js.flow +0 -33
  216. package/transforms/FilterDirectivesTransform.js.flow +0 -45
  217. package/transforms/FlattenTransform.js.flow +0 -458
  218. package/transforms/GenerateIDFieldTransform.js.flow +0 -151
  219. package/transforms/GenerateTypeNameTransform.js.flow +0 -159
  220. package/transforms/InlineDataFragmentTransform.js.flow +0 -123
  221. package/transforms/InlineFragmentsTransform.js.flow +0 -70
  222. package/transforms/MaskTransform.js.flow +0 -124
  223. package/transforms/MatchTransform.js.flow +0 -587
  224. package/transforms/ReactFlightComponentTransform.js.flow +0 -207
  225. package/transforms/RefetchableFragmentTransform.js.flow +0 -266
  226. package/transforms/RelayDirectiveTransform.js.flow +0 -96
  227. package/transforms/RequiredFieldTransform.js.flow +0 -413
  228. package/transforms/SkipClientExtensionsTransform.js.flow +0 -54
  229. package/transforms/SkipHandleFieldTransform.js.flow +0 -44
  230. package/transforms/SkipRedundantNodesTransform.js.flow +0 -277
  231. package/transforms/SkipSplitOperationTransform.js.flow +0 -37
  232. package/transforms/SkipUnreachableNodeTransform.js.flow +0 -148
  233. package/transforms/SkipUnusedVariablesTransform.js.flow +0 -59
  234. package/transforms/SplitModuleImportTransform.js.flow +0 -97
  235. package/transforms/TestOperationTransform.js.flow +0 -142
  236. package/transforms/TransformUtils.js.flow +0 -26
  237. package/transforms/ValidateGlobalVariablesTransform.js.flow +0 -80
  238. package/transforms/ValidateRequiredArgumentsTransform.js.flow +0 -130
  239. package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +0 -128
  240. package/transforms/ValidateUnusedVariablesTransform.js.flow +0 -88
  241. package/transforms/query-generators/FetchableQueryGenerator.js.flow +0 -188
  242. package/transforms/query-generators/NodeQueryGenerator.js.flow +0 -217
  243. package/transforms/query-generators/QueryQueryGenerator.js.flow +0 -57
  244. package/transforms/query-generators/ViewerQueryGenerator.js.flow +0 -97
  245. package/transforms/query-generators/index.js.flow +0 -89
  246. package/transforms/query-generators/utils.js.flow +0 -76
  247. package/util/CodeMarker.js.flow +0 -79
  248. package/util/DefaultHandleKey.js.flow +0 -17
  249. package/util/RelayCompilerCache.js.flow +0 -86
  250. package/util/Rollout.js.flow +0 -39
  251. package/util/TimeReporter.js.flow +0 -79
  252. package/util/areEqualArgValues.js.flow +0 -126
  253. package/util/argumentContainsVariables.js.flow +0 -38
  254. package/util/dedupeJSONStringify.js.flow +0 -156
  255. package/util/generateAbstractTypeRefinementKey.js.flow +0 -29
  256. package/util/getDefinitionNodeHash.js.flow +0 -24
  257. package/util/getModuleName.js.flow +0 -39
  258. package/util/joinArgumentDefinitions.js.flow +0 -105
  259. package/util/md5.js.flow +0 -19
  260. package/util/murmurHash.js.flow +0 -94
  261. package/util/nullthrowsOSS.js.flow +0 -25
  262. package/util/orList.js.flow +0 -37
  263. package/util/partitionArray.js.flow +0 -37
@@ -1,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
- };