1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Digia\GraphQL\Validation; |
4
|
|
|
|
5
|
|
|
use function Digia\GraphQL\Util\quotedOrList; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* @param string $definitionName |
9
|
|
|
* @return string |
10
|
|
|
*/ |
11
|
|
|
function nonExecutableDefinitionMessage(string $definitionName): string |
12
|
|
|
{ |
13
|
|
|
return sprintf('The %s definition is not executable.', $definitionName); |
14
|
|
|
} |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @param string $fieldName |
18
|
|
|
* @param string $type |
19
|
|
|
* @param array $suggestedTypeNames |
20
|
|
|
* @param array $suggestedFieldNames |
21
|
|
|
* @return string |
22
|
|
|
*/ |
23
|
|
|
function undefinedFieldMessage( |
24
|
|
|
string $fieldName, |
25
|
|
|
string $type, |
26
|
|
|
array $suggestedTypeNames, |
27
|
|
|
array $suggestedFieldNames |
28
|
|
|
): string { |
29
|
|
|
$message = sprintf('Cannot query field "%s" on type "%s".', $fieldName, $type); |
30
|
|
|
if (!empty($suggestedTypeNames)) { |
31
|
|
|
return $message . ' ' . sprintf( |
32
|
|
|
'Did you mean to use an inline fragment on %s?', |
33
|
|
|
quotedOrList($suggestedTypeNames) |
34
|
|
|
); |
35
|
|
|
} |
36
|
|
|
if (!empty($suggestedFieldNames)) { |
37
|
|
|
return $message . ' ' . sprintf('Did you mean %s?', quotedOrList($suggestedFieldNames)); |
38
|
|
|
} |
39
|
|
|
return $message; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @param string $type |
44
|
|
|
* @return string |
45
|
|
|
*/ |
46
|
|
|
function inlineFragmentOnNonCompositeMessage(string $typeName): string |
47
|
|
|
{ |
48
|
|
|
return sprintf('Fragment cannot condition on non composite type "%s".', $typeName); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @param string $fragmentName |
53
|
|
|
* @param string $typeName |
54
|
|
|
* @return string |
55
|
|
|
*/ |
56
|
|
|
function fragmentOnNonCompositeMessage(string $fragmentName, string $typeName): string |
57
|
|
|
{ |
58
|
|
|
return sprintf('Fragment "%s" cannot condition on non composite type "%s".', $fragmentName, $typeName); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param string $argumentName |
63
|
|
|
* @param string $fieldName |
64
|
|
|
* @param string $typeName |
65
|
|
|
* @param array $suggestedArguments |
66
|
|
|
* @return string |
67
|
|
|
*/ |
68
|
|
|
function unknownArgumentMessage( |
69
|
|
|
string $argumentName, |
70
|
|
|
string $fieldName, |
71
|
|
|
string $typeName, |
72
|
|
|
array $suggestedArguments |
73
|
|
|
): string { |
74
|
|
|
$message = sprintf('Unknown argument "%s" on field "%s" of type "%s".', $argumentName, $fieldName, $typeName); |
75
|
|
|
if (!empty($suggestedArguments)) { |
76
|
|
|
return $message . ' ' . sprintf('Did you mean %s', quotedOrList($suggestedArguments)); |
77
|
|
|
} |
78
|
|
|
return $message; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @param string $argumentName |
83
|
|
|
* @param string $directiveName |
84
|
|
|
* @param array $suggestedArguments |
85
|
|
|
* @return string |
86
|
|
|
*/ |
87
|
|
|
function unknownDirectiveArgumentMessage(string $argumentName, string $directiveName, array $suggestedArguments): string |
88
|
|
|
{ |
89
|
|
|
$message = sprintf('Unknown argument "%s" on directive "@%s".', $argumentName, $directiveName); |
90
|
|
|
if (!empty($suggestedArguments)) { |
91
|
|
|
return $message . ' ' . sprintf('Did you mean %s', quotedOrList($suggestedArguments)); |
92
|
|
|
} |
93
|
|
|
return $message; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @param string $directiveName |
98
|
|
|
* @return string |
99
|
|
|
*/ |
100
|
|
|
function unknownDirectiveMessage(string $directiveName): string |
101
|
|
|
{ |
102
|
|
|
return sprintf('Unknown directive "%s".', $directiveName); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @param string $directiveName |
107
|
|
|
* @param string $location |
108
|
|
|
* @return string |
109
|
|
|
*/ |
110
|
|
|
function misplacedDirectiveMessage(string $directiveName, string $location): string |
111
|
|
|
{ |
112
|
|
|
return sprintf('Directive "%s" may not be used on %s.', $directiveName, $location); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @param string $fragmentName |
117
|
|
|
* @return string |
118
|
|
|
*/ |
119
|
|
|
function unknownFragmentMessage(string $fragmentName): string |
120
|
|
|
{ |
121
|
|
|
return sprintf('Unknown fragment "%s".', $fragmentName); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* @param string $typeName |
126
|
|
|
* @param array $suggestedTypes |
127
|
|
|
* @return string |
128
|
|
|
*/ |
129
|
|
|
function unknownTypeMessage(string $typeName, array $suggestedTypes): string |
130
|
|
|
{ |
131
|
|
|
$message = sprintf('Unknown type "%s".', $typeName); |
132
|
|
|
if (!empty($suggestedTypes)) { |
133
|
|
|
return $message . ' ' . sprintf('Did you mean %s?', quotedOrList($suggestedTypes)); |
134
|
|
|
} |
135
|
|
|
return $message; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* @return string |
140
|
|
|
*/ |
141
|
|
|
function anonymousOperationNotAloneMessage(): string |
142
|
|
|
{ |
143
|
|
|
return 'This anonymous operation must be the only defined operation.'; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @param string $fragmentName |
148
|
|
|
* @param array $spreadNames |
149
|
|
|
* @return string |
150
|
|
|
*/ |
151
|
|
|
function fragmentCycleMessage(string $fragmentName, array $spreadNames): string |
152
|
|
|
{ |
153
|
|
|
$via = !empty($spreadNames) ? ' via ' . implode(', ', $spreadNames) : ''; |
154
|
|
|
return sprintf('Cannot spread fragment "%s" within itself%s.', $fragmentName, $via); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* @param string $variableName |
159
|
|
|
* @param null|string $operationName |
160
|
|
|
* @return string |
161
|
|
|
*/ |
162
|
|
|
function undefinedVariableMessage(string $variableName, ?string $operationName = null): string |
163
|
|
|
{ |
164
|
|
|
/** @noinspection IsEmptyFunctionUsageInspection */ |
165
|
|
|
return !empty($operationName) |
166
|
|
|
? sprintf('Variable "$%s" is not defined by operation "%s".', $variableName, $operationName) |
167
|
|
|
: sprintf('Variable "$%s" is not defined.', $variableName); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* @param string $fragmentName |
172
|
|
|
* @return string |
173
|
|
|
*/ |
174
|
|
|
function unusedFragmentMessage(string $fragmentName): string |
175
|
|
|
{ |
176
|
|
|
return sprintf('Fragment "%s" is never used.', $fragmentName); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param string $variableName |
181
|
|
|
* @param null|string $operationName |
182
|
|
|
* @return string |
183
|
|
|
*/ |
184
|
|
|
function unusedVariableMessage(string $variableName, ?string $operationName = null): string |
185
|
|
|
{ |
186
|
|
|
/** @noinspection IsEmptyFunctionUsageInspection */ |
187
|
|
|
return !empty($operationName) |
188
|
|
|
? sprintf('Variable "$%s" is never used in operation "%s".', $variableName, $operationName) |
189
|
|
|
: sprintf('Variable "$%s" is never used.', $variableName); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* @param string $reasonName |
194
|
|
|
* @param mixed $reason |
195
|
|
|
* @return string |
196
|
|
|
*/ |
197
|
|
|
function fieldsConflictMessage(string $responseName, $reason): string |
198
|
|
|
{ |
199
|
|
|
return sprintf( |
200
|
|
|
'Fields "%s" conflict because %s. Use different aliases on the fields to fetch both if this was intentional.', |
201
|
|
|
$responseName, |
202
|
|
|
conflictReasonMessage($reason) |
203
|
|
|
); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* @param array|string $reason |
208
|
|
|
* @return string |
209
|
|
|
*/ |
210
|
|
|
function conflictReasonMessage($reason): string |
211
|
|
|
{ |
212
|
|
|
if (\is_string($reason)) { |
213
|
|
|
return $reason; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
if (\is_array($reason) && \is_string($reason[0])) { |
217
|
|
|
return conflictReasonMessage([$reason]); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
return implode(' and ', array_map(function ($reason) { |
221
|
|
|
[$responseName, $subreason] = $reason; |
222
|
|
|
return sprintf('subfields "%s" conflict because %s', $responseName, conflictReasonMessage($subreason)); |
223
|
|
|
}, $reason)); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* @param string $fragmentName |
228
|
|
|
* @param string $parentType |
229
|
|
|
* @param string $fragmentType |
230
|
|
|
* @return string |
231
|
|
|
*/ |
232
|
|
|
function typeIncompatibleSpreadMessage( |
233
|
|
|
string $fragmentName, |
234
|
|
|
string $parentType, |
235
|
|
|
string $fragmentType |
236
|
|
|
): string { |
237
|
|
|
return sprintf( |
238
|
|
|
'Fragment "%s" cannot be spread here as objects of type "%s" can never be of type "%s".', |
239
|
|
|
$fragmentName, |
240
|
|
|
$parentType, |
241
|
|
|
$fragmentType |
242
|
|
|
); |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* @param string $parentType |
247
|
|
|
* @param string $fragmentType |
248
|
|
|
* @return string |
249
|
|
|
*/ |
250
|
|
|
function typeIncompatibleAnonymousSpreadMessage(string $parentType, string $fragmentType): string |
251
|
|
|
{ |
252
|
|
|
return sprintf( |
253
|
|
|
'Fragment cannot be spread here as objects of type "%s" can never be of type "%s".', |
254
|
|
|
$parentType, |
255
|
|
|
$fragmentType |
256
|
|
|
); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @param string $fieldName |
261
|
|
|
* @param string $argumentName |
262
|
|
|
* @param string $typeName |
263
|
|
|
* @return string |
264
|
|
|
*/ |
265
|
|
|
function missingFieldArgumentMessage(string $fieldName, string $argumentName, string $typeName): string |
266
|
|
|
{ |
267
|
|
|
return sprintf( |
268
|
|
|
'Field "%s" argument "%s" of type "%s" is required but not provided.', |
269
|
|
|
$fieldName, |
270
|
|
|
$argumentName, |
271
|
|
|
$typeName |
272
|
|
|
); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* @param string $directiveName |
277
|
|
|
* @param string $argumentName |
278
|
|
|
* @param string $typeName |
279
|
|
|
* @return string |
280
|
|
|
*/ |
281
|
|
|
function missingDirectiveArgumentMessage(string $directiveName, string $argumentName, string $typeName): string |
282
|
|
|
{ |
283
|
|
|
return sprintf( |
284
|
|
|
'Directive "%s" argument "%s" of type "%s" is required but not provided.', |
285
|
|
|
$directiveName, |
286
|
|
|
$argumentName, |
287
|
|
|
$typeName |
288
|
|
|
); |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* @param string $fieldName |
293
|
|
|
* @param string $typeName |
294
|
|
|
* @return string |
295
|
|
|
*/ |
296
|
|
|
function noSubselectionAllowedMessage(string $fieldName, string $typeName): string |
297
|
|
|
{ |
298
|
|
|
return sprintf('Field "%s" must not have a selection since type "%s" has no subfields.', $fieldName, $typeName); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
/** |
302
|
|
|
* @param string $fieldName |
303
|
|
|
* @param string $typeName |
304
|
|
|
* @return string |
305
|
|
|
*/ |
306
|
|
|
function requiresSubselectionMessage(string $fieldName, string $typeName): string |
307
|
|
|
{ |
308
|
|
|
return sprintf( |
309
|
|
|
'Field "%s" of type "%s" must have a selection of subfields. Did you mean "%s { ... }"?', |
310
|
|
|
$fieldName, |
311
|
|
|
$typeName, |
312
|
|
|
$fieldName |
313
|
|
|
); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* @param null|string $name |
318
|
|
|
* @return string |
319
|
|
|
*/ |
320
|
|
|
function singleFieldOnlyMessage(?string $name): string |
321
|
|
|
{ |
322
|
|
|
$prefix = $name ? "Subscription {$name}" : 'Anonymous subscription'; |
323
|
|
|
return sprintf('%s must select only one top level field.', $prefix); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
/** |
327
|
|
|
* @param string $argumentName |
328
|
|
|
* @return string |
329
|
|
|
*/ |
330
|
|
|
function duplicateArgumentMessage(string $argumentName): string |
331
|
|
|
{ |
332
|
|
|
return sprintf('There can be only one argument named "%s".', $argumentName); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
/** |
336
|
|
|
* @param string $directiveName |
337
|
|
|
* @return string |
338
|
|
|
*/ |
339
|
|
|
function duplicateDirectiveMessage(string $directiveName): string |
340
|
|
|
{ |
341
|
|
|
return sprintf('The directive "%s" can only be used once at this location.', $directiveName); |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
/** |
345
|
|
|
* @param string $fragmentName |
346
|
|
|
* @return string |
347
|
|
|
*/ |
348
|
|
|
function duplicateFragmentMessage(string $fragmentName): string |
349
|
|
|
{ |
350
|
|
|
return sprintf('There can be only one fragment named "%s".', $fragmentName); |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* @param string $fieldName |
355
|
|
|
* @return string |
356
|
|
|
*/ |
357
|
|
|
function duplicateInputFieldMessage(string $fieldName): string |
358
|
|
|
{ |
359
|
|
|
return sprintf('There can be only one input field named "%s".', $fieldName); |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
/** |
363
|
|
|
* @param string $operationName |
364
|
|
|
* @return string |
365
|
|
|
*/ |
366
|
|
|
function duplicateOperationMessage(string $operationName): string |
367
|
|
|
{ |
368
|
|
|
return sprintf('There can be only one operation named "%s".', $operationName); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* @param string $variableName |
373
|
|
|
* @return string |
374
|
|
|
*/ |
375
|
|
|
function duplicateVariableMessage(string $variableName): string |
376
|
|
|
{ |
377
|
|
|
return sprintf('There can be only one variable named "%s".', $variableName); |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* @param string $variableName |
382
|
|
|
* @param string $typeName |
383
|
|
|
* @return string |
384
|
|
|
*/ |
385
|
|
|
function nonInputTypeOnVariableMessage(string $variableName, string $typeName): string |
386
|
|
|
{ |
387
|
|
|
return sprintf('Variable "$%s" cannot be non-input type "%s".', $variableName, $typeName); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* @param string $variableName |
392
|
|
|
* @param string $typeName |
393
|
|
|
* @param string $guessedTypeName |
394
|
|
|
* @return string |
395
|
|
|
*/ |
396
|
|
|
function variableDefaultValueNotAllowedMessage(string $variableName, string $typeName, string $guessedTypeName): string |
397
|
|
|
{ |
398
|
|
|
return sprintf( |
399
|
|
|
'Variable "$%s" of type "%s" is required and will not use the default value. Perhaps you meant to use type "%s".', |
400
|
|
|
$variableName, |
401
|
|
|
$typeName, |
402
|
|
|
$guessedTypeName |
403
|
|
|
); |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
/** |
407
|
|
|
* @param string $variableName |
408
|
|
|
* @param string $typeName |
409
|
|
|
* @param string $expectedTypeName |
410
|
|
|
* @return string |
411
|
|
|
*/ |
412
|
|
|
function badVariablePositionMessage(string $variableName, string $typeName, string $expectedTypeName): string |
413
|
|
|
{ |
414
|
|
|
return sprintf( |
415
|
|
|
'Variable "$%s" of type "%s" used in position expecting type "%s".', |
416
|
|
|
$variableName, |
417
|
|
|
$typeName, |
418
|
|
|
$expectedTypeName |
419
|
|
|
); |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* @param string $typeName |
424
|
|
|
* @param string $valueName |
425
|
|
|
* @param null|string $message |
426
|
|
|
* @return string |
427
|
|
|
*/ |
428
|
|
|
function badValueMessage(string $typeName, string $valueName, ?string $message = null): string |
429
|
|
|
{ |
430
|
|
|
return sprintf('Expected type %s, found %s%s', $typeName, $valueName, null !== $message ? "; $message" : '.'); |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* @param string $typeName |
435
|
|
|
* @param string $fieldName |
436
|
|
|
* @param string $fieldTypeName |
437
|
|
|
* @return string |
438
|
|
|
*/ |
439
|
|
|
function requiredFieldMessage(string $typeName, string $fieldName, string $fieldTypeName): string |
440
|
|
|
{ |
441
|
|
|
return sprintf('Field %s.%s of required type %s was not provided.', $typeName, $fieldName, $fieldTypeName); |
442
|
|
|
} |
443
|
|
|
|
444
|
|
|
/** |
445
|
|
|
* @param string $typeName |
446
|
|
|
* @param string $fieldName |
447
|
|
|
* @param null|string $message |
448
|
|
|
* @return string |
449
|
|
|
*/ |
450
|
|
|
function unknownFieldMessage(string $typeName, string $fieldName, ?string $message = null): string |
451
|
|
|
{ |
452
|
|
|
return sprintf( |
453
|
|
|
'Field %s is not defined by type %s%s', |
454
|
|
|
$fieldName, |
455
|
|
|
$typeName, |
456
|
|
|
null !== $message ? "; $message" : '.' |
457
|
|
|
); |
458
|
|
|
} |
459
|
|
|
|