Skip to content

Commit

Permalink
added document transformers
Browse files Browse the repository at this point in the history
  • Loading branch information
romalytvynenko committed Jan 31, 2025
1 parent 318ae2b commit c16fa68
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 14 deletions.
52 changes: 52 additions & 0 deletions src/Configuration/DocumentTransformers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Dedoc\Scramble\Configuration;

use Illuminate\Support\Arr;

class DocumentTransformers
{
protected array $transformers = [];

protected array $appends = [];

protected array $prepends = [];

public function append(array|callable|string $transformers)
{
$this->appends = array_merge(
$this->appends,
Arr::wrap($transformers)
);

return $this;
}

public function prepend(array|callable|string $transformers)
{
$this->prepends = array_merge(
$this->prepends,
Arr::wrap($transformers)
);

return $this;
}

public function use(array $transformers)
{
$this->transformers = $transformers;

return $this;
}

public function all(): array
{
$base = $this->transformers;

return array_values(array_unique([
...$this->prepends,
...$base,
...$this->appends,
], SORT_REGULAR));
}
}
11 changes: 11 additions & 0 deletions src/Contracts/DocumentTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Dedoc\Scramble\Contracts;

use Dedoc\Scramble\OpenApiContext;
use Dedoc\Scramble\Support\Generator\OpenApi;

interface DocumentTransformer
{
public function handle(OpenApi $document, OpenApiContext $context);
}
13 changes: 9 additions & 4 deletions src/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Dedoc\Scramble\Exceptions\RouteAware;
use Dedoc\Scramble\Infer\Services\FileParser;
use Dedoc\Scramble\OpenApiVisitor\SchemaEnforceVisitor;
use Dedoc\Scramble\Support\ContainerUtils;
use Dedoc\Scramble\Support\Generator\Components;
use Dedoc\Scramble\Support\Generator\InfoObject;
use Dedoc\Scramble\Support\Generator\OpenApi;
Expand Down Expand Up @@ -91,10 +92,14 @@ public function __invoke(?GeneratorConfig $config = null)

$this->moveSameAlternativeServersToPath($openApi);

if ($afterOpenApiGenerated = $config->afterOpenApiGenerated()) {
foreach ($afterOpenApiGenerated as $openApiTransformer) {
$openApiTransformer($openApi, $context);
}
foreach ($config->documentTransformers->all() as $openApiTransformer) {
$openApiTransformer = is_callable($openApiTransformer)
? $openApiTransformer
: ContainerUtils::makeContextable($openApiTransformer, [
TypeTransformer::class => $typeTransformer,
]);

$openApiTransformer($openApi, $context);
}

return $openApi->toArray();
Expand Down
40 changes: 32 additions & 8 deletions src/GeneratorConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace Dedoc\Scramble;

use Closure;
use Dedoc\Scramble\Configuration\DocumentTransformers;
use Dedoc\Scramble\Configuration\OperationTransformers;
use Dedoc\Scramble\Configuration\ParametersExtractors;
use Dedoc\Scramble\Contracts\DocumentTransformer;
use Illuminate\Routing\Route;
use Illuminate\Routing\Router;
use Illuminate\Support\Arr;
Expand All @@ -27,9 +29,9 @@ class GeneratorConfig
public function __construct(
private array $config = [],
private ?Closure $routeResolver = null,
private array $afterOpenApiGenerated = [],
public readonly ParametersExtractors $parametersExtractors = new ParametersExtractors,
public readonly OperationTransformers $operationTransformers = new OperationTransformers,
public readonly DocumentTransformers $documentTransformers = new DocumentTransformers,
) {}

public function config(array $config)
Expand Down Expand Up @@ -82,11 +84,11 @@ private function defaultRoutesFilter(Route $route)
public function afterOpenApiGenerated(?callable $afterOpenApiGenerated = null)
{
if (count(func_get_args()) === 0) {
return $this->afterOpenApiGenerated;
return $this->documentTransformers->all();
}

if ($afterOpenApiGenerated) {
$this->afterOpenApiGenerated[] = $afterOpenApiGenerated;
$this->documentTransformers->append($afterOpenApiGenerated);
}

return $this;
Expand Down Expand Up @@ -114,11 +116,7 @@ public function withOperationTransformers(array|string|callable $cb): static
return $this;
}

$cb = function (OperationTransformers $transformers) use ($cb) {
$transformers->append($cb);
};

$cb($this->operationTransformers);
$this->operationTransformers->append($cb);

return $this;
}
Expand All @@ -136,6 +134,32 @@ private function isOperationTransformerMapper($cb): bool
&& is_a($reflection->getParameters()[0]->getType()->getName(), OperationTransformers::class, true);
}

public function withDocumentTransformers(array|string|callable $cb): static
{
if ($this->isDocumentTransformerMapper($cb)) {
$cb($this->documentTransformers);

return $this;
}

$this->documentTransformers->append($cb);

return $this;
}

private function isDocumentTransformerMapper($cb): bool
{
if (! $cb instanceof Closure) {
return false;
}

$reflection = new ReflectionFunction($cb);

return count($reflection->getParameters()) === 1
&& $reflection->getParameters()[0]->getType() instanceof ReflectionNamedType
&& is_a($reflection->getParameters()[0]->getType()->getName(), DocumentTransformer::class, true);
}

public function get(string $key, mixed $default = null)
{
return Arr::get($this->config, $key, $default);
Expand Down
2 changes: 1 addition & 1 deletion src/Scramble.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static function extendOpenApi(callable $openApiExtender)
*/
public static function afterOpenApiGenerated(callable $afterOpenApiGenerated)
{
static::configure()->afterOpenApiGenerated($afterOpenApiGenerated);
static::configure()->withDocumentTransformers($afterOpenApiGenerated);
}

public static function routes(callable $routeResolver)
Expand Down
3 changes: 2 additions & 1 deletion src/Support/OperationBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Dedoc\Scramble\Support\Generator\OpenApi;
use Dedoc\Scramble\Support\Generator\Operation;
use Dedoc\Scramble\Support\Generator\TypeTransformer;
use InvalidArgumentException;

/** @internal */
class OperationBuilder
Expand Down Expand Up @@ -36,7 +37,7 @@ public function build(RouteInfo $routeInfo, OpenApi $openApi, GeneratorConfig $c
continue;
}

// throw here.
throw new InvalidArgumentException('(callable(Operation, RouteInfo): void)|OperationTransformer type for operation transformer expected, received '.$instance::class);
}

return $operation;
Expand Down

0 comments on commit c16fa68

Please sign in to comment.