Skip to content

Commit 52864c1

Browse files
committed
Support custom directives in SchemaPrinter
1 parent bf11070 commit 52864c1

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

src/Utils/SchemaPrinter.php

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
namespace GraphQL\Utils;
66

77
use GraphQL\Error\Error;
8+
use GraphQL\Language\AST\ArgumentNode;
9+
use GraphQL\Language\AST\DirectiveNode;
10+
use GraphQL\Language\AST\NodeKind;
811
use GraphQL\Language\Printer;
912
use GraphQL\Type\Definition\Directive;
1013
use GraphQL\Type\Definition\EnumType;
@@ -29,6 +32,7 @@
2932
use function count;
3033
use function explode;
3134
use function implode;
35+
use function iterator_to_array;
3236
use function ksort;
3337
use function mb_strlen;
3438
use function preg_match_all;
@@ -371,7 +375,7 @@ public static function printType(Type $type, array $options = []): string
371375
*/
372376
protected static function printScalar(ScalarType $type, array $options): string
373377
{
374-
return sprintf('%sscalar %s', static::printDescription($options, $type), $type->name);
378+
return sprintf('%sscalar %s', static::printDescription($options, $type), $type->name) . static::printFieldOrTypeDirectives($type);
375379
}
376380

377381
/**
@@ -410,14 +414,64 @@ protected static function printFields(array $options, $type): string
410414
static function (FieldDefinition $f, int $i) use ($options): string {
411415
return static::printDescription($options, $f, ' ', $i === 0) . ' ' .
412416
$f->name . static::printArgs($options, $f->args, ' ') . ': ' .
413-
(string) $f->getType() . static::printDeprecated($f);
417+
(string) $f->getType() . static::printFieldOrTypeDirectives($f);
414418
},
415419
$fields,
416420
array_keys($fields)
417421
)
418422
);
419423
}
420424

425+
/**
426+
* @param FieldDefinition|ScalarType|EnumValueDefinition $fieldOrEnumVal
427+
*/
428+
protected static function printFieldOrTypeDirectives($fieldOrEnumVal): string
429+
{
430+
$serialized = '';
431+
432+
if (($fieldOrEnumVal instanceof FieldDefinition || $fieldOrEnumVal instanceof EnumValueDefinition) && $fieldOrEnumVal->deprecationReason !== null) {
433+
$serialized .= static::printDeprecated($fieldOrEnumVal);
434+
}
435+
436+
if ($fieldOrEnumVal->astNode !== null) {
437+
foreach ($fieldOrEnumVal->astNode->directives as $directive) {
438+
/** @var DirectiveNode $directive */
439+
if ($directive->name->value === Directive::DEPRECATED_NAME && $fieldOrEnumVal->deprecationReason !== null) {
440+
continue;
441+
}
442+
443+
$serialized .= ' @' . $directive->name->value;
444+
445+
if ($directive->arguments->count() === 0) {
446+
continue;
447+
}
448+
449+
$serialized .= '(' . implode(',', array_map(static function (ArgumentNode $argument): string {
450+
switch ($argument->value->kind) {
451+
case NodeKind::INT:
452+
$type = Type::int();
453+
break;
454+
case NodeKind::FLOAT:
455+
$type = Type::float();
456+
break;
457+
case NodeKind::STRING:
458+
$type = Type::string();
459+
break;
460+
case NodeKind::BOOLEAN:
461+
$type = Type::boolean();
462+
break;
463+
default:
464+
return '';
465+
}
466+
467+
return $argument->name->value . ': ' . Printer::doPrint(AST::astFromValue($argument->value->value, $type));
468+
}, iterator_to_array($directive->arguments))) . ')';
469+
}
470+
}
471+
472+
return $serialized;
473+
}
474+
421475
/**
422476
* @param FieldArgument|EnumValueDefinition $fieldOrEnumVal
423477
*/
@@ -487,7 +541,7 @@ protected static function printEnumValues(array $values, array $options): string
487541
array_map(
488542
static function (EnumValueDefinition $value, int $i) use ($options): string {
489543
return static::printDescription($options, $value, ' ', $i === 0) . ' ' .
490-
$value->name . static::printDeprecated($value);
544+
$value->name . static::printFieldOrTypeDirectives($value);
491545
},
492546
$values,
493547
array_keys($values)

tests/Utils/SchemaPrinterTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Generator;
88
use GraphQL\Language\DirectiveLocation;
9+
use GraphQL\Language\Parser;
910
use GraphQL\Type\Definition\CustomScalarType;
1011
use GraphQL\Type\Definition\Directive;
1112
use GraphQL\Type\Definition\EnumType;
@@ -1370,4 +1371,22 @@ enum __TypeKind {
13701371
EOT;
13711372
self::assertEquals($introspectionSchema, $output);
13721373
}
1374+
1375+
public function testPrintParsedSDLIncludesCustomDirectives(): void
1376+
{
1377+
$SDL = <<<'EOT'
1378+
directive @customDirective(stringArgument: String!, intArgument: Int!, floatArgument: Float!, booleanArgument: Boolean!) on FIELD_DEFINITION
1379+
1380+
type Query {
1381+
field1: Boolean @customDirective(stringArgument: "test", intArgument: 42, floatArgument: 0.0, booleanArgument: true)
1382+
field2: Boolean
1383+
}
1384+
1385+
EOT;
1386+
$documentNode = Parser::parse($SDL);
1387+
$schema = BuildSchema::build($documentNode);
1388+
$output = SchemaPrinter::doPrint($schema);
1389+
1390+
self::assertEquals($SDL, $output);
1391+
}
13731392
}

0 commit comments

Comments
 (0)