relay-compiler 10.0.1 → 10.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/bin/relay-compiler +1347 -604
- package/codegen/NormalizationCodeGenerator.js.flow +12 -4
- package/codegen/ReaderCodeGenerator.js.flow +38 -3
- package/codegen/RelayFileWriter.js.flow +2 -0
- package/codegen/writeRelayGeneratedFile.js.flow +1 -1
- package/core/ASTCache.js.flow +1 -0
- package/core/CompilerContext.js.flow +1 -0
- package/core/IR.js.flow +0 -1
- package/core/IRPrinter.js.flow +3 -8
- package/core/RelayIRTransforms.js.flow +7 -0
- package/core/Schema.js.flow +55 -1
- package/index.js +1 -1
- package/language/javascript/FindGraphQLTags.js.flow +2 -97
- package/language/javascript/RelayFlowBabelFactories.js.flow +11 -15
- package/language/javascript/RelayFlowGenerator.js.flow +76 -19
- package/language/javascript/RelayFlowTypeTransformers.js.flow +4 -4
- package/lib/bin/RelayCompilerMain.js +5 -5
- package/lib/codegen/CodegenRunner.js +2 -2
- package/lib/codegen/NormalizationCodeGenerator.js +20 -8
- package/lib/codegen/ReaderCodeGenerator.js +43 -8
- package/lib/codegen/RelayFileWriter.js +2 -2
- package/lib/codegen/compileRelayArtifacts.js +2 -2
- package/lib/codegen/sortObjectByKey.js +2 -2
- package/lib/codegen/writeRelayGeneratedFile.js +2 -2
- package/lib/core/ASTCache.js +1 -0
- package/lib/core/CompilerContext.js +1 -0
- package/lib/core/CompilerError.js +2 -2
- package/lib/core/IRPrinter.js +3 -4
- package/lib/core/RelayGraphQLEnumsGenerator.js +2 -2
- package/lib/core/RelayIRTransforms.js +10 -4
- package/lib/core/RelayParser.js +4 -4
- package/lib/core/Schema.js +48 -7
- package/lib/core/getFieldDefinition.js +2 -2
- package/lib/core/inferRootArgumentDefinitions.js +4 -4
- package/lib/language/javascript/FindGraphQLTags.js +3 -69
- package/lib/language/javascript/RelayFlowBabelFactories.js +5 -5
- package/lib/language/javascript/RelayFlowGenerator.js +80 -21
- package/lib/runner/Artifacts.js +2 -2
- package/lib/runner/BufferedFilesystem.js +2 -2
- package/lib/runner/GraphQLASTNodeGroup.js +2 -2
- package/lib/runner/GraphQLNodeMap.js +2 -2
- package/lib/runner/Sources.js +21 -2
- package/lib/runner/StrictMap.js +2 -2
- package/lib/runner/getChangedNodeNames.js +2 -2
- package/lib/transforms/ApplyFragmentArgumentTransform.js +14 -14
- package/lib/transforms/ClientExtensionsTransform.js +5 -3
- package/lib/transforms/ConnectionTransform.js +8 -9
- package/lib/transforms/DeclarativeConnectionMutationTransform.js +113 -55
- package/lib/transforms/DeferStreamTransform.js +2 -2
- package/lib/transforms/DisallowTypenameOnRoot.js +2 -2
- package/lib/transforms/FieldHandleTransform.js +2 -2
- package/lib/transforms/FilterCompilerDirectivesTransform.js +29 -0
- package/lib/transforms/FlattenTransform.js +13 -12
- package/lib/transforms/GenerateIDFieldTransform.js +2 -2
- package/lib/transforms/GenerateTypeNameTransform.js +3 -3
- package/lib/transforms/InlineDataFragmentTransform.js +2 -2
- package/lib/transforms/MaskTransform.js +3 -3
- package/lib/transforms/MatchTransform.js +7 -3
- package/lib/transforms/ReactFlightComponentTransform.js +162 -0
- package/lib/transforms/RefetchableFragmentTransform.js +4 -4
- package/lib/transforms/RelayDirectiveTransform.js +2 -2
- package/lib/transforms/RequiredFieldTransform.js +380 -0
- package/lib/transforms/SkipHandleFieldTransform.js +1 -1
- package/lib/transforms/SkipRedundantNodesTransform.js +3 -1
- package/lib/transforms/SkipUnreachableNodeTransform.js +1 -1
- package/lib/transforms/SkipUnusedVariablesTransform.js +3 -3
- package/lib/transforms/TestOperationTransform.js +2 -2
- package/lib/transforms/ValidateGlobalVariablesTransform.js +2 -2
- package/lib/transforms/ValidateRequiredArgumentsTransform.js +2 -2
- package/lib/transforms/ValidateServerOnlyDirectivesTransform.js +2 -2
- package/lib/transforms/ValidateUnusedVariablesTransform.js +2 -2
- package/lib/transforms/query-generators/FetchableQueryGenerator.js +1 -1
- package/lib/transforms/query-generators/NodeQueryGenerator.js +1 -1
- package/lib/transforms/query-generators/index.js +2 -2
- package/lib/transforms/query-generators/utils.js +2 -2
- package/package.json +3 -3
- package/relay-compiler.js +4 -4
- package/relay-compiler.min.js +4 -4
- package/runner/Sources.js.flow +14 -0
- package/transforms/ClientExtensionsTransform.js.flow +2 -0
- package/transforms/ConnectionTransform.js.flow +0 -1
- package/transforms/DeclarativeConnectionMutationTransform.js.flow +137 -48
- package/transforms/FieldHandleTransform.js.flow +0 -1
- package/transforms/FilterCompilerDirectivesTransform.js.flow +33 -0
- package/transforms/FlattenTransform.js.flow +3 -2
- package/transforms/MatchTransform.js.flow +6 -0
- package/transforms/ReactFlightComponentTransform.js.flow +195 -0
- package/transforms/RequiredFieldTransform.js.flow +415 -0
- package/transforms/SkipRedundantNodesTransform.js.flow +3 -0
@@ -46,7 +46,6 @@ import type {
|
|
46
46
|
NormalizationLocalArgumentDefinition,
|
47
47
|
NormalizationModuleImport,
|
48
48
|
NormalizationOperation,
|
49
|
-
NormalizationScalarField,
|
50
49
|
NormalizationSelection,
|
51
50
|
NormalizationSplitOperation,
|
52
51
|
NormalizationStream,
|
@@ -290,7 +289,6 @@ function generateLinkedField(
|
|
290
289
|
kind: 'LinkedHandle',
|
291
290
|
name: node.name,
|
292
291
|
};
|
293
|
-
// T45504512: new connection model
|
294
292
|
// NOTE: this intentionally adds a dynamic key in order to avoid
|
295
293
|
// triggering updates to existing queries that do not use dynamic
|
296
294
|
// keys.
|
@@ -392,7 +390,7 @@ function generateScalarField(node): Array<NormalizationSelection> {
|
|
392
390
|
[handle.dynamicKey.loc],
|
393
391
|
);
|
394
392
|
}
|
395
|
-
|
393
|
+
const nodeHandle = {
|
396
394
|
alias: node.alias === node.name ? null : node.alias,
|
397
395
|
args: generateArgs(node.args),
|
398
396
|
filters: handle.filters,
|
@@ -401,9 +399,16 @@ function generateScalarField(node): Array<NormalizationSelection> {
|
|
401
399
|
kind: 'ScalarHandle',
|
402
400
|
name: node.name,
|
403
401
|
};
|
402
|
+
|
403
|
+
if (handle.handleArgs != null) {
|
404
|
+
// $FlowFixMe handleArgs exists in Handle
|
405
|
+
nodeHandle.handleArgs = generateArgs(handle.handleArgs);
|
406
|
+
}
|
407
|
+
|
408
|
+
return nodeHandle;
|
404
409
|
})) ||
|
405
410
|
[];
|
406
|
-
let field
|
411
|
+
let field = {
|
407
412
|
alias: node.alias === node.name ? null : node.alias,
|
408
413
|
args: generateArgs(node.args),
|
409
414
|
kind: 'ScalarField',
|
@@ -415,6 +420,9 @@ function generateScalarField(node): Array<NormalizationSelection> {
|
|
415
420
|
if (storageKey != null) {
|
416
421
|
field = {...field, storageKey};
|
417
422
|
}
|
423
|
+
if (node.metadata?.flight === true) {
|
424
|
+
field = {...field, kind: 'FlightField'};
|
425
|
+
}
|
418
426
|
return [field].concat(handles);
|
419
427
|
}
|
420
428
|
|
@@ -39,16 +39,20 @@ import type {
|
|
39
39
|
InlineDataFragmentSpread,
|
40
40
|
} from '../core/IR';
|
41
41
|
import type {Schema, TypeID} from '../core/Schema';
|
42
|
+
import type {RequiredDirectiveMetadata} from '../transforms/RequiredFieldTransform';
|
42
43
|
import type {
|
43
44
|
ReaderArgument,
|
44
45
|
ReaderArgumentDefinition,
|
45
46
|
ReaderField,
|
47
|
+
ReaderFlightField,
|
46
48
|
ReaderFragment,
|
47
49
|
ReaderInlineDataFragmentSpread,
|
48
50
|
ReaderLinkedField,
|
49
51
|
ReaderModuleImport,
|
52
|
+
ReaderRequiredField,
|
50
53
|
ReaderScalarField,
|
51
54
|
ReaderSelection,
|
55
|
+
RequiredFieldAction,
|
52
56
|
} from 'relay-runtime';
|
53
57
|
|
54
58
|
/**
|
@@ -267,7 +271,7 @@ function generateInlineDataFragmentSpread(
|
|
267
271
|
function generateLinkedField(
|
268
272
|
schema: Schema,
|
269
273
|
node: LinkedField,
|
270
|
-
): ReaderLinkedField {
|
274
|
+
): ReaderLinkedField | ReaderRequiredField {
|
271
275
|
// Note: it is important that the arguments of this field be sorted to
|
272
276
|
// ensure stable generation of storage keys for equivalent arguments
|
273
277
|
// which may have originally appeared in different orders across an app.
|
@@ -298,9 +302,26 @@ function generateLinkedField(
|
|
298
302
|
if (storageKey) {
|
299
303
|
field = {...field, storageKey};
|
300
304
|
}
|
305
|
+
const requiredMetadata: ?RequiredDirectiveMetadata = (node.metadata
|
306
|
+
?.required: $FlowFixMe);
|
307
|
+
if (requiredMetadata != null) {
|
308
|
+
return createRequiredField(field, requiredMetadata);
|
309
|
+
}
|
301
310
|
return field;
|
302
311
|
}
|
303
312
|
|
313
|
+
function createRequiredField(
|
314
|
+
field: ReaderField,
|
315
|
+
requiredMetadata: RequiredDirectiveMetadata,
|
316
|
+
): ReaderRequiredField {
|
317
|
+
return {
|
318
|
+
kind: 'RequiredField',
|
319
|
+
field,
|
320
|
+
action: requiredMetadata.action,
|
321
|
+
path: requiredMetadata.path,
|
322
|
+
};
|
323
|
+
}
|
324
|
+
|
304
325
|
function generateModuleImport(
|
305
326
|
schema: Schema,
|
306
327
|
node: ModuleImport,
|
@@ -335,7 +356,7 @@ function generateModuleImport(
|
|
335
356
|
function generateScalarField(
|
336
357
|
schema: Schema,
|
337
358
|
node: ScalarField,
|
338
|
-
): ReaderScalarField {
|
359
|
+
): ReaderScalarField | ReaderRequiredField | ReaderFlightField {
|
339
360
|
// Note: it is important that the arguments of this field be sorted to
|
340
361
|
// ensure stable generation of storage keys for equivalent arguments
|
341
362
|
// which may have originally appeared in different orders across an app.
|
@@ -349,7 +370,7 @@ function generateScalarField(
|
|
349
370
|
// 'ReaderCodeGenerator: unexpected handles',
|
350
371
|
// );
|
351
372
|
|
352
|
-
let field
|
373
|
+
let field = {
|
353
374
|
alias: node.alias === node.name ? null : node.alias,
|
354
375
|
args: generateArgs(node.args),
|
355
376
|
kind: 'ScalarField',
|
@@ -361,6 +382,20 @@ function generateScalarField(
|
|
361
382
|
if (storageKey) {
|
362
383
|
field = {...field, storageKey};
|
363
384
|
}
|
385
|
+
if (node.metadata?.flight === true) {
|
386
|
+
field = {...field, kind: 'FlightField'};
|
387
|
+
}
|
388
|
+
const requiredMetadata: ?RequiredDirectiveMetadata = (node.metadata
|
389
|
+
?.required: $FlowFixMe);
|
390
|
+
if (requiredMetadata != null) {
|
391
|
+
if (field.kind === 'FlightField') {
|
392
|
+
throw new createUserError(
|
393
|
+
'@required cannot be used on a ReactFlightComponent.',
|
394
|
+
[node.loc],
|
395
|
+
);
|
396
|
+
}
|
397
|
+
return createRequiredField(field, requiredMetadata);
|
398
|
+
}
|
364
399
|
return field;
|
365
400
|
}
|
366
401
|
|
@@ -146,7 +146,9 @@ function writeAll({
|
|
146
146
|
}: {|
|
147
147
|
config: WriterConfig,
|
148
148
|
onlyValidate: boolean,
|
149
|
+
// $FlowFixMe[value-as-type]
|
149
150
|
baseDocuments: ImmutableMap<string, DocumentNode>,
|
151
|
+
// $FlowFixMe[value-as-type]
|
150
152
|
documents: ImmutableMap<string, DocumentNode>,
|
151
153
|
schema: Schema,
|
152
154
|
reporter: Reporter,
|
@@ -68,7 +68,7 @@ function writeRelayGeneratedFile(
|
|
68
68
|
) => void,
|
69
69
|
languagePlugin: ?PluginInterface,
|
70
70
|
): Promise<?GeneratedNode> {
|
71
|
-
let generatedNode = _generatedNode;
|
71
|
+
let generatedNode: GeneratedNode = _generatedNode;
|
72
72
|
// Copy to const so Flow can refine.
|
73
73
|
const persistQuery = _persistQuery;
|
74
74
|
const operationName =
|
package/core/ASTCache.js.flow
CHANGED
@@ -34,6 +34,7 @@ export type CompilerContextDocument = Fragment | Root | SplitOperation;
|
|
34
34
|
*/
|
35
35
|
class CompilerContext {
|
36
36
|
_isMutable: boolean;
|
37
|
+
// $FlowFixMe[value-as-type]
|
37
38
|
_documents: ImmutableOrderedMap<string, CompilerContextDocument>;
|
38
39
|
_withTransform: WeakMap<IRTransform, CompilerContext>;
|
39
40
|
+_schema: Schema;
|
package/core/IR.js.flow
CHANGED
package/core/IRPrinter.js.flow
CHANGED
@@ -377,21 +377,16 @@ function printValue(
|
|
377
377
|
if (value.kind === 'Variable') {
|
378
378
|
return '$' + value.variableName;
|
379
379
|
} else if (value.kind === 'ObjectValue') {
|
380
|
-
|
381
|
-
type && schema.isInputObject(type),
|
382
|
-
'GraphQLIRPrinter: Need an InputObject type to print objects.',
|
383
|
-
);
|
384
|
-
const inputType = schema.assertInputObjectType(type);
|
380
|
+
const inputType = type != null ? schema.asInputObjectType(type) : null;
|
385
381
|
const pairs = value.fields
|
386
382
|
.map(field => {
|
387
383
|
const fieldConfig =
|
388
|
-
|
384
|
+
inputType != null
|
389
385
|
? schema.hasField(inputType, field.name)
|
390
386
|
? schema.getFieldConfig(schema.expectField(inputType, field.name))
|
391
387
|
: null
|
392
388
|
: null;
|
393
|
-
const innerValue =
|
394
|
-
fieldConfig && printValue(schema, field.value, fieldConfig.type);
|
389
|
+
const innerValue = printValue(schema, field.value, fieldConfig?.type);
|
395
390
|
return innerValue == null ? null : field.name + ': ' + innerValue;
|
396
391
|
})
|
397
392
|
.filter(Boolean);
|
@@ -20,6 +20,7 @@ const DeferStreamTransform = require('../transforms/DeferStreamTransform');
|
|
20
20
|
const DisallowIdAsAlias = require('../transforms/DisallowIdAsAlias');
|
21
21
|
const DisallowTypenameOnRoot = require('../transforms/DisallowTypenameOnRoot');
|
22
22
|
const FieldHandleTransform = require('../transforms/FieldHandleTransform');
|
23
|
+
const FilterCompilerDirectivesTransform = require('../transforms/FilterCompilerDirectivesTransform');
|
23
24
|
const FilterDirectivesTransform = require('../transforms/FilterDirectivesTransform');
|
24
25
|
const FlattenTransform = require('../transforms/FlattenTransform');
|
25
26
|
const GenerateIDFieldTransform = require('../transforms/GenerateIDFieldTransform');
|
@@ -28,9 +29,11 @@ const InlineDataFragmentTransform = require('../transforms/InlineDataFragmentTra
|
|
28
29
|
const InlineFragmentsTransform = require('../transforms/InlineFragmentsTransform');
|
29
30
|
const MaskTransform = require('../transforms/MaskTransform');
|
30
31
|
const MatchTransform = require('../transforms/MatchTransform');
|
32
|
+
const ReactFlightComponentTransform = require('../transforms/ReactFlightComponentTransform');
|
31
33
|
const RefetchableFragmentTransform = require('../transforms/RefetchableFragmentTransform');
|
32
34
|
const RelayDirectiveTransform = require('../transforms/RelayDirectiveTransform');
|
33
35
|
const RelayFlowGenerator = require('../language/javascript/RelayFlowGenerator');
|
36
|
+
const RequiredFieldTransform = require('../transforms/RequiredFieldTransform');
|
34
37
|
const SkipClientExtensionsTransform = require('../transforms/SkipClientExtensionsTransform');
|
35
38
|
const SkipHandleFieldTransform = require('../transforms/SkipHandleFieldTransform');
|
36
39
|
const SkipRedundantNodesTransform = require('../transforms/SkipRedundantNodesTransform');
|
@@ -51,6 +54,7 @@ const relaySchemaExtensions: $ReadOnlyArray<string> = [
|
|
51
54
|
DeclarativeConnectionMutationTransform.SCHEMA_EXTENSION,
|
52
55
|
InlineDataFragmentTransform.SCHEMA_EXTENSION,
|
53
56
|
MatchTransform.SCHEMA_EXTENSION,
|
57
|
+
RequiredFieldTransform.SCHEMA_EXTENSION,
|
54
58
|
RefetchableFragmentTransform.SCHEMA_EXTENSION,
|
55
59
|
RelayDirectiveTransform.SCHEMA_EXTENSION,
|
56
60
|
RelayFlowGenerator.SCHEMA_EXTENSION,
|
@@ -68,6 +72,7 @@ const relayCommonTransforms: $ReadOnlyArray<IRTransform> = [
|
|
68
72
|
MatchTransform.transform,
|
69
73
|
RefetchableFragmentTransform.transform,
|
70
74
|
DeferStreamTransform.transform,
|
75
|
+
ReactFlightComponentTransform.transform,
|
71
76
|
];
|
72
77
|
|
73
78
|
// Transforms applied to fragments used for reading data from a store
|
@@ -76,6 +81,7 @@ const relayFragmentTransforms: $ReadOnlyArray<IRTransform> = [
|
|
76
81
|
FieldHandleTransform.transform,
|
77
82
|
InlineDataFragmentTransform.transform,
|
78
83
|
FlattenTransform.transformWithOptions({isForCodegen: true}),
|
84
|
+
RequiredFieldTransform.transform,
|
79
85
|
SkipRedundantNodesTransform.transform,
|
80
86
|
];
|
81
87
|
|
@@ -93,6 +99,7 @@ const relayQueryTransforms: $ReadOnlyArray<IRTransform> = [
|
|
93
99
|
|
94
100
|
// Transforms applied to the code used to process a query response.
|
95
101
|
const relayCodegenTransforms: $ReadOnlyArray<IRTransform> = [
|
102
|
+
FilterCompilerDirectivesTransform.transform,
|
96
103
|
SkipUnreachableNodeTransform.transform,
|
97
104
|
InlineFragmentsTransform.transform,
|
98
105
|
// NOTE: For the codegen context, we make sure to run ClientExtensions
|
package/core/Schema.js.flow
CHANGED
@@ -133,10 +133,21 @@ type InternalArgumentStruct = $ReadOnly<{|
|
|
133
133
|
|
134
134
|
type FieldDefinition = {|
|
135
135
|
+arguments: $ReadOnlyArray<InternalArgumentStruct>,
|
136
|
+
+directives: ?$ReadOnlyArray<DirectiveInvocation>,
|
136
137
|
+type: TypeNode,
|
137
138
|
+isClient: boolean,
|
138
139
|
|};
|
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
|
+
|
140
151
|
type InternalDirectiveMap = Map<string, InternalDirectiveStruct>;
|
141
152
|
|
142
153
|
type InternalDirectiveStruct = $ReadOnly<{|
|
@@ -251,6 +262,7 @@ class NonNull<+T> {
|
|
251
262
|
*/
|
252
263
|
class Field {
|
253
264
|
+args: $ReadOnlyMap<string, Argument>;
|
265
|
+
+directives: ?$ReadOnlyArray<DirectiveInvocation>;
|
254
266
|
+belongsTo: CompositeType | InputObjectType;
|
255
267
|
+name: string;
|
256
268
|
+type: TypeID;
|
@@ -262,6 +274,7 @@ class Field {
|
|
262
274
|
type: TypeID,
|
263
275
|
belongsTo: CompositeType | InputObjectType,
|
264
276
|
args: $ReadOnlyArray<InternalArgumentStruct>,
|
277
|
+
directives: ?$ReadOnlyArray<DirectiveInvocation>,
|
265
278
|
isClient: boolean,
|
266
279
|
) {
|
267
280
|
this.name = name;
|
@@ -269,6 +282,7 @@ class Field {
|
|
269
282
|
this.belongsTo = belongsTo;
|
270
283
|
this.isClient = isClient;
|
271
284
|
this.args = parseInputArgumentDefinitionsMap(schema, args);
|
285
|
+
this.directives = directives;
|
272
286
|
}
|
273
287
|
}
|
274
288
|
|
@@ -528,6 +542,21 @@ class Schema {
|
|
528
542
|
return type;
|
529
543
|
}
|
530
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
|
+
|
531
560
|
areEqualTypes(typeA: TypeID, typeB: TypeID): boolean {
|
532
561
|
if (typeA === typeB) {
|
533
562
|
return true;
|
@@ -758,6 +787,13 @@ class Schema {
|
|
758
787
|
return type;
|
759
788
|
}
|
760
789
|
|
790
|
+
asInputObjectType(type: TypeID): ?InputObjectTypeID {
|
791
|
+
if (!isInputObject(type)) {
|
792
|
+
return null;
|
793
|
+
}
|
794
|
+
return type;
|
795
|
+
}
|
796
|
+
|
761
797
|
assertInterfaceType(type: TypeID): InterfaceTypeID {
|
762
798
|
if (!isInterface(type)) {
|
763
799
|
throw createCompilerError(
|
@@ -1066,6 +1102,7 @@ class Schema {
|
|
1066
1102
|
fieldType,
|
1067
1103
|
this.assertCompositeType(type),
|
1068
1104
|
fieldDefinition.arguments,
|
1105
|
+
fieldDefinition.directives,
|
1069
1106
|
fieldDefinition.isClient,
|
1070
1107
|
),
|
1071
1108
|
);
|
@@ -1078,7 +1115,7 @@ class Schema {
|
|
1078
1115
|
const fieldType = this.expectTypeFromAST(typeNode);
|
1079
1116
|
fieldsMap.set(
|
1080
1117
|
fieldName,
|
1081
|
-
new Field(this, fieldName, fieldType, type, [], false),
|
1118
|
+
new Field(this, fieldName, fieldType, type, [], null, false),
|
1082
1119
|
);
|
1083
1120
|
}
|
1084
1121
|
}
|
@@ -1111,6 +1148,7 @@ class Schema {
|
|
1111
1148
|
this.getNonNullType(this.expectStringType()),
|
1112
1149
|
type,
|
1113
1150
|
[],
|
1151
|
+
null,
|
1114
1152
|
false, // isClient === false
|
1115
1153
|
);
|
1116
1154
|
this._typeNameMap.set(type, typename);
|
@@ -1127,6 +1165,7 @@ class Schema {
|
|
1127
1165
|
this.getNonNullType(this.expectIdType()),
|
1128
1166
|
type,
|
1129
1167
|
[],
|
1168
|
+
null,
|
1130
1169
|
true, // isClient === true
|
1131
1170
|
);
|
1132
1171
|
this._clientIdMap.set(type, clientId);
|
@@ -1685,6 +1724,21 @@ class TypeMap {
|
|
1685
1724
|
};
|
1686
1725
|
})
|
1687
1726
|
: [],
|
1727
|
+
directives: fieldNode.directives
|
1728
|
+
? fieldNode.directives.map(directive => {
|
1729
|
+
return {
|
1730
|
+
name: directive.name.value,
|
1731
|
+
args: directive.arguments
|
1732
|
+
? directive.arguments.map(arg => {
|
1733
|
+
return {
|
1734
|
+
name: arg.name.value,
|
1735
|
+
value: arg.value,
|
1736
|
+
};
|
1737
|
+
})
|
1738
|
+
: [],
|
1739
|
+
};
|
1740
|
+
})
|
1741
|
+
: null,
|
1688
1742
|
type: fieldNode.type,
|
1689
1743
|
isClient: isClient,
|
1690
1744
|
});
|
package/index.js
CHANGED
@@ -46,79 +46,10 @@ const BABYLON_OPTIONS = {
|
|
46
46
|
|
47
47
|
function find(text: string): $ReadOnlyArray<GraphQLTag> {
|
48
48
|
const result: Array<GraphQLTag> = [];
|
49
|
+
// $FlowFixMe Discovered when typing babel/parser
|
49
50
|
const ast = babylon.parse(text, BABYLON_OPTIONS);
|
50
51
|
|
51
52
|
const visitors = {
|
52
|
-
CallExpression: node => {
|
53
|
-
const callee = node.callee;
|
54
|
-
if (
|
55
|
-
!(
|
56
|
-
(callee.type === 'Identifier' &&
|
57
|
-
CREATE_CONTAINER_FUNCTIONS[callee.name]) ||
|
58
|
-
(callee.kind === 'MemberExpression' &&
|
59
|
-
callee.object.type === 'Identifier' &&
|
60
|
-
callee.object.value === 'Relay' &&
|
61
|
-
callee.property.type === 'Identifier' &&
|
62
|
-
CREATE_CONTAINER_FUNCTIONS[callee.property.name])
|
63
|
-
)
|
64
|
-
) {
|
65
|
-
traverse(node, visitors);
|
66
|
-
return;
|
67
|
-
}
|
68
|
-
const fragments = node.arguments[1];
|
69
|
-
if (fragments.type === 'ObjectExpression') {
|
70
|
-
fragments.properties.forEach(property => {
|
71
|
-
invariant(
|
72
|
-
property.type === 'ObjectProperty' &&
|
73
|
-
property.key.type === 'Identifier' &&
|
74
|
-
property.value.type === 'TaggedTemplateExpression',
|
75
|
-
'FindGraphQLTags: `%s` expects fragment definitions to be ' +
|
76
|
-
'`key: graphql`.',
|
77
|
-
node.callee.name,
|
78
|
-
);
|
79
|
-
invariant(
|
80
|
-
isGraphQLModernOrDeprecatedTag(property.value.tag),
|
81
|
-
'FindGraphQLTags: `%s` expects fragment definitions to be tagged ' +
|
82
|
-
'with `graphql`, got `%s`.',
|
83
|
-
node.callee.name,
|
84
|
-
getSourceTextForLocation(text, property.value.tag.loc),
|
85
|
-
);
|
86
|
-
if (isGraphQLTag(property.value.tag)) {
|
87
|
-
result.push({
|
88
|
-
keyName: property.key.name,
|
89
|
-
template: getGraphQLText(property.value.quasi),
|
90
|
-
sourceLocationOffset: getSourceLocationOffset(
|
91
|
-
property.value.quasi,
|
92
|
-
),
|
93
|
-
});
|
94
|
-
}
|
95
|
-
});
|
96
|
-
} else {
|
97
|
-
invariant(
|
98
|
-
fragments && fragments.type === 'TaggedTemplateExpression',
|
99
|
-
'FindGraphQLTags: `%s` expects a second argument of fragment ' +
|
100
|
-
'definitions.',
|
101
|
-
node.callee.name,
|
102
|
-
);
|
103
|
-
invariant(
|
104
|
-
isGraphQLModernOrDeprecatedTag(fragments.tag),
|
105
|
-
'FindGraphQLTags: `%s` expects fragment definitions to be tagged ' +
|
106
|
-
'with `graphql`, got `%s`.',
|
107
|
-
node.callee.name,
|
108
|
-
getSourceTextForLocation(text, fragments.tag.loc),
|
109
|
-
);
|
110
|
-
result.push({
|
111
|
-
keyName: null,
|
112
|
-
template: getGraphQLText(fragments.quasi),
|
113
|
-
sourceLocationOffset: getSourceLocationOffset(fragments.quasi),
|
114
|
-
});
|
115
|
-
}
|
116
|
-
|
117
|
-
// Visit remaining arguments
|
118
|
-
for (let ii = 2; ii < node.arguments.length; ii++) {
|
119
|
-
visit(node.arguments[ii], visitors);
|
120
|
-
}
|
121
|
-
},
|
122
53
|
TaggedTemplateExpression: node => {
|
123
54
|
if (isGraphQLTag(node.tag)) {
|
124
55
|
result.push({
|
@@ -133,12 +64,6 @@ function find(text: string): $ReadOnlyArray<GraphQLTag> {
|
|
133
64
|
return result;
|
134
65
|
}
|
135
66
|
|
136
|
-
const CREATE_CONTAINER_FUNCTIONS = Object.create(null, {
|
137
|
-
createFragmentContainer: {value: true},
|
138
|
-
createPaginationContainer: {value: true},
|
139
|
-
createRefetchContainer: {value: true},
|
140
|
-
});
|
141
|
-
|
142
67
|
const IGNORED_KEYS = {
|
143
68
|
comments: true,
|
144
69
|
end: true,
|
@@ -154,13 +79,6 @@ function isGraphQLTag(tag): boolean {
|
|
154
79
|
return tag.type === 'Identifier' && tag.name === 'graphql';
|
155
80
|
}
|
156
81
|
|
157
|
-
function isGraphQLModernOrDeprecatedTag(tag): boolean {
|
158
|
-
return (
|
159
|
-
tag.type === 'Identifier' &&
|
160
|
-
(tag.name === 'graphql' || tag.name === 'graphql_DEPRECATED')
|
161
|
-
);
|
162
|
-
}
|
163
|
-
|
164
82
|
function getTemplateNode(quasi) {
|
165
83
|
const quasis = quasi.quasis;
|
166
84
|
invariant(
|
@@ -170,10 +88,6 @@ function getTemplateNode(quasi) {
|
|
170
88
|
return quasis[0];
|
171
89
|
}
|
172
90
|
|
173
|
-
function getGraphQLText(quasi): string {
|
174
|
-
return getTemplateNode(quasi).value.raw;
|
175
|
-
}
|
176
|
-
|
177
91
|
function getSourceLocationOffset(quasi) {
|
178
92
|
const loc = getTemplateNode(quasi).loc.start;
|
179
93
|
return {
|
@@ -182,16 +96,6 @@ function getSourceLocationOffset(quasi) {
|
|
182
96
|
};
|
183
97
|
}
|
184
98
|
|
185
|
-
function getSourceTextForLocation(text, loc) {
|
186
|
-
if (loc == null) {
|
187
|
-
return '(source unavailable)';
|
188
|
-
}
|
189
|
-
const lines = text.split('\n').slice(loc.start.line - 1, loc.end.line);
|
190
|
-
lines[0] = lines[0].slice(loc.start.column);
|
191
|
-
lines[lines.length - 1] = lines[lines.length - 1].slice(0, loc.end.column);
|
192
|
-
return lines.join('\n');
|
193
|
-
}
|
194
|
-
|
195
99
|
function invariant(condition, msg, ...args) {
|
196
100
|
if (!condition) {
|
197
101
|
throw new Error(util.format(msg, ...args));
|
@@ -199,6 +103,7 @@ function invariant(condition, msg, ...args) {
|
|
199
103
|
}
|
200
104
|
|
201
105
|
function visit(node, visitors) {
|
106
|
+
// $FlowFixMe Discovered when typing babel
|
202
107
|
const fn = visitors[node.type];
|
203
108
|
if (fn != null) {
|
204
109
|
fn(node);
|
@@ -15,13 +15,13 @@
|
|
15
15
|
const invariant = require('invariant');
|
16
16
|
const t = require('@babel/types');
|
17
17
|
|
18
|
-
type BabelAST =
|
18
|
+
type BabelAST = BabelNode_DEPRECATED;
|
19
19
|
|
20
20
|
/**
|
21
21
|
* type NAME = any;
|
22
22
|
*/
|
23
23
|
function anyTypeAlias(name: string): BabelAST {
|
24
|
-
return t.typeAlias(t.identifier(name),
|
24
|
+
return t.typeAlias(t.identifier(name), undefined, t.anyTypeAnnotation());
|
25
25
|
}
|
26
26
|
|
27
27
|
/**
|
@@ -29,9 +29,7 @@ function anyTypeAlias(name: string): BabelAST {
|
|
29
29
|
* PROPS
|
30
30
|
* |}
|
31
31
|
*/
|
32
|
-
function exactObjectTypeAnnotation(
|
33
|
-
props: $ReadOnlyArray<BabelAST>,
|
34
|
-
): $FlowFixMe {
|
32
|
+
function exactObjectTypeAnnotation(props: Array<BabelAST>): $FlowFixMe {
|
35
33
|
const typeAnnotation = t.objectTypeAnnotation(props);
|
36
34
|
typeAnnotation.exact = true;
|
37
35
|
return typeAnnotation;
|
@@ -43,9 +41,7 @@ function exactObjectTypeAnnotation(
|
|
43
41
|
* ...
|
44
42
|
* }
|
45
43
|
*/
|
46
|
-
function inexactObjectTypeAnnotation(
|
47
|
-
props: $ReadOnlyArray<BabelAST>,
|
48
|
-
): $FlowFixMe {
|
44
|
+
function inexactObjectTypeAnnotation(props: Array<BabelAST>): $FlowFixMe {
|
49
45
|
const typeAnnotation = t.objectTypeAnnotation(props);
|
50
46
|
typeAnnotation.inexact = true;
|
51
47
|
return typeAnnotation;
|
@@ -56,9 +52,9 @@ function inexactObjectTypeAnnotation(
|
|
56
52
|
*/
|
57
53
|
function exportType(name: string, type: BabelAST): $FlowFixMe {
|
58
54
|
return t.exportNamedDeclaration(
|
59
|
-
t.typeAlias(t.identifier(name),
|
55
|
+
t.typeAlias(t.identifier(name), undefined, type),
|
60
56
|
[],
|
61
|
-
|
57
|
+
undefined,
|
62
58
|
);
|
63
59
|
}
|
64
60
|
|
@@ -67,12 +63,12 @@ function exportType(name: string, type: BabelAST): $FlowFixMe {
|
|
67
63
|
*/
|
68
64
|
function exportTypes(names: $ReadOnlyArray<string>): $FlowFixMe {
|
69
65
|
const res = t.exportNamedDeclaration(
|
70
|
-
|
66
|
+
undefined,
|
71
67
|
names.map(name =>
|
72
68
|
t.exportSpecifier(t.identifier(name), t.identifier(name)),
|
73
69
|
),
|
74
70
|
|
75
|
-
|
71
|
+
undefined,
|
76
72
|
);
|
77
73
|
res.exportKind = 'type';
|
78
74
|
return res;
|
@@ -85,7 +81,7 @@ function declareExportOpaqueType(name: string, value: string): $FlowFixMe {
|
|
85
81
|
return t.declareExportDeclaration(
|
86
82
|
t.declareOpaqueType(
|
87
83
|
t.identifier(name),
|
88
|
-
|
84
|
+
undefined,
|
89
85
|
t.genericTypeAnnotation(t.identifier(value)),
|
90
86
|
),
|
91
87
|
);
|
@@ -113,7 +109,7 @@ function importTypes(
|
|
113
109
|
*
|
114
110
|
* TYPES[0] & TYPES[1] & ...
|
115
111
|
*/
|
116
|
-
function intersectionTypeAnnotation(types:
|
112
|
+
function intersectionTypeAnnotation(types: Array<BabelAST>): BabelAST {
|
117
113
|
invariant(
|
118
114
|
types.length > 0,
|
119
115
|
'RelayFlowBabelFactories: cannot create an intersection of 0 types',
|
@@ -155,7 +151,7 @@ function stringLiteralTypeAnnotation(value: string): $FlowFixMe {
|
|
155
151
|
*
|
156
152
|
* TYPES[0] | TYPES[1] | ...
|
157
153
|
*/
|
158
|
-
function unionTypeAnnotation(types:
|
154
|
+
function unionTypeAnnotation(types: Array<BabelAST>): BabelAST {
|
159
155
|
invariant(
|
160
156
|
types.length > 0,
|
161
157
|
'RelayFlowBabelFactories: cannot create a union of 0 types',
|