PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.3
WooCommerce v10.9.3
10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / lib / packages / GraphQL / Language / Printer.php
woocommerce / lib / packages / GraphQL / Language Last commit date
AST 2 months ago BlockString.php 2 months ago DirectiveLocation.php 2 months ago Lexer.php 2 months ago Parser.php 2 months ago Printer.php 2 months ago Source.php 2 months ago SourceLocation.php 2 months ago Token.php 2 months ago Visitor.php 2 months ago VisitorOperation.php 2 months ago VisitorRemoveNode.php 2 months ago VisitorSkipNode.php 2 months ago VisitorStop.php 2 months ago
Printer.php
526 lines
1 <?php declare(strict_types=1);
2
3 namespace Automattic\WooCommerce\Vendor\GraphQL\Language;
4
5 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ArgumentNode;
6 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\BooleanValueNode;
7 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\DirectiveDefinitionNode;
8 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\DirectiveNode;
9 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\DocumentNode;
10 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\EnumTypeDefinitionNode;
11 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\EnumTypeExtensionNode;
12 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\EnumValueDefinitionNode;
13 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\EnumValueNode;
14 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\FieldDefinitionNode;
15 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\FieldNode;
16 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\FloatValueNode;
17 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\FragmentDefinitionNode;
18 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\FragmentSpreadNode;
19 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\InlineFragmentNode;
20 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\InputObjectTypeDefinitionNode;
21 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\InputObjectTypeExtensionNode;
22 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\InputValueDefinitionNode;
23 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\InterfaceTypeDefinitionNode;
24 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\InterfaceTypeExtensionNode;
25 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\IntValueNode;
26 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ListTypeNode;
27 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ListValueNode;
28 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\NamedTypeNode;
29 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\NameNode;
30 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\Node;
31 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\NodeList;
32 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\NonNullTypeNode;
33 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\NullValueNode;
34 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ObjectFieldNode;
35 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ObjectTypeDefinitionNode;
36 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ObjectTypeExtensionNode;
37 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ObjectValueNode;
38 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\OperationDefinitionNode;
39 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\OperationTypeDefinitionNode;
40 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ScalarTypeDefinitionNode;
41 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\ScalarTypeExtensionNode;
42 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\SchemaDefinitionNode;
43 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\SchemaExtensionNode;
44 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\SelectionSetNode;
45 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\StringValueNode;
46 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\UnionTypeDefinitionNode;
47 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\UnionTypeExtensionNode;
48 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\VariableDefinitionNode;
49 use Automattic\WooCommerce\Vendor\GraphQL\Language\AST\VariableNode;
50
51 /**
52 * Prints AST to string. Capable of printing Automattic\WooCommerce\Vendor\GraphQL queries and Type definition language.
53 * Useful for pretty-printing queries or printing back AST for logging, documentation, etc.
54 *
55 * Usage example:
56 *
57 * ```php
58 * $query = 'query myQuery {someField}';
59 * $ast = Automattic\WooCommerce\Vendor\GraphQL\Language\Parser::parse($query);
60 * $printed = Automattic\WooCommerce\Vendor\GraphQL\Language\Printer::doPrint($ast);
61 * ```
62 *
63 * @see \Automattic\WooCommerce\Vendor\GraphQL\Tests\Language\PrinterTest
64 */
65 class Printer
66 {
67 /**
68 * Converts the AST of a Automattic\WooCommerce\Vendor\GraphQL node to a string.
69 *
70 * Handles both executable definitions and schema definitions.
71 *
72 * @throws \JsonException
73 *
74 * @api
75 */
76 public static function doPrint(Node $ast): string
77 {
78 return static::p($ast);
79 }
80
81 /** @throws \JsonException */
82 protected static function p(?Node $node): string
83 {
84 if ($node === null) {
85 return '';
86 }
87
88 switch (true) {
89 case $node instanceof ArgumentNode:
90 case $node instanceof ObjectFieldNode:
91 return static::p($node->name) . ': ' . static::p($node->value);
92
93 case $node instanceof BooleanValueNode:
94 return $node->value
95 ? 'true'
96 : 'false';
97
98 case $node instanceof DirectiveDefinitionNode:
99 $argStrings = [];
100 foreach ($node->arguments as $arg) {
101 $argStrings[] = static::p($arg);
102 }
103
104 $noIndent = true;
105 foreach ($argStrings as $argString) {
106 if (strpos($argString, "\n") !== false) {
107 $noIndent = false;
108 break;
109 }
110 }
111
112 return static::addDescription($node->description, 'directive @'
113 . static::p($node->name)
114 . ($noIndent
115 ? static::wrap('(', static::join($argStrings, ', '), ')')
116 : static::wrap("(\n", static::indent(static::join($argStrings, "\n")), "\n"))
117 . ($node->repeatable
118 ? ' repeatable'
119 : '')
120 . ' on ' . static::printList($node->locations, ' | '));
121
122 case $node instanceof DirectiveNode:
123 return '@' . static::p($node->name) . static::wrap('(', static::printList($node->arguments, ', '), ')');
124
125 case $node instanceof DocumentNode:
126 return static::printList($node->definitions, "\n\n") . "\n";
127
128 case $node instanceof EnumTypeDefinitionNode:
129 return static::addDescription($node->description, static::join(
130 [
131 'enum',
132 static::p($node->name),
133 static::printList($node->directives, ' '),
134 static::printListBlock($node->values),
135 ],
136 ' '
137 ));
138
139 case $node instanceof EnumTypeExtensionNode:
140 return static::join(
141 [
142 'extend enum',
143 static::p($node->name),
144 static::printList($node->directives, ' '),
145 static::printListBlock($node->values),
146 ],
147 ' '
148 );
149
150 case $node instanceof EnumValueDefinitionNode:
151 return static::addDescription(
152 $node->description,
153 static::join([static::p($node->name), static::printList($node->directives, ' ')], ' ')
154 );
155
156 case $node instanceof EnumValueNode:
157 case $node instanceof FloatValueNode:
158 case $node instanceof IntValueNode:
159 case $node instanceof NameNode:
160 return $node->value;
161
162 case $node instanceof FieldDefinitionNode:
163 $argStrings = [];
164 foreach ($node->arguments as $item) {
165 $argStrings[] = static::p($item);
166 }
167
168 $noIndent = true;
169 foreach ($argStrings as $argString) {
170 if (strpos($argString, "\n") !== false) {
171 $noIndent = false;
172 break;
173 }
174 }
175
176 return static::addDescription(
177 $node->description,
178 static::p($node->name)
179 . ($noIndent
180 ? static::wrap('(', static::join($argStrings, ', '), ')')
181 : static::wrap("(\n", static::indent(static::join($argStrings, "\n")), "\n)"))
182 . ': ' . static::p($node->type)
183 . static::wrap(' ', static::printList($node->directives, ' '))
184 );
185
186 case $node instanceof FieldNode:
187 $prefix = static::wrap('', $node->alias->value ?? null, ': ') . static::p($node->name);
188
189 $argsLine = $prefix . static::wrap(
190 '(',
191 static::printList($node->arguments, ', '),
192 ')'
193 );
194 if (strlen($argsLine) > 80) {
195 $argsLine = $prefix . static::wrap(
196 "(\n",
197 static::indent(
198 static::printList($node->arguments, "\n")
199 ),
200 "\n)"
201 );
202 }
203
204 return static::join(
205 [
206 $argsLine,
207 static::printList($node->directives, ' '),
208 static::p($node->selectionSet),
209 ],
210 ' '
211 );
212
213 case $node instanceof FragmentDefinitionNode:
214 // Note: fragment variable definitions are experimental and may be changed or removed in the future.
215 return 'fragment ' . static::p($node->name)
216 . static::wrap(
217 '(',
218 static::printList($node->variableDefinitions ?? new NodeList([]), ', '),
219 ')'
220 )
221 . ' on ' . static::p($node->typeCondition->name) . ' '
222 . static::wrap(
223 '',
224 static::printList($node->directives, ' '),
225 ' '
226 )
227 . static::p($node->selectionSet);
228
229 case $node instanceof FragmentSpreadNode:
230 return '...'
231 . static::p($node->name)
232 . static::wrap(' ', static::printList($node->directives, ' '));
233
234 case $node instanceof InlineFragmentNode:
235 return static::join(
236 [
237 '...',
238 static::wrap('on ', static::p($node->typeCondition->name ?? null)),
239 static::printList($node->directives, ' '),
240 static::p($node->selectionSet),
241 ],
242 ' '
243 );
244
245 case $node instanceof InputObjectTypeDefinitionNode:
246 return static::addDescription($node->description, static::join(
247 [
248 'input',
249 static::p($node->name),
250 static::printList($node->directives, ' '),
251 static::printListBlock($node->fields),
252 ],
253 ' '
254 ));
255
256 case $node instanceof InputObjectTypeExtensionNode:
257 return static::join(
258 [
259 'extend input',
260 static::p($node->name),
261 static::printList($node->directives, ' '),
262 static::printListBlock($node->fields),
263 ],
264 ' '
265 );
266
267 case $node instanceof InputValueDefinitionNode:
268 return static::addDescription($node->description, static::join(
269 [
270 static::p($node->name) . ': ' . static::p($node->type),
271 static::wrap('= ', static::p($node->defaultValue)),
272 static::printList($node->directives, ' '),
273 ],
274 ' '
275 ));
276
277 case $node instanceof InterfaceTypeDefinitionNode:
278 return static::addDescription($node->description, static::join(
279 [
280 'interface',
281 static::p($node->name),
282 static::wrap('implements ', static::printList($node->interfaces, ' & ')),
283 static::printList($node->directives, ' '),
284 static::printListBlock($node->fields),
285 ],
286 ' '
287 ));
288
289 case $node instanceof InterfaceTypeExtensionNode:
290 return static::join(
291 [
292 'extend interface',
293 static::p($node->name),
294 static::wrap('implements ', static::printList($node->interfaces, ' & ')),
295 static::printList($node->directives, ' '),
296 static::printListBlock($node->fields),
297 ],
298 ' '
299 );
300
301 case $node instanceof ListTypeNode:
302 return '[' . static::p($node->type) . ']';
303
304 case $node instanceof ListValueNode:
305 return '[' . static::printList($node->values, ', ') . ']';
306
307 case $node instanceof NamedTypeNode:
308 return static::p($node->name);
309
310 case $node instanceof NonNullTypeNode:
311 return static::p($node->type) . '!';
312
313 case $node instanceof NullValueNode:
314 return 'null';
315
316 case $node instanceof ObjectTypeDefinitionNode:
317 return static::addDescription($node->description, static::join(
318 [
319 'type',
320 static::p($node->name),
321 static::wrap('implements ', static::printList($node->interfaces, ' & ')),
322 static::printList($node->directives, ' '),
323 static::printListBlock($node->fields),
324 ],
325 ' '
326 ));
327
328 case $node instanceof ObjectTypeExtensionNode:
329 return static::join(
330 [
331 'extend type',
332 static::p($node->name),
333 static::wrap('implements ', static::printList($node->interfaces, ' & ')),
334 static::printList($node->directives, ' '),
335 static::printListBlock($node->fields),
336 ],
337 ' '
338 );
339
340 case $node instanceof ObjectValueNode:
341 return '{ '
342 . static::printList($node->fields, ', ')
343 . ' }';
344
345 case $node instanceof OperationDefinitionNode:
346 $op = $node->operation;
347 $name = static::p($node->name);
348 $varDefs = static::wrap('(', static::printList($node->variableDefinitions, ', '), ')');
349 $directives = static::printList($node->directives, ' ');
350 $selectionSet = static::p($node->selectionSet);
351
352 // Anonymous queries with no directives or variable definitions can use
353 // the query short form.
354 return $name === '' && $directives === '' && $varDefs === '' && $op === 'query'
355 ? $selectionSet
356 : static::join([$op, static::join([$name, $varDefs]), $directives, $selectionSet], ' ');
357
358 case $node instanceof OperationTypeDefinitionNode:
359 return $node->operation . ': ' . static::p($node->type);
360
361 case $node instanceof ScalarTypeDefinitionNode:
362 return static::addDescription($node->description, static::join([
363 'scalar',
364 static::p($node->name),
365 static::printList($node->directives, ' '),
366 ], ' '));
367
368 case $node instanceof ScalarTypeExtensionNode:
369 return static::join(
370 [
371 'extend scalar',
372 static::p($node->name),
373 static::printList($node->directives, ' '),
374 ],
375 ' '
376 );
377
378 case $node instanceof SchemaDefinitionNode:
379 return static::addDescription($node->description, static::join(
380 [
381 'schema',
382 static::printList($node->directives, ' '),
383 static::printListBlock($node->operationTypes),
384 ],
385 ' '
386 ));
387
388 case $node instanceof SchemaExtensionNode:
389 return static::join(
390 [
391 'extend schema',
392 static::printList($node->directives, ' '),
393 static::printListBlock($node->operationTypes),
394 ],
395 ' '
396 );
397
398 case $node instanceof SelectionSetNode:
399 return static::printListBlock($node->selections);
400
401 case $node instanceof StringValueNode:
402 if ($node->block) {
403 return BlockString::print($node->value);
404 }
405
406 return json_encode($node->value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
407
408 case $node instanceof UnionTypeDefinitionNode:
409 $typesStr = static::printList($node->types, ' | ');
410
411 return static::addDescription($node->description, static::join(
412 [
413 'union',
414 static::p($node->name),
415 static::printList($node->directives, ' '),
416 $typesStr !== ''
417 ? "= {$typesStr}"
418 : '',
419 ],
420 ' '
421 ));
422
423 case $node instanceof UnionTypeExtensionNode:
424 $typesStr = static::printList($node->types, ' | ');
425
426 return static::join(
427 [
428 'extend union',
429 static::p($node->name),
430 static::printList($node->directives, ' '),
431 $typesStr !== ''
432 ? "= {$typesStr}"
433 : '',
434 ],
435 ' '
436 );
437
438 case $node instanceof VariableDefinitionNode:
439 return '$' . static::p($node->variable->name)
440 . ': '
441 . static::p($node->type)
442 . static::wrap(' = ', static::p($node->defaultValue))
443 . static::wrap(' ', static::printList($node->directives, ' '));
444
445 case $node instanceof VariableNode:
446 return '$' . static::p($node->name);
447 }
448
449 return '';
450 }
451
452 /**
453 * @template TNode of Node
454 *
455 * @param NodeList<TNode> $list
456 *
457 * @throws \JsonException
458 */
459 protected static function printList(NodeList $list, string $separator = ''): string
460 {
461 $parts = [];
462 foreach ($list as $item) {
463 $parts[] = static::p($item);
464 }
465
466 return static::join($parts, $separator);
467 }
468
469 /**
470 * Print each item on its own line, wrapped in an indented "{ }" block.
471 *
472 * @template TNode of Node
473 *
474 * @param NodeList<TNode> $list
475 *
476 * @throws \JsonException
477 */
478 protected static function printListBlock(NodeList $list): string
479 {
480 if (count($list) === 0) {
481 return '';
482 }
483
484 $parts = [];
485 foreach ($list as $item) {
486 $parts[] = static::p($item);
487 }
488
489 return "{\n" . static::indent(static::join($parts, "\n")) . "\n}";
490 }
491
492 /** @throws \JsonException */
493 protected static function addDescription(?StringValueNode $description, string $body): string
494 {
495 return static::join([static::p($description), $body], "\n");
496 }
497
498 /**
499 * If maybeString is not null or empty, then wrap with start and end, otherwise
500 * print an empty string.
501 */
502 protected static function wrap(string $start, ?string $maybeString, string $end = ''): string
503 {
504 if ($maybeString === null || $maybeString === '') {
505 return '';
506 }
507
508 return $start . $maybeString . $end;
509 }
510
511 protected static function indent(string $string): string
512 {
513 if ($string === '') {
514 return '';
515 }
516
517 return ' ' . str_replace("\n", "\n ", $string);
518 }
519
520 /** @param array<string|null> $parts */
521 protected static function join(array $parts, string $separator = ''): string
522 {
523 return implode($separator, array_filter($parts, static fn (?string $part) => $part !== '' && $part !== null));
524 }
525 }
526