|
6 | 6 |
|
7 | 7 | use Exception; |
8 | 8 | use GraphQL\Error\InvariantViolation; |
9 | | -use GraphQL\Language\AST\DirectiveNode; |
10 | 9 | use GraphQL\Language\AST\DocumentNode; |
11 | 10 | use GraphQL\Language\AST\FieldNode; |
12 | 11 | use GraphQL\Language\AST\FragmentSpreadNode; |
|
16 | 15 | use GraphQL\Language\AST\NodeList; |
17 | 16 | use GraphQL\Language\AST\OperationDefinitionNode; |
18 | 17 | use GraphQL\Language\AST\SelectionSetNode; |
19 | | -use GraphQL\Language\AST\StringValueNode; |
20 | 18 | use GraphQL\Language\Parser; |
21 | 19 | use GraphQL\Language\Printer; |
22 | 20 | use GraphQL\Type\Definition\EnumType; |
@@ -143,6 +141,8 @@ final class GraphQLCodeGenerator |
143 | 141 | private readonly DataClassGenerator $dataClassGenerator; |
144 | 142 | private readonly InputTypeGenerator $inputTypeGenerator; |
145 | 143 | private TypeMapper $typeMapper; |
| 144 | + private DirectiveProcessor $directiveProcessor; |
| 145 | + private VariableParser $variableParser; |
146 | 146 |
|
147 | 147 | /** |
148 | 148 | * @var array<string, SymfonyType> |
@@ -323,6 +323,10 @@ public function generate() : array |
323 | 323 | $this->objectTypes, |
324 | 324 | ); |
325 | 325 |
|
| 326 | + // Initialize helper classes |
| 327 | + $this->directiveProcessor = new DirectiveProcessor(); |
| 328 | + $this->variableParser = new VariableParser($this->typeMapper); |
| 329 | + |
326 | 330 | foreach ($this->schema->getTypeMap() as $typeName => $type) { |
327 | 331 | if (str_starts_with($typeName, '__')) { |
328 | 332 | continue; |
@@ -451,7 +455,7 @@ private function processOperation(DocumentNode $document, string $relativeFilePa |
451 | 455 | $queryDir = $this->config->outputDir . '/' . $operationType; |
452 | 456 | $operationDir = $queryDir . '/' . $operationName; |
453 | 457 |
|
454 | | - $variables = $this->parseVariables($operation); |
| 458 | + $variables = $this->variableParser->parseVariables($operation); |
455 | 459 |
|
456 | 460 | $relativePath = str_replace($this->config->outputDir . '/', '', $queryDir . '/' . $queryClassName . $operationType . '.php'); |
457 | 461 | $this->files[$relativePath] = $this->operationClassGenerator->generate( |
@@ -509,33 +513,6 @@ private function processOperation(DocumentNode $document, string $relativeFilePa |
509 | 513 | ); |
510 | 514 | } |
511 | 515 |
|
512 | | - /** |
513 | | - * @return array<string, SymfonyType> |
514 | | - */ |
515 | | - private function parseVariables(OperationDefinitionNode $operation) : array |
516 | | - { |
517 | | - $required = []; |
518 | | - $optional = []; |
519 | | - |
520 | | - foreach ($operation->variableDefinitions as $varDef) { |
521 | | - $name = $varDef->variable->name->value; |
522 | | - $type = $this->typeMapper->mapGraphQLASTTypeToPHPType($varDef->type); |
523 | | - |
524 | | - if ($type instanceof SymfonyType\NullableType) { |
525 | | - $optional[$name] = $type; |
526 | | - |
527 | | - continue; |
528 | | - } |
529 | | - |
530 | | - $required[$name] = $type; |
531 | | - } |
532 | | - |
533 | | - return [ |
534 | | - ...$required, |
535 | | - ...$optional, |
536 | | - ]; |
537 | | - } |
538 | | - |
539 | 516 | /** |
540 | 517 | * @param list<string> $indexBy |
541 | 518 | * |
@@ -668,7 +645,7 @@ private function parseSelectionSet( |
668 | 645 | $indexBy = []; |
669 | 646 |
|
670 | 647 | if ($this->config->indexByDirective) { |
671 | | - $indexBy = $this->getIndexByDirective($selection->directives); |
| 648 | + $indexBy = $this->directiveProcessor->getIndexByDirective($selection->directives); |
672 | 649 |
|
673 | 650 | if ($indexBy !== []) { |
674 | 651 | $indexByType = $this->typeMapper->mapGraphQLTypeToPHPType(RecursiveTypeFinder::find($nakedFieldType, $indexBy)); |
@@ -734,7 +711,7 @@ private function parseSelectionSet( |
734 | 711 | $this->inlineFragmentRequiredFields, |
735 | 712 | ); |
736 | 713 |
|
737 | | - if ($this->hasIncludeOrSkipDirective($selection->directives)) { |
| 714 | + if ($this->directiveProcessor->hasIncludeOrSkipDirective($selection->directives)) { |
738 | 715 | $subType = SymfonyType::nullable($subType); |
739 | 716 | $subPayloadShape = SymfonyType::nullable($subPayloadShape); |
740 | 717 | } |
@@ -931,41 +908,6 @@ private function getPossibleTypes(Type $type) : array |
931 | 908 | return []; |
932 | 909 | } |
933 | 910 |
|
934 | | - /** |
935 | | - * @param NodeList<DirectiveNode> $directives |
936 | | - */ |
937 | | - private function hasIncludeOrSkipDirective(NodeList $directives) : bool |
938 | | - { |
939 | | - foreach ($directives as $directive) { |
940 | | - if (in_array($directive->name->value, ['include', 'skip'], true)) { |
941 | | - return true; |
942 | | - } |
943 | | - } |
944 | | - |
945 | | - return false; |
946 | | - } |
947 | | - |
948 | | - /** |
949 | | - * @param NodeList<DirectiveNode> $directives |
950 | | - * @return list<string> |
951 | | - */ |
952 | | - private function getIndexByDirective(NodeList $directives) : array |
953 | | - { |
954 | | - foreach ($directives as $directive) { |
955 | | - if ($directive->name->value !== 'indexBy') { |
956 | | - continue; |
957 | | - } |
958 | | - |
959 | | - if ( ! $directive->arguments[0]->value instanceof StringValueNode) { |
960 | | - continue; |
961 | | - } |
962 | | - |
963 | | - return explode('.', $directive->arguments[0]->value->value); |
964 | | - } |
965 | | - |
966 | | - return []; |
967 | | - } |
968 | | - |
969 | 911 | private function singularize(string $fieldName) : string |
970 | 912 | { |
971 | 913 | $options = $this->inflector->singularize($fieldName); |
|
0 commit comments