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