Skip to content

Commit 5f1b2b3

Browse files
committed
SCALAR support.
1 parent e18d52d commit 5f1b2b3

File tree

2 files changed

+103
-2
lines changed

2 files changed

+103
-2
lines changed

src/Utils/SchemaPrinter.php

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
namespace GraphQL\Utils;
66

7+
use Closure;
78
use GraphQL\Error\Error;
9+
use GraphQL\Language\AST\DirectiveNode;
10+
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
811
use GraphQL\Language\BlockString;
912
use GraphQL\Language\Printer;
1013
use GraphQL\Type\Definition\Directive;
@@ -30,23 +33,29 @@
3033
use function count;
3134
use function explode;
3235
use function implode;
36+
use function is_callable;
3337
use function ksort;
3438
use function mb_strlen;
39+
use function self;
3540
use function sprintf;
3641
use function str_replace;
3742
use function strlen;
3843

3944
/**
4045
* Prints the contents of a Schema in schema definition language.
4146
*
42-
* @phpstan-type Options array{commentDescriptions?: bool}
47+
* @phpstan-type Options array{commentDescriptions?: bool, printDirectives?: callable(DirectiveNode): bool}
4348
*
4449
* - commentDescriptions:
4550
* Provide true to use preceding comments as the description.
4651
* This option is provided to ease adoption and will be removed in v16.
52+
* - printDirectives
53+
* Callable used to determine should be directive printed or not.
4754
*/
4855
class SchemaPrinter
4956
{
57+
protected const LINE_LENGTH = 80;
58+
5059
/**
5160
* @param array<string, bool> $options
5261
* @phpstan-param Options $options
@@ -308,7 +317,9 @@ protected static function printInputValue($arg): string
308317
*/
309318
protected static function printScalar(ScalarType $type, array $options): string
310319
{
311-
return sprintf('%sscalar %s', static::printDescription($options, $type), $type->name);
320+
return static::printDescription($options, $type) .
321+
sprintf('scalar %s', $type->name) .
322+
static::printTypeDirectives($type, $options);
312323
}
313324

314325
/**
@@ -459,4 +470,53 @@ protected static function printBlock(array $items): string
459470
? " {\n" . implode("\n", $items) . "\n}"
460471
: '';
461472
}
473+
474+
/**
475+
* @param array<string, bool> $options
476+
* @phpstan-param Options $options
477+
*/
478+
protected static function printTypeDirectives(Type $type, array $options, string $indentation = ''): string {
479+
// Enabled?
480+
$filter = $options['printDirectives'] ?? null;
481+
482+
if (!$filter || !is_callable($filter)) {
483+
return '';
484+
}
485+
486+
// AST Node available and has directives?
487+
$node = $type->astNode;
488+
489+
if (!($node instanceof ScalarTypeDefinitionNode)) {
490+
return '';
491+
}
492+
493+
// Print
494+
/** @var array<string> $directives */
495+
$length = 0;
496+
$directives = [];
497+
498+
foreach ($node->directives as $directive) {
499+
if ($filter($directive)) {
500+
$string = static::printTypeDirective($directive, $options, $indentation);
501+
$length = $length + mb_strlen($string);
502+
$directives[] = $string;
503+
}
504+
}
505+
506+
// Multiline?
507+
$delimiter = $length > static::LINE_LENGTH ? "\n{$indentation}" : ' ';
508+
$serialized = $delimiter.implode($delimiter, $directives);
509+
510+
// Return
511+
return $serialized;
512+
}
513+
514+
/**
515+
* @param array<string, bool> $options
516+
* @phpstan-param Options $options
517+
*/
518+
protected static function printTypeDirective(DirectiveNode $directive, array $options, string $indentation): string
519+
{
520+
return Printer::doPrint($directive);
521+
}
462522
}

tests/Utils/SchemaPrinterTest.php

Lines changed: 41 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;
@@ -19,6 +20,8 @@
1920
use GraphQL\Utils\SchemaPrinter;
2021
use PHPUnit\Framework\TestCase;
2122

23+
use function str_pad;
24+
2225
class SchemaPrinterTest extends TestCase
2326
{
2427
private static function assertPrintedSchemaEquals(string $expected, Schema $schema): void
@@ -1273,4 +1276,42 @@ enum __TypeKind {
12731276
GRAPHQL;
12741277
self::assertEquals($expected, $output);
12751278
}
1279+
1280+
public function testPrintDirectives(): void {
1281+
$text = str_pad('a', 80, 'a');
1282+
$schema = /** @lang GraphQL */ <<<GRAPHQL
1283+
directive @test(
1284+
value: String
1285+
) on SCHEMA |
1286+
SCALAR |
1287+
OBJECT |
1288+
FIELD_DEFINITION |
1289+
ARGUMENT_DEFINITION |
1290+
INTERFACE |
1291+
UNION |
1292+
ENUM |
1293+
ENUM_VALUE |
1294+
INPUT_OBJECT |
1295+
INPUT_FIELD_DEFINITION
1296+
1297+
scalar ScalarA @test
1298+
scalar ScalarB @test(value: "{$text}")
1299+
GRAPHQL;
1300+
$expected = <<<'GRAPHQL'
1301+
directive @test(value: String) on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
1302+
1303+
scalar ScalarA @test
1304+
1305+
scalar ScalarB
1306+
@test(value: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
1307+
1308+
GRAPHQL;
1309+
$actual = SchemaPrinter::doPrint(BuildSchema::build($schema), [
1310+
'printDirectives' => static function(): bool {
1311+
return true;
1312+
},
1313+
]);
1314+
1315+
self::assertEquals($expected, $actual);
1316+
}
12761317
}

0 commit comments

Comments
 (0)