Skip to content

Commit 3231084

Browse files
Gregory-Gerardspawnia
authored andcommitted
Add missing __Directive.args(includeDeprecated:)
Adds the missing includeDeprecated argument to `__Directive.args` field to match GraphQL.js implementation (graphql/graphql-js#3273). The argument allows filtering deprecated directive arguments from introspection results when set to false (default behavior). This notably fixes schema generation with `graphql-codegen` when using the "inputValueDeprecation" option (see dotansimha/graphql-code-generator#9659). Includes tests for deprecated argument filtering that I didn't find in GraphQL.js.
1 parent 23b3fa9 commit 3231084

File tree

3 files changed

+121
-8
lines changed

3 files changed

+121
-8
lines changed

src/Type/Introspection.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public static function getIntrospectionQuery(array $options = []): string
110110
directives {
111111
name
112112
{$descriptions}
113-
args {
113+
args(includeDeprecated: true) {
114114
...InputValue
115115
}
116116
{$directiveIsRepeatable}
@@ -362,7 +362,7 @@ public static function _type(): ObjectType
362362
if ($type instanceof ObjectType || $type instanceof InterfaceType) {
363363
$fields = $type->getVisibleFields();
364364

365-
if (! ($args['includeDeprecated'] ?? false)) {
365+
if (! $args['includeDeprecated']) {
366366
return array_filter(
367367
$fields,
368368
static fn (FieldDefinition $field): bool => ! $field->isDeprecated()
@@ -399,7 +399,7 @@ public static function _type(): ObjectType
399399
if ($type instanceof EnumType) {
400400
$values = $type->getValues();
401401

402-
if (! ($args['includeDeprecated'] ?? false)) {
402+
if (! $args['includeDeprecated']) {
403403
return array_filter(
404404
$values,
405405
static fn (EnumValueDefinition $value): bool => ! $value->isDeprecated()
@@ -424,7 +424,7 @@ public static function _type(): ObjectType
424424
if ($type instanceof InputObjectType) {
425425
$fields = $type->getFields();
426426

427-
if (! ($args['includeDeprecated'] ?? false)) {
427+
if (! $args['includeDeprecated']) {
428428
return array_filter(
429429
$fields,
430430
static fn (InputObjectField $field): bool => ! $field->isDeprecated(),
@@ -523,7 +523,7 @@ public static function _field(): ObjectType
523523
'resolve' => static function (FieldDefinition $field, $args): array {
524524
$values = $field->args;
525525

526-
if (! ($args['includeDeprecated'] ?? false)) {
526+
if (! $args['includeDeprecated']) {
527527
return array_filter(
528528
$values,
529529
static fn (Argument $value): bool => ! $value->isDeprecated(),
@@ -667,7 +667,24 @@ public static function _directive(): ObjectType
667667
],
668668
'args' => [
669669
'type' => Type::nonNull(Type::listOf(Type::nonNull(self::_inputValue()))),
670-
'resolve' => static fn (Directive $directive): array => $directive->args,
670+
'args' => [
671+
'includeDeprecated' => [
672+
'type' => Type::boolean(),
673+
'defaultValue' => false,
674+
],
675+
],
676+
'resolve' => static function (Directive $directive, $args): array {
677+
$values = $directive->args;
678+
679+
if (! $args['includeDeprecated']) {
680+
return array_filter(
681+
$values,
682+
static fn (Argument $value): bool => ! $value->isDeprecated(),
683+
);
684+
}
685+
686+
return $values;
687+
},
671688
],
672689
],
673690
]);

tests/Type/IntrospectionTest.php

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
66
use GraphQL\GraphQL;
7+
use GraphQL\Language\DirectiveLocation;
78
use GraphQL\Language\SourceLocation;
89
use GraphQL\Tests\ErrorHelper;
10+
use GraphQL\Type\Definition\Directive;
911
use GraphQL\Type\Definition\EnumType;
1012
use GraphQL\Type\Definition\FieldDefinition;
1113
use GraphQL\Type\Definition\InputObjectType;
@@ -775,7 +777,19 @@ public function testExecutesAnIntrospectionQuery(): void
775777
],
776778
[
777779
'name' => 'args',
778-
'args' => [],
780+
'args' => [
781+
0 => [
782+
'name' => 'includeDeprecated',
783+
'type' => [
784+
'kind' => 'SCALAR',
785+
'name' => 'Boolean',
786+
'ofType' => null,
787+
],
788+
'defaultValue' => 'false',
789+
'isDeprecated' => false,
790+
'deprecationReason' => null,
791+
],
792+
],
779793
'type' => [
780794
'kind' => 'NON_NULL',
781795
'name' => null,
@@ -1872,4 +1886,86 @@ public function testIsOneOf(): void
18721886
$introspection = Introspection::fromSchema($schema);
18731887
self::assertTrue($introspection['__schema']['types'][1]['isOneOf']);
18741888
}
1889+
1890+
public function testRespectsTheIncludeDeprecatedParameterForDirectiveArgs(): void
1891+
{
1892+
$query = new ObjectType([
1893+
'name' => 'QueryRoot',
1894+
'fields' => [
1895+
[
1896+
'name' => 'test',
1897+
'type' => Type::int(),
1898+
],
1899+
],
1900+
]);
1901+
1902+
$directive = new Directive([
1903+
'name' => 'TestDirective',
1904+
'args' => [
1905+
'nonDeprecated' => [
1906+
'type' => Type::string(),
1907+
],
1908+
'deprecated' => [
1909+
'type' => Type::string(),
1910+
'deprecationReason' => 'Removed in 1.0',
1911+
],
1912+
],
1913+
'locations' => [DirectiveLocation::FIELD],
1914+
]);
1915+
1916+
$schema = new Schema([
1917+
'query' => $query,
1918+
'directives' => [$directive],
1919+
]);
1920+
1921+
$request = '
1922+
{
1923+
__schema {
1924+
directives {
1925+
trueArgs: args(includeDeprecated: true) {
1926+
name
1927+
isDeprecated
1928+
deprecationReason
1929+
}
1930+
falseArgs: args(includeDeprecated: false) {
1931+
name
1932+
}
1933+
omittedArgs: args {
1934+
name
1935+
}
1936+
}
1937+
}
1938+
}
1939+
';
1940+
1941+
$expected = [
1942+
[
1943+
'trueArgs' => [
1944+
[
1945+
'name' => 'nonDeprecated',
1946+
'isDeprecated' => false,
1947+
'deprecationReason' => null,
1948+
],
1949+
[
1950+
'name' => 'deprecated',
1951+
'isDeprecated' => true,
1952+
'deprecationReason' => 'Removed in 1.0',
1953+
],
1954+
],
1955+
'falseArgs' => [
1956+
[
1957+
'name' => 'nonDeprecated',
1958+
],
1959+
],
1960+
'omittedArgs' => [
1961+
[
1962+
'name' => 'nonDeprecated',
1963+
],
1964+
],
1965+
],
1966+
];
1967+
1968+
$result = GraphQL::executeQuery($schema, $request)->toArray();
1969+
self::assertSame($expected, $result['data']['__schema']['directives'] ?? null);
1970+
}
18751971
}

tests/Utils/SchemaPrinterTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ enum __TypeKind {
11601160
description: String
11611161
isRepeatable: Boolean!
11621162
locations: [__DirectiveLocation!]!
1163-
args: [__InputValue!]!
1163+
args(includeDeprecated: Boolean = false): [__InputValue!]!
11641164
}
11651165
11661166
"A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies."

0 commit comments

Comments
 (0)