|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace ApiClients\Tools\OpenApiClientGenerator\Generator; |
| 4 | + |
| 5 | +use ApiClients\Contracts\HTTP\Headers\AuthenticationInterface; |
| 6 | +use ApiClients\Tools\OpenApiClientGenerator\File; |
| 7 | +use ApiClients\Tools\OpenApiClientGenerator\SchemaRegistry; |
| 8 | +use cebe\openapi\spec\Operation as OpenAPiOperation; |
| 9 | +use cebe\openapi\spec\PathItem; |
| 10 | +use Jawira\CaseConverter\Convert; |
| 11 | +use League\OpenAPIValidation\Schema\Exception\SchemaMismatch; |
| 12 | +use PhpParser\Builder\Param; |
| 13 | +use PhpParser\BuilderFactory; |
| 14 | +use PhpParser\Comment\Doc; |
| 15 | +use PhpParser\Node; |
| 16 | +use PhpParser\Node\Arg; |
| 17 | +use PhpParser\Node\Stmt\Class_; |
| 18 | +use Psr\Http\Message\RequestInterface; |
| 19 | +use Psr\Http\Message\ResponseInterface; |
| 20 | +use Psr\Http\Message\ServerRequestInterface; |
| 21 | +use React\Http\Browser; |
| 22 | +use React\Promise\PromiseInterface; |
| 23 | +use RingCentral\Psr7\Request; |
| 24 | +use Rx\Observable; |
| 25 | + |
| 26 | +final class ClientInterface |
| 27 | +{ |
| 28 | + /** |
| 29 | + * @return iterable<Node> |
| 30 | + * @throws \Jawira\CaseConverter\CaseConverterException |
| 31 | + */ |
| 32 | + public static function generate(string $namespace, array $clients, SchemaRegistry $schemaRegistry): iterable |
| 33 | + { |
| 34 | + $factory = new BuilderFactory(); |
| 35 | + $stmt = $factory->namespace(rtrim($namespace, '\\')); |
| 36 | + |
| 37 | + $class = $factory->interface('ClientInterface'); |
| 38 | + $operationCalls = []; |
| 39 | + $callReturnTypes = []; |
| 40 | + |
| 41 | + foreach ($clients as $operationGroup => $operations) { |
| 42 | + $cn = str_replace('/', '\\', '\\' . $namespace . 'Operation/' . $operationGroup); |
| 43 | + $casedOperationgroup = lcfirst($operationGroup); |
| 44 | + foreach ($operations as $operationOperation => $operationDetails) { |
| 45 | + $returnType = []; |
| 46 | + foreach ($operationDetails['operation']->responses as $code => $spec) { |
| 47 | + $contentTypeCases = []; |
| 48 | + foreach ($spec->content as $contentType => $contentTypeSchema) { |
| 49 | + $fallbackName = 'Operation\\' . $operationGroup . '\\Response\\' . (new Convert(str_replace('/', '\\', $contentType) . '\\H' . $code ))->toPascal(); |
| 50 | + $object = '\\' . $namespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema, $fallbackName); |
| 51 | + $callReturnTypes[] = ($contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class . '<' : '') . $object . ($contentTypeSchema->schema->type === 'array' ? '>' : ''); |
| 52 | + $contentTypeCases[] = $returnType[] = $contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class : $object; |
| 53 | + } |
| 54 | + if (count($contentTypeCases) === 0) { |
| 55 | + $returnType[] = $callReturnTypes[] = 'int'; |
| 56 | + } |
| 57 | + } |
| 58 | + $operationCalls[] = [ |
| 59 | + 'operationGroupMethod' => $casedOperationgroup, |
| 60 | + 'operationMethod' => lcfirst($operationOperation), |
| 61 | + 'className' => str_replace('/', '\\', '\\' . $namespace . 'Operation\\' . $operationDetails['class']), |
| 62 | + 'params' => iterator_to_array((function (array $operationDetails): iterable { |
| 63 | + foreach ($operationDetails['operation']->parameters as $parameter) { |
| 64 | + yield $parameter->name; |
| 65 | + } |
| 66 | + })($operationDetails)), |
| 67 | + 'returnType' => $returnType, |
| 68 | + ]; |
| 69 | + } |
| 70 | + $class->addStmt( |
| 71 | + $factory->method($casedOperationgroup)->setReturnType($cn)->makePublic() |
| 72 | + ); |
| 73 | + } |
| 74 | + |
| 75 | + $class->addStmt( |
| 76 | + $factory->method('call')->makePublic()->setReturnType( |
| 77 | + new Node\Name('\\' . PromiseInterface::class) |
| 78 | + )->setDocComment( |
| 79 | + new Doc(implode(PHP_EOL, [ |
| 80 | + '/**', |
| 81 | + ' * @return \\' . PromiseInterface::class . '<' . implode('|', array_unique($callReturnTypes)) . '>', |
| 82 | + ' */', |
| 83 | + ])) |
| 84 | + )->addParam((new Param('call'))->setType('string'))->addParam((new Param('params'))->setType('array')->setDefault([])) |
| 85 | + ); |
| 86 | + |
| 87 | + $class->addStmt( |
| 88 | + $factory->method('hydrateObject')->makePublic()->setReturnType('object')->addParam( |
| 89 | + (new Param('className'))->setType('string') |
| 90 | + )->addParam( |
| 91 | + (new Param('data'))->setType('array') |
| 92 | + ) |
| 93 | + ); |
| 94 | + |
| 95 | + yield new File($namespace . '\\' . 'ClientInterface', $stmt->addStmt($class)->getNode()); |
| 96 | + } |
| 97 | +} |
0 commit comments