Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ You can find and compare releases at the [GitHub release page](https://github.co
- Allow sending both `query` and `queryId`, ignore `queryId` in that case
- Fix `extend()` to preserve `repeatable` (#931)
- Preserve extended methods from class-based types in `SchemaExtender::extend()`
- Fix printing of empty types (#940)

### Removed

Expand Down
147 changes: 71 additions & 76 deletions src/Utils/SchemaPrinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use GraphQL\Type\Definition\EnumValueDefinition;
use GraphQL\Type\Definition\FieldArgument;
use GraphQL\Type\Definition\FieldDefinition;
use GraphQL\Type\Definition\ImplementingType;
use GraphQL\Type\Definition\InputObjectField;
use GraphQL\Type\Definition\InputObjectType;
use GraphQL\Type\Definition\InterfaceType;
Expand Down Expand Up @@ -332,21 +333,10 @@ protected static function printScalar(ScalarType $type, array $options): string
*/
protected static function printObject(ObjectType $type, array $options): string
{
$interfaces = $type->getInterfaces();
$implementedInterfaces = count($interfaces) > 0
? ' implements ' . implode(
' & ',
array_map(
static function (InterfaceType $interface): string {
return $interface->name;
},
$interfaces
)
)
: '';

return static::printDescription($options, $type) .
sprintf("type %s%s {\n%s\n}", $type->name, $implementedInterfaces, static::printFields($options, $type));
sprintf('type %s', $type->name) .
self::printImplementedInterfaces($type) .
static::printFields($options, $type);
}

/**
Expand All @@ -356,19 +346,21 @@ static function (InterfaceType $interface): string {
protected static function printFields(array $options, $type): string
{
$fields = array_values($type->getFields());

return implode(
"\n",
array_map(
static function (FieldDefinition $f, int $i) use ($options): string {
return static::printDescription($options, $f, ' ', $i === 0) . ' ' .
$f->name . static::printArgs($options, $f->args, ' ') . ': ' .
(string) $f->getType() . static::printDeprecated($f);
},
$fields,
array_keys($fields)
)
$fields = array_map(
static function (FieldDefinition $f, int $i) use ($options): string {
return static::printDescription($options, $f, ' ', $i === 0) .
' ' .
$f->name .
static::printArgs($options, $f->args, ' ') .
': ' .
(string) $f->getType() .
static::printDeprecated($f);
},
$fields,
array_keys($fields)
);

return self::printBlock($fields);
}

/**
Expand All @@ -389,63 +381,63 @@ protected static function printDeprecated($fieldOrEnumVal): string
Printer::doPrint(AST::astFromValue($reason, Type::string())) . ')';
}

/**
* @param array<string, bool> $options
*/
protected static function printInterface(InterfaceType $type, array $options): string
protected static function printImplementedInterfaces(ImplementingType $type): string
{
$interfaces = $type->getInterfaces();
$implementedInterfaces = count($interfaces) > 0
? ' implements ' . implode(
' & ',
array_map(
static function (InterfaceType $interface): string {
return $interface->name;
},
$interfaces
)
)
: '';
$interfaces = $type->getInterfaces();

return static::printDescription($options, $type) .
sprintf("interface %s%s {\n%s\n}", $type->name, $implementedInterfaces, static::printFields($options, $type));
return count($interfaces) > 0
? ' implements ' . implode(
' & ',
array_map(
static fn (InterfaceType $interface): string => $interface->name,
$interfaces
)
)
: '';
}

/**
* @param array<string, bool> $options
*/
protected static function printUnion(UnionType $type, array $options): string
protected static function printInterface(InterfaceType $type, array $options): string
{
return static::printDescription($options, $type) .
sprintf('union %s = %s', $type->name, implode(' | ', $type->getTypes()));
sprintf('interface %s', $type->name) .
self::printImplementedInterfaces($type) .
static::printFields($options, $type);
}

/**
* @param array<string, bool> $options
*/
protected static function printEnum(EnumType $type, array $options): string
protected static function printUnion(UnionType $type, array $options): string
{
return static::printDescription($options, $type) .
sprintf("enum %s {\n%s\n}", $type->name, static::printEnumValues($type->getValues(), $options));
$types = $type->getTypes();
$types = count($types) > 0 ? ' = ' . implode(' | ', $types) : '';

return static::printDescription($options, $type) . 'union ' . $type->name . $types;
}

/**
* @param array<int, EnumValueDefinition> $values
* @param array<string, bool> $options
* @param array<string, bool> $options
*/
protected static function printEnumValues(array $values, array $options): string
protected static function printEnum(EnumType $type, array $options): string
{
return implode(
"\n",
array_map(
static function (EnumValueDefinition $value, int $i) use ($options): string {
return static::printDescription($options, $value, ' ', $i === 0) . ' ' .
$value->name . static::printDeprecated($value);
},
$values,
array_keys($values)
)
$values = $type->getValues();
$values = array_map(
static function (EnumValueDefinition $value, int $i) use ($options): string {
return static::printDescription($options, $value, ' ', $i === 0) .
' ' .
$value->name .
static::printDeprecated($value);
},
$values,
array_keys($values)
);

return static::printDescription($options, $type) .
sprintf('enum %s', $type->name) .
static::printBlock($values);
}

/**
Expand All @@ -454,22 +446,17 @@ static function (EnumValueDefinition $value, int $i) use ($options): string {
protected static function printInputObject(InputObjectType $type, array $options): string
{
$fields = array_values($type->getFields());
$fields = array_map(
static function ($f, $i) use ($options): string {
return static::printDescription($options, $f, ' ', ! $i) . ' ' . static::printInputValue($f);
},
$fields,
array_keys($fields)
);

return static::printDescription($options, $type) .
sprintf(
"input %s {\n%s\n}",
$type->name,
implode(
"\n",
array_map(
static function ($f, $i) use ($options): string {
return static::printDescription($options, $f, ' ', ! $i) . ' ' . static::printInputValue($f);
},
$fields,
array_keys($fields)
)
)
);
sprintf('input %s', $type->name) .
static::printBlock($fields);
}

/**
Expand All @@ -486,4 +473,12 @@ public static function printIntrospectionSchema(Schema $schema, array $options =
$options
);
}

/**
* @param array<string> $items
*/
protected static function printBlock(array $items): string
{
return count($items) > 0 ? " {\n" . implode("\n", $items) . "\n}" : '';
}
}
34 changes: 34 additions & 0 deletions tests/Utils/SchemaPrinterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,40 @@ enum RGB {
);
}

/**
* @see it('Prints empty types')
*/
public function testPrintsEmptyTypes(): void
{
$schema = new Schema([
'types' => [
new EnumType(['name' => 'SomeEnum', 'values' => []]),
new InputObjectType(['name' => 'SomeInputObject', 'fields' => []]),
new InterfaceType(['name' => 'SomeInterface', 'fields' => []]),
new ObjectType(['name' => 'SomeObject', 'fields' => []]),
new UnionType(['name' => 'SomeUnion', 'types' => []]),
],
]);

$output = $this->printForTest($schema);
self::assertEquals(
<<<'GQL'

enum SomeEnum

input SomeInputObject

interface SomeInterface

type SomeObject

union SomeUnion

GQL,
$output
);
}

/**
* @see it('Prints custom directives')
*/
Expand Down