diff --git a/src/Generator.php b/src/Generator.php index a70bcd1..5b4b419 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -2,6 +2,8 @@ namespace ApiClients\Tools\OpenApiClientGenerator; +use ApiClients\Tools\OpenApiClientGenerator\Generator\Client; +use ApiClients\Tools\OpenApiClientGenerator\Generator\Clients; use ApiClients\Tools\OpenApiClientGenerator\Generator\Operation; use ApiClients\Tools\OpenApiClientGenerator\Generator\Path; use ApiClients\Tools\OpenApiClientGenerator\Generator\Schema; @@ -81,6 +83,7 @@ private function all(string $namespace): iterable } } + $clients = []; if (count($this->spec->paths ?? []) > 0) { foreach ($this->spec->paths as $path => $pathItem) { $pathClassName = $this->className($path); @@ -97,7 +100,7 @@ private function all(string $namespace): iterable ); foreach ($pathItem->getOperations() as $method => $operation) { - $operationClassName = $this->className((new Convert($operation->operationId))->fromTrain()->toPascal()); + $operationClassName = $this->className((new Convert($operation->operationId))->fromTrain()->toPascal()) . '_'; $operations[$method] = $operationClassName; if (strlen($operationClassName) === 0) { continue; @@ -110,10 +113,35 @@ private function all(string $namespace): iterable $this->basename($namespace . 'Operation/' . $operationClassName), $operation ); + + [$operationGroup, $operationOperation] = explode('/', $operationClassName); + if (!array_key_exists($operationGroup, $clients)) { + $clients[$operationGroup] = []; + } + $clients[$operationGroup][$operationOperation] = [ + 'class' => $operationClassName, + 'operation' => $operation, + ]; } } } + yield from (function (array $clients, string $namespace): \Generator { + foreach ($clients as $operationGroup => $operations) { + yield from Client::generate( + $operationGroup, + $this->dirname($namespace . 'Operation/' . $operationGroup), + $this->basename($namespace . 'Operation/' . $operationGroup), + $operations, + ); + + } + yield from Clients::generate( + $namespace, + $clients, + ); + })($clients, $namespace); + if (count($this->spec->webhooks ?? []) > 0) { $pathClassNameMapping = []; foreach ($this->spec->webhooks as $path => $pathItem) { diff --git a/src/Generator/Client.php b/src/Generator/Client.php new file mode 100644 index 0000000..32ce242 --- /dev/null +++ b/src/Generator/Client.php @@ -0,0 +1,66 @@ + $operations + * @return iterable + */ + public static function generate(string $operationGroup, string $namespace, string $className, array $operations): iterable + { + $factory = new BuilderFactory(); + $stmt = $factory->namespace($namespace); + + $class = $factory->class($className)->makeFinal(); + + foreach ($operations as $operationOperation => $operationDetails) { + $params = []; + $cn = str_replace('/', '\\', '\\' . $namespace . '\\' . $operationDetails['class']); + $method = $factory->method(lcfirst($operationOperation))->setReturnType($cn)->makePublic(); + foreach ($operationDetails['operation']->parameters as $parameter) { + $params[] = new Node\Arg(new Node\Expr\Variable($parameter->name)); + $param = new Param($parameter->name); + if ($parameter->schema->default !== null) { + $param->setType( + str_replace([ + 'integer', + 'any', + 'boolean', + ], [ + 'int', + '', + 'bool', + ], $parameter->schema->type) + ); + } + if ($parameter->schema->default !== null) { + $param->setDefault($parameter->schema->default); + } + $method->addParam($param); + } + $class->addStmt($method->addStmt( + new Node\Stmt\Return_( + new Node\Expr\New_( + new Node\Name( + $cn + ), + $params + ) + ) + )); + } + + yield new File($namespace . '\\' . $className, $stmt->addStmt($class)->getNode()); + } +} diff --git a/src/Generator/Clients.php b/src/Generator/Clients.php new file mode 100644 index 0000000..110f05b --- /dev/null +++ b/src/Generator/Clients.php @@ -0,0 +1,50 @@ + + * @throws \Jawira\CaseConverter\CaseConverterException + */ + public static function generate(string $namespace, array $clients): iterable + { + $factory = new BuilderFactory(); + $stmt = $factory->namespace(rtrim($namespace, '\\')); + + $class = $factory->class('Client')->makeFinal(); + + + foreach ($clients as $operationGroup => $operations) { + $cn = str_replace('/', '\\', '\\' . $namespace . 'Operation/' . $operationGroup); + $class->addStmt( + $factory->method(lcfirst($operationGroup))->setReturnType($cn)->addStmt( + new Node\Stmt\Return_( + new Node\Expr\New_( + new Node\Name( + $cn + ), + ) + ) + )->makePublic() + ); + } + + + yield new File($namespace . '\\' . 'Client', $stmt->addStmt($class)->getNode()); + } +}