Skip to content

Introduce client to wire operations up #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2022
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
30 changes: 29 additions & 1 deletion src/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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) {
Expand Down
66 changes: 66 additions & 0 deletions src/Generator/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace ApiClients\Tools\OpenApiClientGenerator\Generator;

use ApiClients\Tools\OpenApiClientGenerator\File;
use cebe\openapi\spec\Operation as OpenAPiOperation;
use PhpParser\Builder\Param;
use PhpParser\BuilderFactory;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use Psr\Http\Message\RequestInterface;
use RingCentral\Psr7\Request;

final class Client
{
/**
* @param array<string, string> $operations
* @return iterable<Node>
*/
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());
}
}
50 changes: 50 additions & 0 deletions src/Generator/Clients.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace ApiClients\Tools\OpenApiClientGenerator\Generator;

use ApiClients\Tools\OpenApiClientGenerator\File;
use cebe\openapi\spec\Operation as OpenAPiOperation;
use cebe\openapi\spec\PathItem;
use Jawira\CaseConverter\Convert;
use League\OpenAPIValidation\Schema\Exception\SchemaMismatch;
use PhpParser\Builder\Param;
use PhpParser\BuilderFactory;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ServerRequestInterface;
use RingCentral\Psr7\Request;

final class Clients
{
/**
* @return iterable<Node>
* @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());
}
}