Skip to content

Generate unknown schemas #61

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
Dec 24, 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
43 changes: 27 additions & 16 deletions src/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public function generate(string $namespace, string $destinationPath)
}
}

private function className(string $className): string
public static function className(string $className): string
{
return str_replace(['{', '}', '-', '$', '_'], ['Cb', 'Rcb', 'Dash', '_', '\\'], (new Convert($className))->toPascal()) . ($this->isKeyword($className) ? '_' : '');
return str_replace(['{', '}', '-', '$', '_'], ['Cb', 'Rcb', 'Dash', '_', '\\'], (new Convert($className))->toPascal()) . (self::isKeyword($className) ? '_' : '');
}

private function cleanUpNamespace(string $namespace): string
Expand All @@ -57,17 +57,17 @@ private function cleanUpNamespace(string $namespace): string
*/
private function all(string $namespace): iterable
{
$schemaRegistry = new SchemaRegistry();
if (count($this->spec->components->schemas ?? []) > 0) {
$schemaClassNameMap = [];
foreach ($this->spec->components->schemas as $name => $schema) {
$schemaClassName = $this->className($name);
$schemaClassName = self::className($name);
if (strlen($schemaClassName) === 0) {
continue;
}
$schemaClassNameMap[spl_object_hash($schema)] = $schemaClassName;
$schemaRegistry->addClassName($schemaClassName, $schema);
}
foreach ($this->spec->components->schemas as $name => $schema) {
$schemaClassName = $schemaClassNameMap[spl_object_hash($schema)];
$schemaClassName = $schemaRegistry->get($schema);
if (strlen($schemaClassName) === 0) {
continue;
}
Expand All @@ -77,7 +77,7 @@ private function all(string $namespace): iterable
$this->dirname($namespace . 'Schema/' . $schemaClassName),
$this->basename($namespace . 'Schema/' . $schemaClassName),
$schema,
$schemaClassNameMap,
$schemaRegistry,
$namespace . 'Schema'
);
}
Expand All @@ -86,7 +86,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);
$pathClassName = self::className($path);
if (strlen($pathClassName) === 0) {
continue;
}
Expand All @@ -100,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 = self::className((new Convert($operation->operationId))->fromTrain()->toPascal()) . '_';
$operations[$method] = $operationClassName;
if (strlen($operationClassName) === 0) {
continue;
Expand All @@ -113,7 +113,7 @@ private function all(string $namespace): iterable
$namespace,
$this->basename($namespace . 'Operation/' . $operationClassName),
$operation,
$schemaClassNameMap
$schemaRegistry
);

[$operationGroup, $operationOperation] = explode('/', $operationClassName);
Expand All @@ -128,7 +128,7 @@ private function all(string $namespace): iterable
}
}

yield from (function (array $clients, string $namespace, array $schemaClassNameMap): \Generator {
yield from (function (array $clients, string $namespace, SchemaRegistry $schemaRegistry): \Generator {
foreach ($clients as $operationGroup => $operations) {
yield from Client::generate(
$operationGroup,
Expand All @@ -141,14 +141,14 @@ private function all(string $namespace): iterable
yield from Clients::generate(
$namespace,
$clients,
$schemaClassNameMap,
$schemaRegistry,
);
})($clients, $namespace, $schemaClassNameMap);
})($clients, $namespace, $schemaRegistry);

if (count($this->spec->webhooks ?? []) > 0) {
$pathClassNameMapping = [];
foreach ($this->spec->webhooks as $path => $pathItem) {
$webHookClassName = $this->className($path);
$webHookClassName = self::className($path);
$pathClassNameMapping[$path] = $this->fqcn($namespace . 'WebHook/' . $webHookClassName);
if (strlen($webHookClassName) === 0) {
continue;
Expand All @@ -160,7 +160,7 @@ private function all(string $namespace): iterable
$namespace,
$this->basename($namespace . 'WebHook/' . $webHookClassName),
$pathItem,
$schemaClassNameMap,
$schemaRegistry,
$namespace
);
}
Expand All @@ -175,6 +175,17 @@ private function all(string $namespace): iterable
$pathClassNameMapping,
);
}

foreach ($schemaRegistry->unknownSchemas() as $schema) {
yield from Schema::generate(
$schema['name'],
$this->dirname($namespace . 'Schema/' . $schema['className']),
$this->basename($namespace . 'Schema/' . $schema['className']),
$schema['schema'],
$schemaRegistry,
$namespace . 'Schema'
);
}
}

private function fqcn(string $fqcn): string
Expand All @@ -196,7 +207,7 @@ private function basename(string $fqcn): string
return $this->cleanUpNamespace(basename($fqcn));
}

private function isKeyword(string $name): bool
private static function isKeyword(string $name): bool
{
return in_array($name, array('__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor'), false);
}
Expand Down
5 changes: 3 additions & 2 deletions src/Generator/Clients.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ApiClients\Tools\OpenApiClientGenerator\Generator;

use ApiClients\Tools\OpenApiClientGenerator\File;
use ApiClients\Tools\OpenApiClientGenerator\SchemaRegistry;
use cebe\openapi\spec\Operation as OpenAPiOperation;
use cebe\openapi\spec\PathItem;
use Jawira\CaseConverter\Convert;
Expand All @@ -26,7 +27,7 @@ final class Clients
* @return iterable<Node>
* @throws \Jawira\CaseConverter\CaseConverterException
*/
public static function generate(string $namespace, array $clients, array $schemaClassNameMap): iterable
public static function generate(string $namespace, array $clients, SchemaRegistry $schemaRegistry): iterable
{
$factory = new BuilderFactory();
$stmt = $factory->namespace(rtrim($namespace, '\\'));
Expand Down Expand Up @@ -94,7 +95,7 @@ public static function generate(string $namespace, array $clients, array $schema
$returnType = [];
foreach ($operationDetails['operation']->responses as $spec) {
foreach ($spec->content as $contentTypeSchema) {
$callReturnTypes[] = $returnType[] = '\\' . $namespace . 'Schema\\' . $schemaClassNameMap[spl_object_hash($contentTypeSchema->schema)];
$callReturnTypes[] = $returnType[] = '\\' . $namespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema);
}
}
$operationCalls[] = [
Expand Down
21 changes: 17 additions & 4 deletions src/Generator/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ApiClients\Tools\OpenApiClientGenerator\Generator;

use ApiClients\Tools\OpenApiClientGenerator\File;
use ApiClients\Tools\OpenApiClientGenerator\SchemaRegistry;
use cebe\openapi\spec\Operation as OpenAPiOperation;
use PhpParser\Builder\Param;
use PhpParser\BuilderFactory;
Expand All @@ -25,7 +26,7 @@ final class Operation
* @param OpenAPiOperation $operation
* @return iterable<Node>
*/
public static function generate(string $path, string $method, string $namespace, string $rootNamespace, string $className, OpenAPiOperation $operation, array $schemaClassNameMap): iterable
public static function generate(string $path, string $method, string $namespace, string $rootNamespace, string $className, OpenAPiOperation $operation, SchemaRegistry $schemaRegistry): iterable
{
$factory = new BuilderFactory();
$stmt = $factory->namespace($namespace);
Expand Down Expand Up @@ -180,7 +181,13 @@ public static function generate(string $path, string $method, string $namespace,
new Node\Name('validate'),
[
new Node\Arg(new Node\Expr\Variable('data')),
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [new Node\Scalar\String_(json_encode($requestBodyContent->schema->getSerializableData())), new Node\Scalar\String_('\cebe\openapi\spec\Schema')])),
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [
new Node\Expr\ClassConstFetch(
new Node\Name('\\' . $rootNamespace . 'Schema\\' . $schemaRegistry->get($requestBodyContent->schema)),
new Node\Name('SCHEMA_JSON'),
),
new Node\Scalar\String_('\cebe\openapi\spec\Schema'),
])),
]
))
);
Expand All @@ -207,7 +214,7 @@ public static function generate(string $path, string $method, string $namespace,
foreach ($operation->responses as $code => $spec) {
$contentTypeCases = [];
foreach ($spec->content as $contentType => $contentTypeSchema) {
$returnType[] = $object = '\\' . $rootNamespace . 'Schema\\' . $schemaClassNameMap[spl_object_hash($contentTypeSchema->schema)];
$returnType[] = $object = '\\' . $rootNamespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema);
$ctc = new Node\Stmt\Case_(
new Node\Scalar\String_($contentType),
[
Expand All @@ -219,7 +226,13 @@ public static function generate(string $path, string $method, string $namespace,
new Node\Name('validate'),
[
new Node\Arg(new Node\Expr\Variable('body')),
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [new Node\Scalar\String_(json_encode($contentTypeSchema->schema->getSerializableData())), new Node\Scalar\String_('\cebe\openapi\spec\Schema')])),
new Node\Arg(new Node\Expr\StaticCall(new Node\Name('\cebe\openapi\Reader'), new Node\Name('readFromJson'), [
new Node\Expr\ClassConstFetch(
new Node\Name('\\' . $rootNamespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema)),
new Node\Name('SCHEMA_JSON'),
),
new Node\Scalar\String_('\cebe\openapi\spec\Schema'),
])),
]
)),
new Node\Stmt\Return_(new Node\Expr\MethodCall(
Expand Down
Loading