graphql 16.11.0 → 16.13.0
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/README.md +49 -6
- package/execution/execute.d.ts +14 -1
- package/execution/execute.js +72 -13
- package/execution/execute.mjs +72 -13
- package/execution/subscribe.js +1 -0
- package/execution/subscribe.mjs +2 -0
- package/index.d.ts +11 -0
- package/index.js +24 -0
- package/index.mjs +6 -2
- package/language/ast.d.ts +45 -1
- package/language/ast.js +14 -1
- package/language/ast.mjs +14 -1
- package/language/index.d.ts +14 -1
- package/language/index.js +12 -0
- package/language/index.mjs +8 -1
- package/language/kinds.d.ts +6 -0
- package/language/kinds.js +5 -0
- package/language/kinds.mjs +5 -0
- package/language/lexer.d.ts +52 -1
- package/language/lexer.js +10 -0
- package/language/lexer.mjs +17 -4
- package/language/parser.d.ts +30 -3
- package/language/parser.js +129 -13
- package/language/parser.mjs +123 -11
- package/language/predicates.d.ts +4 -0
- package/language/predicates.js +11 -0
- package/language/predicates.mjs +9 -0
- package/language/printer.js +42 -13
- package/language/printer.mjs +42 -13
- package/language/schemaCoordinateLexer.d.ts +43 -0
- package/language/schemaCoordinateLexer.js +171 -0
- package/language/schemaCoordinateLexer.mjs +122 -0
- package/language/tokenKind.d.ts +1 -0
- package/language/tokenKind.js +1 -0
- package/language/tokenKind.mjs +1 -0
- package/package.json +1 -1
- package/utilities/index.d.ts +5 -0
- package/utilities/index.js +14 -0
- package/utilities/index.mjs +5 -0
- package/utilities/resolveSchemaCoordinate.d.ts +80 -0
- package/utilities/resolveSchemaCoordinate.js +260 -0
- package/utilities/resolveSchemaCoordinate.mjs +243 -0
- package/validation/rules/ValuesOfCorrectTypeRule.js +7 -36
- package/validation/rules/ValuesOfCorrectTypeRule.mjs +7 -35
- package/validation/validate.js +12 -0
- package/validation/validate.mjs +13 -2
- package/version.js +2 -2
- package/version.mjs +2 -2
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.resolveASTSchemaCoordinate = resolveASTSchemaCoordinate;
|
|
7
|
+
exports.resolveSchemaCoordinate = resolveSchemaCoordinate;
|
|
8
|
+
|
|
9
|
+
var _inspect = require('../jsutils/inspect.js');
|
|
10
|
+
|
|
11
|
+
var _kinds = require('../language/kinds.js');
|
|
12
|
+
|
|
13
|
+
var _parser = require('../language/parser.js');
|
|
14
|
+
|
|
15
|
+
var _definition = require('../type/definition.js');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A schema coordinate is resolved in the context of a GraphQL schema to
|
|
19
|
+
* uniquely identify a schema element. It returns undefined if the schema
|
|
20
|
+
* coordinate does not resolve to a schema element, meta-field, or introspection
|
|
21
|
+
* schema element. It will throw if the containing schema element (if
|
|
22
|
+
* applicable) does not exist.
|
|
23
|
+
*
|
|
24
|
+
* https://spec.graphql.org/draft/#sec-Schema-Coordinates.Semantics
|
|
25
|
+
*/
|
|
26
|
+
function resolveSchemaCoordinate(schema, schemaCoordinate) {
|
|
27
|
+
return resolveASTSchemaCoordinate(
|
|
28
|
+
schema,
|
|
29
|
+
(0, _parser.parseSchemaCoordinate)(schemaCoordinate),
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* TypeCoordinate : Name
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
function resolveTypeCoordinate(schema, schemaCoordinate) {
|
|
37
|
+
// 1. Let {typeName} be the value of {Name}.
|
|
38
|
+
const typeName = schemaCoordinate.name.value;
|
|
39
|
+
const type = schema.getType(typeName); // 2. Return the type in the {schema} named {typeName} if it exists.
|
|
40
|
+
|
|
41
|
+
if (type == null) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
kind: 'NamedType',
|
|
47
|
+
type,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* MemberCoordinate : Name . Name
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
function resolveMemberCoordinate(schema, schemaCoordinate) {
|
|
55
|
+
// 1. Let {typeName} be the value of the first {Name}.
|
|
56
|
+
// 2. Let {type} be the type in the {schema} named {typeName}.
|
|
57
|
+
const typeName = schemaCoordinate.name.value;
|
|
58
|
+
const type = schema.getType(typeName); // 3. Assert: {type} must exist, and must be an Enum, Input Object, Object or Interface type.
|
|
59
|
+
|
|
60
|
+
if (!type) {
|
|
61
|
+
throw new Error(
|
|
62
|
+
`Expected ${(0, _inspect.inspect)(
|
|
63
|
+
typeName,
|
|
64
|
+
)} to be defined as a type in the schema.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
!(0, _definition.isEnumType)(type) &&
|
|
70
|
+
!(0, _definition.isInputObjectType)(type) &&
|
|
71
|
+
!(0, _definition.isObjectType)(type) &&
|
|
72
|
+
!(0, _definition.isInterfaceType)(type)
|
|
73
|
+
) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Expected ${(0, _inspect.inspect)(
|
|
76
|
+
typeName,
|
|
77
|
+
)} to be an Enum, Input Object, Object or Interface type.`,
|
|
78
|
+
);
|
|
79
|
+
} // 4. If {type} is an Enum type:
|
|
80
|
+
|
|
81
|
+
if ((0, _definition.isEnumType)(type)) {
|
|
82
|
+
// 1. Let {enumValueName} be the value of the second {Name}.
|
|
83
|
+
const enumValueName = schemaCoordinate.memberName.value;
|
|
84
|
+
const enumValue = type.getValue(enumValueName); // 2. Return the enum value of {type} named {enumValueName} if it exists.
|
|
85
|
+
|
|
86
|
+
if (enumValue == null) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
kind: 'EnumValue',
|
|
92
|
+
type,
|
|
93
|
+
enumValue,
|
|
94
|
+
};
|
|
95
|
+
} // 5. Otherwise, if {type} is an Input Object type:
|
|
96
|
+
|
|
97
|
+
if ((0, _definition.isInputObjectType)(type)) {
|
|
98
|
+
// 1. Let {inputFieldName} be the value of the second {Name}.
|
|
99
|
+
const inputFieldName = schemaCoordinate.memberName.value;
|
|
100
|
+
const inputField = type.getFields()[inputFieldName]; // 2. Return the input field of {type} named {inputFieldName} if it exists.
|
|
101
|
+
|
|
102
|
+
if (inputField == null) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
kind: 'InputField',
|
|
108
|
+
type,
|
|
109
|
+
inputField,
|
|
110
|
+
};
|
|
111
|
+
} // 6. Otherwise:
|
|
112
|
+
// 1. Let {fieldName} be the value of the second {Name}.
|
|
113
|
+
|
|
114
|
+
const fieldName = schemaCoordinate.memberName.value;
|
|
115
|
+
const field = type.getFields()[fieldName]; // 2. Return the field of {type} named {fieldName} if it exists.
|
|
116
|
+
|
|
117
|
+
if (field == null) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
kind: 'Field',
|
|
123
|
+
type,
|
|
124
|
+
field,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* ArgumentCoordinate : Name . Name ( Name : )
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
function resolveArgumentCoordinate(schema, schemaCoordinate) {
|
|
132
|
+
// 1. Let {typeName} be the value of the first {Name}.
|
|
133
|
+
// 2. Let {type} be the type in the {schema} named {typeName}.
|
|
134
|
+
const typeName = schemaCoordinate.name.value;
|
|
135
|
+
const type = schema.getType(typeName); // 3. Assert: {type} must exist, and be an Object or Interface type.
|
|
136
|
+
|
|
137
|
+
if (type == null) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`Expected ${(0, _inspect.inspect)(
|
|
140
|
+
typeName,
|
|
141
|
+
)} to be defined as a type in the schema.`,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (
|
|
146
|
+
!(0, _definition.isObjectType)(type) &&
|
|
147
|
+
!(0, _definition.isInterfaceType)(type)
|
|
148
|
+
) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`Expected ${(0, _inspect.inspect)(
|
|
151
|
+
typeName,
|
|
152
|
+
)} to be an object type or interface type.`,
|
|
153
|
+
);
|
|
154
|
+
} // 4. Let {fieldName} be the value of the second {Name}.
|
|
155
|
+
// 5. Let {field} be the field of {type} named {fieldName}.
|
|
156
|
+
|
|
157
|
+
const fieldName = schemaCoordinate.fieldName.value;
|
|
158
|
+
const field = type.getFields()[fieldName]; // 7. Assert: {field} must exist.
|
|
159
|
+
|
|
160
|
+
if (field == null) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Expected ${(0, _inspect.inspect)(
|
|
163
|
+
fieldName,
|
|
164
|
+
)} to exist as a field of type ${(0, _inspect.inspect)(
|
|
165
|
+
typeName,
|
|
166
|
+
)} in the schema.`,
|
|
167
|
+
);
|
|
168
|
+
} // 7. Let {fieldArgumentName} be the value of the third {Name}.
|
|
169
|
+
|
|
170
|
+
const fieldArgumentName = schemaCoordinate.argumentName.value;
|
|
171
|
+
const fieldArgument = field.args.find(
|
|
172
|
+
(arg) => arg.name === fieldArgumentName,
|
|
173
|
+
); // 8. Return the argument of {field} named {fieldArgumentName} if it exists.
|
|
174
|
+
|
|
175
|
+
if (fieldArgument == null) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
kind: 'FieldArgument',
|
|
181
|
+
type,
|
|
182
|
+
field,
|
|
183
|
+
fieldArgument,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* DirectiveCoordinate : \@ Name
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
function resolveDirectiveCoordinate(schema, schemaCoordinate) {
|
|
191
|
+
// 1. Let {directiveName} be the value of {Name}.
|
|
192
|
+
const directiveName = schemaCoordinate.name.value;
|
|
193
|
+
const directive = schema.getDirective(directiveName); // 2. Return the directive in the {schema} named {directiveName} if it exists.
|
|
194
|
+
|
|
195
|
+
if (!directive) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
kind: 'Directive',
|
|
201
|
+
directive,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* DirectiveArgumentCoordinate : \@ Name ( Name : )
|
|
206
|
+
*/
|
|
207
|
+
|
|
208
|
+
function resolveDirectiveArgumentCoordinate(schema, schemaCoordinate) {
|
|
209
|
+
// 1. Let {directiveName} be the value of the first {Name}.
|
|
210
|
+
// 2. Let {directive} be the directive in the {schema} named {directiveName}.
|
|
211
|
+
const directiveName = schemaCoordinate.name.value;
|
|
212
|
+
const directive = schema.getDirective(directiveName); // 3. Assert {directive} must exist.
|
|
213
|
+
|
|
214
|
+
if (!directive) {
|
|
215
|
+
throw new Error(
|
|
216
|
+
`Expected ${(0, _inspect.inspect)(
|
|
217
|
+
directiveName,
|
|
218
|
+
)} to be defined as a directive in the schema.`,
|
|
219
|
+
);
|
|
220
|
+
} // 4. Let {directiveArgumentName} be the value of the second {Name}.
|
|
221
|
+
|
|
222
|
+
const {
|
|
223
|
+
argumentName: { value: directiveArgumentName },
|
|
224
|
+
} = schemaCoordinate;
|
|
225
|
+
const directiveArgument = directive.args.find(
|
|
226
|
+
(arg) => arg.name === directiveArgumentName,
|
|
227
|
+
); // 5. Return the argument of {directive} named {directiveArgumentName} if it exists.
|
|
228
|
+
|
|
229
|
+
if (!directiveArgument) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
kind: 'DirectiveArgument',
|
|
235
|
+
directive,
|
|
236
|
+
directiveArgument,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Resolves schema coordinate from a parsed SchemaCoordinate node.
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
function resolveASTSchemaCoordinate(schema, schemaCoordinate) {
|
|
244
|
+
switch (schemaCoordinate.kind) {
|
|
245
|
+
case _kinds.Kind.TYPE_COORDINATE:
|
|
246
|
+
return resolveTypeCoordinate(schema, schemaCoordinate);
|
|
247
|
+
|
|
248
|
+
case _kinds.Kind.MEMBER_COORDINATE:
|
|
249
|
+
return resolveMemberCoordinate(schema, schemaCoordinate);
|
|
250
|
+
|
|
251
|
+
case _kinds.Kind.ARGUMENT_COORDINATE:
|
|
252
|
+
return resolveArgumentCoordinate(schema, schemaCoordinate);
|
|
253
|
+
|
|
254
|
+
case _kinds.Kind.DIRECTIVE_COORDINATE:
|
|
255
|
+
return resolveDirectiveCoordinate(schema, schemaCoordinate);
|
|
256
|
+
|
|
257
|
+
case _kinds.Kind.DIRECTIVE_ARGUMENT_COORDINATE:
|
|
258
|
+
return resolveDirectiveArgumentCoordinate(schema, schemaCoordinate);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { inspect } from '../jsutils/inspect.mjs';
|
|
2
|
+
import { Kind } from '../language/kinds.mjs';
|
|
3
|
+
import { parseSchemaCoordinate } from '../language/parser.mjs';
|
|
4
|
+
import {
|
|
5
|
+
isEnumType,
|
|
6
|
+
isInputObjectType,
|
|
7
|
+
isInterfaceType,
|
|
8
|
+
isObjectType,
|
|
9
|
+
} from '../type/definition.mjs';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A schema coordinate is resolved in the context of a GraphQL schema to
|
|
13
|
+
* uniquely identify a schema element. It returns undefined if the schema
|
|
14
|
+
* coordinate does not resolve to a schema element, meta-field, or introspection
|
|
15
|
+
* schema element. It will throw if the containing schema element (if
|
|
16
|
+
* applicable) does not exist.
|
|
17
|
+
*
|
|
18
|
+
* https://spec.graphql.org/draft/#sec-Schema-Coordinates.Semantics
|
|
19
|
+
*/
|
|
20
|
+
export function resolveSchemaCoordinate(schema, schemaCoordinate) {
|
|
21
|
+
return resolveASTSchemaCoordinate(
|
|
22
|
+
schema,
|
|
23
|
+
parseSchemaCoordinate(schemaCoordinate),
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* TypeCoordinate : Name
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
function resolveTypeCoordinate(schema, schemaCoordinate) {
|
|
31
|
+
// 1. Let {typeName} be the value of {Name}.
|
|
32
|
+
const typeName = schemaCoordinate.name.value;
|
|
33
|
+
const type = schema.getType(typeName); // 2. Return the type in the {schema} named {typeName} if it exists.
|
|
34
|
+
|
|
35
|
+
if (type == null) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
kind: 'NamedType',
|
|
41
|
+
type,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* MemberCoordinate : Name . Name
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
function resolveMemberCoordinate(schema, schemaCoordinate) {
|
|
49
|
+
// 1. Let {typeName} be the value of the first {Name}.
|
|
50
|
+
// 2. Let {type} be the type in the {schema} named {typeName}.
|
|
51
|
+
const typeName = schemaCoordinate.name.value;
|
|
52
|
+
const type = schema.getType(typeName); // 3. Assert: {type} must exist, and must be an Enum, Input Object, Object or Interface type.
|
|
53
|
+
|
|
54
|
+
if (!type) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
`Expected ${inspect(typeName)} to be defined as a type in the schema.`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (
|
|
61
|
+
!isEnumType(type) &&
|
|
62
|
+
!isInputObjectType(type) &&
|
|
63
|
+
!isObjectType(type) &&
|
|
64
|
+
!isInterfaceType(type)
|
|
65
|
+
) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`Expected ${inspect(
|
|
68
|
+
typeName,
|
|
69
|
+
)} to be an Enum, Input Object, Object or Interface type.`,
|
|
70
|
+
);
|
|
71
|
+
} // 4. If {type} is an Enum type:
|
|
72
|
+
|
|
73
|
+
if (isEnumType(type)) {
|
|
74
|
+
// 1. Let {enumValueName} be the value of the second {Name}.
|
|
75
|
+
const enumValueName = schemaCoordinate.memberName.value;
|
|
76
|
+
const enumValue = type.getValue(enumValueName); // 2. Return the enum value of {type} named {enumValueName} if it exists.
|
|
77
|
+
|
|
78
|
+
if (enumValue == null) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
kind: 'EnumValue',
|
|
84
|
+
type,
|
|
85
|
+
enumValue,
|
|
86
|
+
};
|
|
87
|
+
} // 5. Otherwise, if {type} is an Input Object type:
|
|
88
|
+
|
|
89
|
+
if (isInputObjectType(type)) {
|
|
90
|
+
// 1. Let {inputFieldName} be the value of the second {Name}.
|
|
91
|
+
const inputFieldName = schemaCoordinate.memberName.value;
|
|
92
|
+
const inputField = type.getFields()[inputFieldName]; // 2. Return the input field of {type} named {inputFieldName} if it exists.
|
|
93
|
+
|
|
94
|
+
if (inputField == null) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
kind: 'InputField',
|
|
100
|
+
type,
|
|
101
|
+
inputField,
|
|
102
|
+
};
|
|
103
|
+
} // 6. Otherwise:
|
|
104
|
+
// 1. Let {fieldName} be the value of the second {Name}.
|
|
105
|
+
|
|
106
|
+
const fieldName = schemaCoordinate.memberName.value;
|
|
107
|
+
const field = type.getFields()[fieldName]; // 2. Return the field of {type} named {fieldName} if it exists.
|
|
108
|
+
|
|
109
|
+
if (field == null) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
kind: 'Field',
|
|
115
|
+
type,
|
|
116
|
+
field,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* ArgumentCoordinate : Name . Name ( Name : )
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
function resolveArgumentCoordinate(schema, schemaCoordinate) {
|
|
124
|
+
// 1. Let {typeName} be the value of the first {Name}.
|
|
125
|
+
// 2. Let {type} be the type in the {schema} named {typeName}.
|
|
126
|
+
const typeName = schemaCoordinate.name.value;
|
|
127
|
+
const type = schema.getType(typeName); // 3. Assert: {type} must exist, and be an Object or Interface type.
|
|
128
|
+
|
|
129
|
+
if (type == null) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Expected ${inspect(typeName)} to be defined as a type in the schema.`,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!isObjectType(type) && !isInterfaceType(type)) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`Expected ${inspect(typeName)} to be an object type or interface type.`,
|
|
138
|
+
);
|
|
139
|
+
} // 4. Let {fieldName} be the value of the second {Name}.
|
|
140
|
+
// 5. Let {field} be the field of {type} named {fieldName}.
|
|
141
|
+
|
|
142
|
+
const fieldName = schemaCoordinate.fieldName.value;
|
|
143
|
+
const field = type.getFields()[fieldName]; // 7. Assert: {field} must exist.
|
|
144
|
+
|
|
145
|
+
if (field == null) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Expected ${inspect(fieldName)} to exist as a field of type ${inspect(
|
|
148
|
+
typeName,
|
|
149
|
+
)} in the schema.`,
|
|
150
|
+
);
|
|
151
|
+
} // 7. Let {fieldArgumentName} be the value of the third {Name}.
|
|
152
|
+
|
|
153
|
+
const fieldArgumentName = schemaCoordinate.argumentName.value;
|
|
154
|
+
const fieldArgument = field.args.find(
|
|
155
|
+
(arg) => arg.name === fieldArgumentName,
|
|
156
|
+
); // 8. Return the argument of {field} named {fieldArgumentName} if it exists.
|
|
157
|
+
|
|
158
|
+
if (fieldArgument == null) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
kind: 'FieldArgument',
|
|
164
|
+
type,
|
|
165
|
+
field,
|
|
166
|
+
fieldArgument,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* DirectiveCoordinate : \@ Name
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
function resolveDirectiveCoordinate(schema, schemaCoordinate) {
|
|
174
|
+
// 1. Let {directiveName} be the value of {Name}.
|
|
175
|
+
const directiveName = schemaCoordinate.name.value;
|
|
176
|
+
const directive = schema.getDirective(directiveName); // 2. Return the directive in the {schema} named {directiveName} if it exists.
|
|
177
|
+
|
|
178
|
+
if (!directive) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
kind: 'Directive',
|
|
184
|
+
directive,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* DirectiveArgumentCoordinate : \@ Name ( Name : )
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
function resolveDirectiveArgumentCoordinate(schema, schemaCoordinate) {
|
|
192
|
+
// 1. Let {directiveName} be the value of the first {Name}.
|
|
193
|
+
// 2. Let {directive} be the directive in the {schema} named {directiveName}.
|
|
194
|
+
const directiveName = schemaCoordinate.name.value;
|
|
195
|
+
const directive = schema.getDirective(directiveName); // 3. Assert {directive} must exist.
|
|
196
|
+
|
|
197
|
+
if (!directive) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
`Expected ${inspect(
|
|
200
|
+
directiveName,
|
|
201
|
+
)} to be defined as a directive in the schema.`,
|
|
202
|
+
);
|
|
203
|
+
} // 4. Let {directiveArgumentName} be the value of the second {Name}.
|
|
204
|
+
|
|
205
|
+
const {
|
|
206
|
+
argumentName: { value: directiveArgumentName },
|
|
207
|
+
} = schemaCoordinate;
|
|
208
|
+
const directiveArgument = directive.args.find(
|
|
209
|
+
(arg) => arg.name === directiveArgumentName,
|
|
210
|
+
); // 5. Return the argument of {directive} named {directiveArgumentName} if it exists.
|
|
211
|
+
|
|
212
|
+
if (!directiveArgument) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
kind: 'DirectiveArgument',
|
|
218
|
+
directive,
|
|
219
|
+
directiveArgument,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Resolves schema coordinate from a parsed SchemaCoordinate node.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
export function resolveASTSchemaCoordinate(schema, schemaCoordinate) {
|
|
227
|
+
switch (schemaCoordinate.kind) {
|
|
228
|
+
case Kind.TYPE_COORDINATE:
|
|
229
|
+
return resolveTypeCoordinate(schema, schemaCoordinate);
|
|
230
|
+
|
|
231
|
+
case Kind.MEMBER_COORDINATE:
|
|
232
|
+
return resolveMemberCoordinate(schema, schemaCoordinate);
|
|
233
|
+
|
|
234
|
+
case Kind.ARGUMENT_COORDINATE:
|
|
235
|
+
return resolveArgumentCoordinate(schema, schemaCoordinate);
|
|
236
|
+
|
|
237
|
+
case Kind.DIRECTIVE_COORDINATE:
|
|
238
|
+
return resolveDirectiveCoordinate(schema, schemaCoordinate);
|
|
239
|
+
|
|
240
|
+
case Kind.DIRECTIVE_ARGUMENT_COORDINATE:
|
|
241
|
+
return resolveDirectiveArgumentCoordinate(schema, schemaCoordinate);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -85,13 +85,7 @@ function ValuesOfCorrectTypeRule(context) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
if (type.isOneOf) {
|
|
88
|
-
validateOneOfInputObject(
|
|
89
|
-
context,
|
|
90
|
-
node,
|
|
91
|
-
type,
|
|
92
|
-
fieldNodeMap,
|
|
93
|
-
variableDefinitions,
|
|
94
|
-
);
|
|
88
|
+
validateOneOfInputObject(context, node, type, fieldNodeMap);
|
|
95
89
|
}
|
|
96
90
|
},
|
|
97
91
|
|
|
@@ -138,6 +132,11 @@ function ValuesOfCorrectTypeRule(context) {
|
|
|
138
132
|
EnumValue: (node) => isValidValueNode(context, node),
|
|
139
133
|
IntValue: (node) => isValidValueNode(context, node),
|
|
140
134
|
FloatValue: (node) => isValidValueNode(context, node),
|
|
135
|
+
// Descriptions are string values that would not validate according
|
|
136
|
+
// to the below logic, but since (per the specification) descriptions must
|
|
137
|
+
// not affect validation, they are ignored entirely when visiting the AST
|
|
138
|
+
// and do not require special handling.
|
|
139
|
+
// See https://spec.graphql.org/draft/#sec-Descriptions
|
|
141
140
|
StringValue: (node) => isValidValueNode(context, node),
|
|
142
141
|
BooleanValue: (node) => isValidValueNode(context, node),
|
|
143
142
|
};
|
|
@@ -214,13 +213,7 @@ function isValidValueNode(context, node) {
|
|
|
214
213
|
}
|
|
215
214
|
}
|
|
216
215
|
|
|
217
|
-
function validateOneOfInputObject(
|
|
218
|
-
context,
|
|
219
|
-
node,
|
|
220
|
-
type,
|
|
221
|
-
fieldNodeMap,
|
|
222
|
-
variableDefinitions,
|
|
223
|
-
) {
|
|
216
|
+
function validateOneOfInputObject(context, node, type, fieldNodeMap) {
|
|
224
217
|
var _fieldNodeMap$keys$;
|
|
225
218
|
|
|
226
219
|
const keys = Object.keys(fieldNodeMap);
|
|
@@ -244,9 +237,6 @@ function validateOneOfInputObject(
|
|
|
244
237
|
? void 0
|
|
245
238
|
: _fieldNodeMap$keys$.value;
|
|
246
239
|
const isNullLiteral = !value || value.kind === _kinds.Kind.NULL;
|
|
247
|
-
const isVariable =
|
|
248
|
-
(value === null || value === void 0 ? void 0 : value.kind) ===
|
|
249
|
-
_kinds.Kind.VARIABLE;
|
|
250
240
|
|
|
251
241
|
if (isNullLiteral) {
|
|
252
242
|
context.reportError(
|
|
@@ -257,24 +247,5 @@ function validateOneOfInputObject(
|
|
|
257
247
|
},
|
|
258
248
|
),
|
|
259
249
|
);
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (isVariable) {
|
|
264
|
-
const variableName = value.name.value;
|
|
265
|
-
const definition = variableDefinitions[variableName];
|
|
266
|
-
const isNullableVariable =
|
|
267
|
-
definition.type.kind !== _kinds.Kind.NON_NULL_TYPE;
|
|
268
|
-
|
|
269
|
-
if (isNullableVariable) {
|
|
270
|
-
context.reportError(
|
|
271
|
-
new _GraphQLError.GraphQLError(
|
|
272
|
-
`Variable "${variableName}" must be non-nullable to be used for OneOf Input Object "${type.name}".`,
|
|
273
|
-
{
|
|
274
|
-
nodes: [node],
|
|
275
|
-
},
|
|
276
|
-
),
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
250
|
}
|
|
280
251
|
}
|
|
@@ -74,13 +74,7 @@ export function ValuesOfCorrectTypeRule(context) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
if (type.isOneOf) {
|
|
77
|
-
validateOneOfInputObject(
|
|
78
|
-
context,
|
|
79
|
-
node,
|
|
80
|
-
type,
|
|
81
|
-
fieldNodeMap,
|
|
82
|
-
variableDefinitions,
|
|
83
|
-
);
|
|
77
|
+
validateOneOfInputObject(context, node, type, fieldNodeMap);
|
|
84
78
|
}
|
|
85
79
|
},
|
|
86
80
|
|
|
@@ -123,6 +117,11 @@ export function ValuesOfCorrectTypeRule(context) {
|
|
|
123
117
|
EnumValue: (node) => isValidValueNode(context, node),
|
|
124
118
|
IntValue: (node) => isValidValueNode(context, node),
|
|
125
119
|
FloatValue: (node) => isValidValueNode(context, node),
|
|
120
|
+
// Descriptions are string values that would not validate according
|
|
121
|
+
// to the below logic, but since (per the specification) descriptions must
|
|
122
|
+
// not affect validation, they are ignored entirely when visiting the AST
|
|
123
|
+
// and do not require special handling.
|
|
124
|
+
// See https://spec.graphql.org/draft/#sec-Descriptions
|
|
126
125
|
StringValue: (node) => isValidValueNode(context, node),
|
|
127
126
|
BooleanValue: (node) => isValidValueNode(context, node),
|
|
128
127
|
};
|
|
@@ -194,13 +193,7 @@ function isValidValueNode(context, node) {
|
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
195
|
|
|
197
|
-
function validateOneOfInputObject(
|
|
198
|
-
context,
|
|
199
|
-
node,
|
|
200
|
-
type,
|
|
201
|
-
fieldNodeMap,
|
|
202
|
-
variableDefinitions,
|
|
203
|
-
) {
|
|
196
|
+
function validateOneOfInputObject(context, node, type, fieldNodeMap) {
|
|
204
197
|
var _fieldNodeMap$keys$;
|
|
205
198
|
|
|
206
199
|
const keys = Object.keys(fieldNodeMap);
|
|
@@ -224,9 +217,6 @@ function validateOneOfInputObject(
|
|
|
224
217
|
? void 0
|
|
225
218
|
: _fieldNodeMap$keys$.value;
|
|
226
219
|
const isNullLiteral = !value || value.kind === Kind.NULL;
|
|
227
|
-
const isVariable =
|
|
228
|
-
(value === null || value === void 0 ? void 0 : value.kind) ===
|
|
229
|
-
Kind.VARIABLE;
|
|
230
220
|
|
|
231
221
|
if (isNullLiteral) {
|
|
232
222
|
context.reportError(
|
|
@@ -234,23 +224,5 @@ function validateOneOfInputObject(
|
|
|
234
224
|
nodes: [node],
|
|
235
225
|
}),
|
|
236
226
|
);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (isVariable) {
|
|
241
|
-
const variableName = value.name.value;
|
|
242
|
-
const definition = variableDefinitions[variableName];
|
|
243
|
-
const isNullableVariable = definition.type.kind !== Kind.NON_NULL_TYPE;
|
|
244
|
-
|
|
245
|
-
if (isNullableVariable) {
|
|
246
|
-
context.reportError(
|
|
247
|
-
new GraphQLError(
|
|
248
|
-
`Variable "${variableName}" must be non-nullable to be used for OneOf Input Object "${type.name}".`,
|
|
249
|
-
{
|
|
250
|
-
nodes: [node],
|
|
251
|
-
},
|
|
252
|
-
),
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
227
|
}
|
|
256
228
|
}
|
package/validation/validate.js
CHANGED
|
@@ -10,8 +10,12 @@ exports.validateSDL = validateSDL;
|
|
|
10
10
|
|
|
11
11
|
var _devAssert = require('../jsutils/devAssert.js');
|
|
12
12
|
|
|
13
|
+
var _mapValue = require('../jsutils/mapValue.js');
|
|
14
|
+
|
|
13
15
|
var _GraphQLError = require('../error/GraphQLError.js');
|
|
14
16
|
|
|
17
|
+
var _ast = require('../language/ast.js');
|
|
18
|
+
|
|
15
19
|
var _visitor = require('../language/visitor.js');
|
|
16
20
|
|
|
17
21
|
var _validate = require('../type/validate.js');
|
|
@@ -22,6 +26,12 @@ var _specifiedRules = require('./specifiedRules.js');
|
|
|
22
26
|
|
|
23
27
|
var _ValidationContext = require('./ValidationContext.js');
|
|
24
28
|
|
|
29
|
+
// Per the specification, descriptions must not affect validation.
|
|
30
|
+
// See https://spec.graphql.org/draft/#sec-Descriptions
|
|
31
|
+
const QueryDocumentKeysToValidate = (0, _mapValue.mapValue)(
|
|
32
|
+
_ast.QueryDocumentKeys,
|
|
33
|
+
(keys) => keys.filter((key) => key !== 'description'),
|
|
34
|
+
);
|
|
25
35
|
/**
|
|
26
36
|
* Implements the "Validation" section of the spec.
|
|
27
37
|
*
|
|
@@ -42,6 +52,7 @@ var _ValidationContext = require('./ValidationContext.js');
|
|
|
42
52
|
* Optionally a custom TypeInfo instance may be provided. If not provided, one
|
|
43
53
|
* will be created from the provided schema.
|
|
44
54
|
*/
|
|
55
|
+
|
|
45
56
|
function validate(
|
|
46
57
|
schema,
|
|
47
58
|
documentAST,
|
|
@@ -91,6 +102,7 @@ function validate(
|
|
|
91
102
|
(0, _visitor.visit)(
|
|
92
103
|
documentAST,
|
|
93
104
|
(0, _TypeInfo.visitWithTypeInfo)(typeInfo, visitor),
|
|
105
|
+
QueryDocumentKeysToValidate,
|
|
94
106
|
);
|
|
95
107
|
} catch (e) {
|
|
96
108
|
if (e !== abortObj) {
|