Skip to content

Commit 66cdc81

Browse files
committed
Reference AST nodes from type, schema and directive definitions
1 parent 0de76ca commit 66cdc81

9 files changed

+263
-49
lines changed

src/type/__tests__/definition-test.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ describe('Type System: Example', () => {
180180
description: undefined,
181181
isDeprecated: true,
182182
deprecationReason: 'Just because',
183-
value: 'foo'
183+
value: 'foo',
184+
astNode: null,
184185
});
185186
});
186187

@@ -200,13 +201,15 @@ describe('Type System: Example', () => {
200201
isDeprecated: false,
201202
deprecationReason: undefined,
202203
value: null,
204+
astNode: null,
203205
},
204206
{
205207
name: 'UNDEFINED',
206208
description: undefined,
207209
isDeprecated: false,
208210
deprecationReason: undefined,
209211
value: undefined,
212+
astNode: null,
210213
},
211214
]);
212215
});

src/type/definition.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import isNullish from '../jsutils/isNullish';
1313
import { ENUM } from '../language/kinds';
1414
import { assertValidName } from '../utilities/assertValidName';
1515
import type {
16+
ASTNode,
1617
OperationDefinitionNode,
1718
FieldNode,
1819
FragmentDefinitionNode,
@@ -294,13 +295,15 @@ function resolveThunk<T>(thunk: Thunk<T>): T {
294295
export class GraphQLScalarType {
295296
name: string;
296297
description: ?string;
298+
astNode: ?ASTNode;
297299

298300
_scalarConfig: GraphQLScalarTypeConfig<*, *>;
299301

300302
constructor(config: GraphQLScalarTypeConfig<*, *>): void {
301303
assertValidName(config.name);
302304
this.name = config.name;
303305
this.description = config.description;
306+
this.astNode = config.astNode || null;
304307
invariant(
305308
typeof config.serialize === 'function',
306309
`${this.name} must provide "serialize" function. If this custom Scalar ` +
@@ -364,6 +367,7 @@ GraphQLScalarType.prototype.toJSON =
364367
export type GraphQLScalarTypeConfig<TInternal, TExternal> = {
365368
name: string;
366369
description?: ?string;
370+
astNode?: ?ASTNode;
367371
serialize: (value: mixed) => ?TExternal;
368372
parseValue?: (value: mixed) => ?TInternal;
369373
parseLiteral?: (valueNode: ValueNode) => ?TInternal;
@@ -411,6 +415,8 @@ export type GraphQLScalarTypeConfig<TInternal, TExternal> = {
411415
export class GraphQLObjectType {
412416
name: string;
413417
description: ?string;
418+
astNode: ?ASTNode;
419+
extensionASTNodes: Array<ASTNode>;
414420
isTypeOf: ?GraphQLIsTypeOfFn<*, *>;
415421

416422
_typeConfig: GraphQLObjectTypeConfig<*, *>;
@@ -421,6 +427,8 @@ export class GraphQLObjectType {
421427
assertValidName(config.name, config.isIntrospection);
422428
this.name = config.name;
423429
this.description = config.description;
430+
this.astNode = config.astNode || null;
431+
this.extensionASTNodes = config.extensionASTNodes || [];
424432
if (config.isTypeOf) {
425433
invariant(
426434
typeof config.isTypeOf === 'function',
@@ -562,7 +570,8 @@ function defineFieldMap<TSource, TContext>(
562570
name: argName,
563571
description: arg.description === undefined ? null : arg.description,
564572
type: arg.type,
565-
defaultValue: arg.defaultValue
573+
defaultValue: arg.defaultValue,
574+
astNode: arg.astNode,
566575
};
567576
});
568577
}
@@ -587,6 +596,8 @@ export type GraphQLObjectTypeConfig<TSource, TContext> = {
587596
isTypeOf?: ?GraphQLIsTypeOfFn<TSource, TContext>;
588597
description?: ?string;
589598
isIntrospection?: boolean;
599+
astNode?: ?ASTNode;
600+
extensionASTNodes?: ?Array<ASTNode>;
590601
};
591602

592603
export type GraphQLTypeResolver<TSource, TContext> = (
@@ -630,6 +641,7 @@ export type GraphQLFieldConfig<TSource, TContext> = {
630641
subscribe?: GraphQLFieldResolver<TSource, TContext>;
631642
deprecationReason?: ?string;
632643
description?: ?string;
644+
astNode?: ?ASTNode;
633645
};
634646

635647
export type GraphQLFieldConfigArgumentMap = {
@@ -640,6 +652,7 @@ export type GraphQLArgumentConfig = {
640652
type: GraphQLInputType;
641653
defaultValue?: mixed;
642654
description?: ?string;
655+
astNode?: ?ASTNode;
643656
};
644657

645658
export type GraphQLFieldConfigMap<TSource, TContext> = {
@@ -655,13 +668,15 @@ export type GraphQLField<TSource, TContext> = {
655668
subscribe?: GraphQLFieldResolver<TSource, TContext>;
656669
isDeprecated?: boolean;
657670
deprecationReason?: ?string;
671+
astNode?: ?ASTNode;
658672
};
659673

660674
export type GraphQLArgument = {
661675
name: string;
662676
type: GraphQLInputType;
663677
defaultValue?: mixed;
664678
description?: ?string;
679+
astNode?: ?ASTNode;
665680
};
666681

667682
export type GraphQLFieldMap<TSource, TContext> = {
@@ -691,6 +706,7 @@ export type GraphQLFieldMap<TSource, TContext> = {
691706
export class GraphQLInterfaceType {
692707
name: string;
693708
description: ?string;
709+
astNode: ?ASTNode;
694710
resolveType: ?GraphQLTypeResolver<*, *>;
695711

696712
_typeConfig: GraphQLInterfaceTypeConfig<*, *>;
@@ -700,6 +716,7 @@ export class GraphQLInterfaceType {
700716
assertValidName(config.name);
701717
this.name = config.name;
702718
this.description = config.description;
719+
this.astNode = config.astNode || null;
703720
if (config.resolveType) {
704721
invariant(
705722
typeof config.resolveType === 'function',
@@ -737,7 +754,8 @@ export type GraphQLInterfaceTypeConfig<TSource, TContext> = {
737754
* Object type.
738755
*/
739756
resolveType?: ?GraphQLTypeResolver<TSource, TContext>,
740-
description?: ?string
757+
description?: ?string,
758+
astNode?: ?ASTNode,
741759
};
742760

743761

@@ -768,6 +786,7 @@ export type GraphQLInterfaceTypeConfig<TSource, TContext> = {
768786
export class GraphQLUnionType {
769787
name: string;
770788
description: ?string;
789+
astNode: ?ASTNode;
771790
resolveType: ?GraphQLTypeResolver<*, *>;
772791

773792
_typeConfig: GraphQLUnionTypeConfig<*, *>;
@@ -778,6 +797,7 @@ export class GraphQLUnionType {
778797
assertValidName(config.name);
779798
this.name = config.name;
780799
this.description = config.description;
800+
this.astNode = config.astNode || null;
781801
if (config.resolveType) {
782802
invariant(
783803
typeof config.resolveType === 'function',
@@ -854,6 +874,7 @@ export type GraphQLUnionTypeConfig<TSource, TContext> = {
854874
*/
855875
resolveType?: ?GraphQLTypeResolver<TSource, TContext>;
856876
description?: ?string;
877+
astNode?: ?ASTNode;
857878
};
858879

859880

@@ -882,6 +903,7 @@ export type GraphQLUnionTypeConfig<TSource, TContext> = {
882903
export class GraphQLEnumType/* <T> */ {
883904
name: string;
884905
description: ?string;
906+
astNode: ?ASTNode;
885907

886908
_enumConfig: GraphQLEnumTypeConfig/* <T> */;
887909
_values: Array<GraphQLEnumValue/* <T> */>;
@@ -892,6 +914,7 @@ export class GraphQLEnumType/* <T> */ {
892914
this.name = config.name;
893915
assertValidName(config.name, config.isIntrospection);
894916
this.description = config.description;
917+
this.astNode = config.astNode || null;
895918
this._values = defineEnumValues(this, config.values);
896919
this._enumConfig = config;
897920
}
@@ -1008,6 +1031,7 @@ function defineEnumValues(
10081031
description: value.description,
10091032
isDeprecated: Boolean(value.deprecationReason),
10101033
deprecationReason: value.deprecationReason,
1034+
astNode: value.astNode || null,
10111035
value: value.hasOwnProperty('value') ? value.value : valueName,
10121036
};
10131037
});
@@ -1017,6 +1041,7 @@ export type GraphQLEnumTypeConfig/* <T> */ = {
10171041
name: string;
10181042
values: GraphQLEnumValueConfigMap/* <T> */;
10191043
description?: ?string;
1044+
astNode?: ?ASTNode;
10201045
isIntrospection?: boolean;
10211046
};
10221047

@@ -1028,13 +1053,15 @@ export type GraphQLEnumValueConfig/* <T> */ = {
10281053
value?: any/* T */;
10291054
deprecationReason?: ?string;
10301055
description?: ?string;
1056+
astNode?: ?ASTNode;
10311057
};
10321058

10331059
export type GraphQLEnumValue/* <T> */ = {
10341060
name: string;
10351061
description: ?string;
10361062
isDeprecated?: boolean;
10371063
deprecationReason: ?string;
1064+
astNode?: ?ASTNode;
10381065
value: any/* T */;
10391066
};
10401067

@@ -1063,6 +1090,7 @@ export type GraphQLEnumValue/* <T> */ = {
10631090
export class GraphQLInputObjectType {
10641091
name: string;
10651092
description: ?string;
1093+
astNode: ?ASTNode;
10661094

10671095
_typeConfig: GraphQLInputObjectTypeConfig;
10681096
_fields: GraphQLInputFieldMap;
@@ -1071,6 +1099,7 @@ export class GraphQLInputObjectType {
10711099
assertValidName(config.name);
10721100
this.name = config.name;
10731101
this.description = config.description;
1102+
this.astNode = config.astNode || null;
10741103
this._typeConfig = config;
10751104
}
10761105

@@ -1130,12 +1159,14 @@ export type GraphQLInputObjectTypeConfig = {
11301159
name: string;
11311160
fields: Thunk<GraphQLInputFieldConfigMap>;
11321161
description?: ?string;
1162+
astNode?: ?ASTNode;
11331163
};
11341164

11351165
export type GraphQLInputFieldConfig = {
11361166
type: GraphQLInputType;
11371167
defaultValue?: mixed;
11381168
description?: ?string;
1169+
astNode?: ?ASTNode;
11391170
};
11401171

11411172
export type GraphQLInputFieldConfigMap = {
@@ -1147,6 +1178,7 @@ export type GraphQLInputField = {
11471178
type: GraphQLInputType;
11481179
defaultValue?: mixed;
11491180
description?: ?string;
1181+
astNode?: ?ASTNode;
11501182
};
11511183

11521184
export type GraphQLInputFieldMap = {

src/type/directives.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
import { GraphQLString, GraphQLBoolean } from './scalars';
1717
import invariant from '../jsutils/invariant';
1818
import { assertValidName } from '../utilities/assertValidName';
19+
import type { ASTNode } from '../language/ast';
1920

2021

2122
export const DirectiveLocation = {
@@ -52,6 +53,7 @@ export class GraphQLDirective {
5253
description: ?string;
5354
locations: Array<DirectiveLocationEnum>;
5455
args: Array<GraphQLArgument>;
56+
astNode: ?ASTNode;
5557

5658
constructor(config: GraphQLDirectiveConfig): void {
5759
invariant(config.name, 'Directive must be named.');
@@ -84,10 +86,13 @@ export class GraphQLDirective {
8486
name: argName,
8587
description: arg.description === undefined ? null : arg.description,
8688
type: arg.type,
87-
defaultValue: arg.defaultValue
89+
defaultValue: arg.defaultValue,
90+
astNode: arg.astNode || null,
8891
};
8992
});
9093
}
94+
95+
this.astNode = config.astNode || null;
9196
}
9297
}
9398

@@ -96,6 +101,7 @@ type GraphQLDirectiveConfig = {
96101
description?: ?string;
97102
locations: Array<DirectiveLocationEnum>;
98103
args?: ?GraphQLFieldConfigArgumentMap;
104+
astNode?: ?ASTNode;
99105
};
100106

101107
/**

src/type/schema.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import type {
2121
GraphQLNamedType,
2222
GraphQLAbstractType
2323
} from './definition';
24+
import type { ASTNode } from '../language/ast';
2425
import { GraphQLDirective, specifiedDirectives } from './directives';
2526
import { __Schema } from './introspection';
2627
import find from '../jsutils/find';
@@ -55,6 +56,7 @@ import { isEqualType, isTypeSubTypeOf } from '../utilities/typeComparators';
5556
*
5657
*/
5758
export class GraphQLSchema {
59+
astNode: ?ASTNode;
5860
_queryType: GraphQLObjectType;
5961
_mutationType: ?GraphQLObjectType;
6062
_subscriptionType: ?GraphQLObjectType;
@@ -107,6 +109,7 @@ export class GraphQLSchema {
107109
);
108110
// Provide specified directives (e.g. @include and @skip) by default.
109111
this._directives = config.directives || specifiedDirectives;
112+
this.astNode = config.astNode || null;
110113

111114
// Build type map now to detect any errors within this schema.
112115
let initialTypes: Array<?GraphQLNamedType> = [
@@ -227,6 +230,7 @@ type GraphQLSchemaConfig = {
227230
subscription?: ?GraphQLObjectType;
228231
types?: ?Array<GraphQLNamedType>;
229232
directives?: ?Array<GraphQLDirective>;
233+
astNode?: ?ASTNode;
230234
};
231235

232236
function typeMapReducer(map: TypeMap, type: ?GraphQLType): TypeMap {

0 commit comments

Comments
 (0)