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.
- package/cli.js +23 -0
- package/index.js +19 -3
- package/linux-x64/relay +0 -0
- package/macos-x64/relay +0 -0
- package/package.json +2 -24
- package/win-x64/relay.exe +0 -0
- package/bin/RelayCompilerBin.js.flow +0 -168
- package/bin/RelayCompilerMain.js.flow +0 -515
- package/bin/__fixtures__/plugin-module.js.flow +0 -17
- package/bin/relay-compiler +0 -19068
- package/codegen/CodegenDirectory.js.flow +0 -372
- package/codegen/CodegenRunner.js.flow +0 -424
- package/codegen/CodegenTypes.js.flow +0 -28
- package/codegen/CodegenWatcher.js.flow +0 -250
- package/codegen/NormalizationCodeGenerator.js.flow +0 -566
- package/codegen/ReaderCodeGenerator.js.flow +0 -510
- package/codegen/RelayCodeGenerator.js.flow +0 -85
- package/codegen/RelayFileWriter.js.flow +0 -365
- package/codegen/SourceControl.js.flow +0 -58
- package/codegen/compileRelayArtifacts.js.flow +0 -181
- package/codegen/createPrintRequireModuleDependency.js.flow +0 -19
- package/codegen/sortObjectByKey.js.flow +0 -25
- package/codegen/writeRelayGeneratedFile.js.flow +0 -235
- package/core/ASTCache.js.flow +0 -73
- package/core/ASTConvert.js.flow +0 -230
- package/core/CompilerContext.js.flow +0 -189
- package/core/CompilerError.js.flow +0 -255
- package/core/DotGraphQLParser.js.flow +0 -37
- package/core/GraphQLCompilerProfiler.js.flow +0 -341
- package/core/GraphQLDerivedFromMetadata.js.flow +0 -36
- package/core/GraphQLWatchmanClient.js.flow +0 -109
- package/core/IR.js.flow +0 -326
- package/core/IRPrinter.js.flow +0 -472
- package/core/IRTransformer.js.flow +0 -376
- package/core/IRValidator.js.flow +0 -259
- package/core/IRVisitor.js.flow +0 -150
- package/core/JSModuleParser.js.flow +0 -24
- package/core/RelayCompilerScope.js.flow +0 -199
- package/core/RelayFindGraphQLTags.js.flow +0 -118
- package/core/RelayGraphQLEnumsGenerator.js.flow +0 -55
- package/core/RelayIRTransforms.js.flow +0 -138
- package/core/RelayParser.js.flow +0 -1741
- package/core/RelaySourceModuleParser.js.flow +0 -133
- package/core/Schema.js.flow +0 -2035
- package/core/SchemaUtils.js.flow +0 -120
- package/core/filterContextForNode.js.flow +0 -49
- package/core/getFieldDefinition.js.flow +0 -156
- package/core/getIdentifierForArgumentValue.js.flow +0 -49
- package/core/getIdentifierForSelection.js.flow +0 -68
- package/core/getLiteralArgumentValues.js.flow +0 -32
- package/core/getNormalizationOperationName.js.flow +0 -19
- package/core/inferRootArgumentDefinitions.js.flow +0 -322
- package/index.js.flow +0 -198
- package/language/RelayLanguagePluginInterface.js.flow +0 -283
- package/language/javascript/FindGraphQLTags.js.flow +0 -136
- package/language/javascript/RelayFlowBabelFactories.js.flow +0 -176
- package/language/javascript/RelayFlowGenerator.js.flow +0 -1096
- package/language/javascript/RelayFlowTypeTransformers.js.flow +0 -181
- package/language/javascript/RelayLanguagePluginJavaScript.js.flow +0 -33
- package/language/javascript/formatGeneratedModule.js.flow +0 -65
- package/lib/bin/RelayCompilerBin.js +0 -143
- package/lib/bin/RelayCompilerMain.js +0 -488
- package/lib/bin/__fixtures__/plugin-module.js +0 -16
- package/lib/codegen/CodegenDirectory.js +0 -335
- package/lib/codegen/CodegenRunner.js +0 -433
- package/lib/codegen/CodegenTypes.js +0 -11
- package/lib/codegen/CodegenWatcher.js +0 -271
- package/lib/codegen/NormalizationCodeGenerator.js +0 -487
- package/lib/codegen/ReaderCodeGenerator.js +0 -473
- package/lib/codegen/RelayCodeGenerator.js +0 -75
- package/lib/codegen/RelayFileWriter.js +0 -270
- package/lib/codegen/SourceControl.js +0 -60
- package/lib/codegen/compileRelayArtifacts.js +0 -157
- package/lib/codegen/createPrintRequireModuleDependency.js +0 -19
- package/lib/codegen/sortObjectByKey.js +0 -41
- package/lib/codegen/writeRelayGeneratedFile.js +0 -206
- package/lib/core/ASTCache.js +0 -70
- package/lib/core/ASTConvert.js +0 -198
- package/lib/core/CompilerContext.js +0 -165
- package/lib/core/CompilerError.js +0 -252
- package/lib/core/DotGraphQLParser.js +0 -40
- package/lib/core/GraphQLCompilerProfiler.js +0 -299
- package/lib/core/GraphQLDerivedFromMetadata.js +0 -31
- package/lib/core/GraphQLWatchmanClient.js +0 -150
- package/lib/core/IR.js +0 -11
- package/lib/core/IRPrinter.js +0 -388
- package/lib/core/IRTransformer.js +0 -345
- package/lib/core/IRValidator.js +0 -226
- package/lib/core/IRVisitor.js +0 -45
- package/lib/core/JSModuleParser.js +0 -18
- package/lib/core/RelayCompilerScope.js +0 -183
- package/lib/core/RelayFindGraphQLTags.js +0 -79
- package/lib/core/RelayGraphQLEnumsGenerator.js +0 -50
- package/lib/core/RelayIRTransforms.js +0 -109
- package/lib/core/RelayParser.js +0 -1381
- package/lib/core/RelaySourceModuleParser.js +0 -104
- package/lib/core/Schema.js +0 -1877
- package/lib/core/SchemaUtils.js +0 -98
- package/lib/core/filterContextForNode.js +0 -50
- package/lib/core/getFieldDefinition.js +0 -145
- package/lib/core/getIdentifierForArgumentValue.js +0 -54
- package/lib/core/getIdentifierForSelection.js +0 -49
- package/lib/core/getLiteralArgumentValues.js +0 -26
- package/lib/core/getNormalizationOperationName.js +0 -17
- package/lib/core/inferRootArgumentDefinitions.js +0 -351
- package/lib/index.js +0 -178
- package/lib/language/RelayLanguagePluginInterface.js +0 -26
- package/lib/language/javascript/FindGraphQLTags.js +0 -126
- package/lib/language/javascript/RelayFlowBabelFactories.js +0 -160
- package/lib/language/javascript/RelayFlowGenerator.js +0 -856
- package/lib/language/javascript/RelayFlowTypeTransformers.js +0 -119
- package/lib/language/javascript/RelayLanguagePluginJavaScript.js +0 -30
- package/lib/language/javascript/formatGeneratedModule.js +0 -36
- package/lib/reporters/ConsoleReporter.js +0 -61
- package/lib/reporters/MultiReporter.js +0 -45
- package/lib/reporters/Reporter.js +0 -11
- package/lib/runner/Artifacts.js +0 -323
- package/lib/runner/BufferedFilesystem.js +0 -262
- package/lib/runner/GraphQLASTNodeGroup.js +0 -256
- package/lib/runner/GraphQLASTUtils.js +0 -23
- package/lib/runner/GraphQLNodeMap.js +0 -81
- package/lib/runner/Sources.js +0 -271
- package/lib/runner/StrictMap.js +0 -134
- package/lib/runner/compileArtifacts.js +0 -39
- package/lib/runner/extractAST.js +0 -77
- package/lib/runner/getChangedNodeNames.js +0 -82
- package/lib/runner/getSchemaInstance.js +0 -30
- package/lib/runner/types.js +0 -12
- package/lib/test-utils/TestSchema.js +0 -27
- package/lib/test-utils/parseGraphQLText.js +0 -30
- package/lib/transforms/ApplyFragmentArgumentTransform.js +0 -393
- package/lib/transforms/ClientExtensionsTransform.js +0 -221
- package/lib/transforms/ConnectionTransform.js +0 -639
- package/lib/transforms/DeclarativeConnectionMutationTransform.js +0 -218
- package/lib/transforms/DeferStreamTransform.js +0 -246
- package/lib/transforms/DisallowIdAsAlias.js +0 -40
- package/lib/transforms/DisallowTypenameOnRoot.js +0 -53
- package/lib/transforms/FieldHandleTransform.js +0 -79
- package/lib/transforms/FilterCompilerDirectivesTransform.js +0 -29
- package/lib/transforms/FilterDirectivesTransform.js +0 -42
- package/lib/transforms/FlattenTransform.js +0 -306
- package/lib/transforms/GenerateIDFieldTransform.js +0 -135
- package/lib/transforms/GenerateTypeNameTransform.js +0 -149
- package/lib/transforms/InlineDataFragmentTransform.js +0 -100
- package/lib/transforms/InlineFragmentsTransform.js +0 -61
- package/lib/transforms/MaskTransform.js +0 -117
- package/lib/transforms/MatchTransform.js +0 -434
- package/lib/transforms/ReactFlightComponentTransform.js +0 -158
- package/lib/transforms/RefetchableFragmentTransform.js +0 -249
- package/lib/transforms/RelayDirectiveTransform.js +0 -83
- package/lib/transforms/RequiredFieldTransform.js +0 -369
- package/lib/transforms/SkipClientExtensionsTransform.js +0 -46
- package/lib/transforms/SkipHandleFieldTransform.js +0 -45
- package/lib/transforms/SkipRedundantNodesTransform.js +0 -261
- package/lib/transforms/SkipSplitOperationTransform.js +0 -32
- package/lib/transforms/SkipUnreachableNodeTransform.js +0 -158
- package/lib/transforms/SkipUnusedVariablesTransform.js +0 -75
- package/lib/transforms/SplitModuleImportTransform.js +0 -82
- package/lib/transforms/TestOperationTransform.js +0 -144
- package/lib/transforms/TransformUtils.js +0 -21
- package/lib/transforms/ValidateGlobalVariablesTransform.js +0 -92
- package/lib/transforms/ValidateRequiredArgumentsTransform.js +0 -114
- package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +0 -108
- package/lib/transforms/ValidateUnusedVariablesTransform.js +0 -96
- package/lib/transforms/query-generators/FetchableQueryGenerator.js +0 -157
- package/lib/transforms/query-generators/NodeQueryGenerator.js +0 -166
- package/lib/transforms/query-generators/QueryQueryGenerator.js +0 -48
- package/lib/transforms/query-generators/ViewerQueryGenerator.js +0 -77
- package/lib/transforms/query-generators/index.js +0 -60
- package/lib/transforms/query-generators/utils.js +0 -92
- package/lib/util/CodeMarker.js +0 -80
- package/lib/util/DefaultHandleKey.js +0 -15
- package/lib/util/RelayCompilerCache.js +0 -97
- package/lib/util/Rollout.js +0 -40
- package/lib/util/TimeReporter.js +0 -83
- package/lib/util/areEqualArgValues.js +0 -135
- package/lib/util/argumentContainsVariables.js +0 -37
- package/lib/util/dedupeJSONStringify.js +0 -160
- package/lib/util/generateAbstractTypeRefinementKey.js +0 -24
- package/lib/util/getDefinitionNodeHash.js +0 -22
- package/lib/util/getModuleName.js +0 -32
- package/lib/util/joinArgumentDefinitions.js +0 -67
- package/lib/util/md5.js +0 -17
- package/lib/util/murmurHash.js +0 -86
- package/lib/util/nullthrowsOSS.js +0 -23
- package/lib/util/orList.js +0 -36
- package/lib/util/partitionArray.js +0 -35
- package/relay-compiler.js +0 -17
- package/relay-compiler.min.js +0 -22
- package/reporters/ConsoleReporter.js.flow +0 -81
- package/reporters/MultiReporter.js.flow +0 -43
- package/reporters/Reporter.js.flow +0 -19
- package/runner/Artifacts.js.flow +0 -215
- package/runner/BufferedFilesystem.js.flow +0 -194
- package/runner/GraphQLASTNodeGroup.js.flow +0 -174
- package/runner/GraphQLASTUtils.js.flow +0 -26
- package/runner/GraphQLNodeMap.js.flow +0 -55
- package/runner/Sources.js.flow +0 -227
- package/runner/StrictMap.js.flow +0 -96
- package/runner/compileArtifacts.js.flow +0 -75
- package/runner/extractAST.js.flow +0 -98
- package/runner/getChangedNodeNames.js.flow +0 -48
- package/runner/getSchemaInstance.js.flow +0 -36
- package/runner/types.js.flow +0 -37
- package/test-utils/TestSchema.js.flow +0 -30
- package/test-utils/parseGraphQLText.js.flow +0 -41
- package/transforms/ApplyFragmentArgumentTransform.js.flow +0 -524
- package/transforms/ClientExtensionsTransform.js.flow +0 -224
- package/transforms/ConnectionTransform.js.flow +0 -850
- package/transforms/DeclarativeConnectionMutationTransform.js.flow +0 -245
- package/transforms/DeferStreamTransform.js.flow +0 -263
- package/transforms/DisallowIdAsAlias.js.flow +0 -46
- package/transforms/DisallowTypenameOnRoot.js.flow +0 -44
- package/transforms/FieldHandleTransform.js.flow +0 -77
- package/transforms/FilterCompilerDirectivesTransform.js.flow +0 -33
- package/transforms/FilterDirectivesTransform.js.flow +0 -45
- package/transforms/FlattenTransform.js.flow +0 -458
- package/transforms/GenerateIDFieldTransform.js.flow +0 -151
- package/transforms/GenerateTypeNameTransform.js.flow +0 -159
- package/transforms/InlineDataFragmentTransform.js.flow +0 -123
- package/transforms/InlineFragmentsTransform.js.flow +0 -70
- package/transforms/MaskTransform.js.flow +0 -124
- package/transforms/MatchTransform.js.flow +0 -587
- package/transforms/ReactFlightComponentTransform.js.flow +0 -207
- package/transforms/RefetchableFragmentTransform.js.flow +0 -266
- package/transforms/RelayDirectiveTransform.js.flow +0 -96
- package/transforms/RequiredFieldTransform.js.flow +0 -413
- package/transforms/SkipClientExtensionsTransform.js.flow +0 -54
- package/transforms/SkipHandleFieldTransform.js.flow +0 -44
- package/transforms/SkipRedundantNodesTransform.js.flow +0 -277
- package/transforms/SkipSplitOperationTransform.js.flow +0 -37
- package/transforms/SkipUnreachableNodeTransform.js.flow +0 -148
- package/transforms/SkipUnusedVariablesTransform.js.flow +0 -59
- package/transforms/SplitModuleImportTransform.js.flow +0 -97
- package/transforms/TestOperationTransform.js.flow +0 -142
- package/transforms/TransformUtils.js.flow +0 -26
- package/transforms/ValidateGlobalVariablesTransform.js.flow +0 -80
- package/transforms/ValidateRequiredArgumentsTransform.js.flow +0 -130
- package/transforms/ValidateServerOnlyDirectivesTransform.js.flow +0 -128
- package/transforms/ValidateUnusedVariablesTransform.js.flow +0 -88
- package/transforms/query-generators/FetchableQueryGenerator.js.flow +0 -188
- package/transforms/query-generators/NodeQueryGenerator.js.flow +0 -217
- package/transforms/query-generators/QueryQueryGenerator.js.flow +0 -57
- package/transforms/query-generators/ViewerQueryGenerator.js.flow +0 -97
- package/transforms/query-generators/index.js.flow +0 -89
- package/transforms/query-generators/utils.js.flow +0 -76
- package/util/CodeMarker.js.flow +0 -79
- package/util/DefaultHandleKey.js.flow +0 -17
- package/util/RelayCompilerCache.js.flow +0 -86
- package/util/Rollout.js.flow +0 -39
- package/util/TimeReporter.js.flow +0 -79
- package/util/areEqualArgValues.js.flow +0 -126
- package/util/argumentContainsVariables.js.flow +0 -38
- package/util/dedupeJSONStringify.js.flow +0 -156
- package/util/generateAbstractTypeRefinementKey.js.flow +0 -29
- package/util/getDefinitionNodeHash.js.flow +0 -24
- package/util/getModuleName.js.flow +0 -39
- package/util/joinArgumentDefinitions.js.flow +0 -105
- package/util/md5.js.flow +0 -19
- package/util/murmurHash.js.flow +0 -94
- package/util/nullthrowsOSS.js.flow +0 -25
- package/util/orList.js.flow +0 -37
- package/util/partitionArray.js.flow +0 -37
package/core/Schema.js.flow
DELETED
@@ -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
|
-
};
|