Skip to content

Commit

Permalink
feat: Auto generates presenter & DTO from column properties
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-code-labx committed Apr 5, 2024
1 parent c608d10 commit 84c06cf
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 17 deletions.
12 changes: 7 additions & 5 deletions src/Commands/Generator/MakeData.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace XtendPackages\RESTPresenter\Commands\Generator;

use Carbon\Carbon;
use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Str;
use Spatie\LaravelData\Optional;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -85,15 +83,19 @@ protected function buildResourceReplacements(): array

protected function transformFieldProperties(array $fields): string
{
return collect($fields)->map(function (string $fieldType, string $field) {
$propertyType = match ($fieldType) {
'int', 'bigint' => 'int',
return collect($fields)->map(function (array $fieldProperties, string $field) {
$propertyType = match ($fieldProperties['type']) {
'int', 'integer', 'bigint' => 'int',
'tinyint' => 'bool',
'timestamp', 'datetime' => 'Carbon | Optional | null',
'json' => 'array',
default => 'string',
};

if ($fieldProperties['nullable'] && $propertyType !== 'Carbon | Optional | null') {
$propertyType = '?' . $propertyType;
}

return "public {$propertyType} \${$field}";
})->implode(",\n\t\t");
}
Expand Down
13 changes: 10 additions & 3 deletions src/Commands/Generator/MakePresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ class MakePresenter extends GeneratorCommand
public function handle()
{
if ($this->hasArgument('fields') && is_array($this->argument('fields'))) {
$presenter = Str::of($this->argument('name'))->replace('Presenter', '');
$this->call('rest-presenter:make-data', [
'type' => 'new',
'name' => $this->argument('name') . 'Data',
'name' => $presenter->singular()->value() . 'Data',
'resource' => $this->argument('resource'),
'fields' => $this->argument('fields'),
'model' => $this->argument('model'),
'presenter' => $this->argument('name'),
'presenter' => $presenter->plural()->value(),
'kit_namespace' => $this->argument('kit_namespace'),
]);
}
Expand Down Expand Up @@ -63,7 +64,12 @@ protected function getDefaultNamespace($rootNamespace): string
$resourceDirectory = Str::plural($this->argument('resource'));

if ($this->argument('kit_namespace')) {
return config('rest-presenter.generator.namespace') . '\\' . $this->argument('kit_namespace') . '\\Presenters\\' . $this->argument('name');
$presenterNamespace = Str::of($this->argument('name'))
->replace('Presenter', '')
->plural()
->value();

return config('rest-presenter.generator.namespace') . '\\' . $this->argument('kit_namespace') . '\\Presenters\\' . $presenterNamespace;
}

return config('rest-presenter.generator.namespace') . '\\Resources\\' . $resourceDirectory . '\\Presenters\\' . $this->argument('name');
Expand Down Expand Up @@ -94,6 +100,7 @@ protected function buildResourceReplacements(): array
'{{ modelClassName }}' => class_basename($this->argument('model')),
'{{ $modelVarSingular }}' => strtolower(class_basename($this->argument('model'))),
'{{ $modelVarPlural }}' => strtolower(Str::plural(class_basename($this->argument('model')))),
'{{ dataClass }}' => Str::of($this->argument('name'))->remove('Presenter')->append('Data')->value(),
];
}

Expand Down
14 changes: 14 additions & 0 deletions src/Commands/Generator/MakeResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ protected function transformFilters(): string

protected function transformPresenters(): string
{
if ($this->hasArgument('presenters') && is_array($this->argument('presenters'))) {
$presenters = $this->argument('presenters');

return collect($presenters)->map(
function ($presenter, $presenterKey) {
$presenterNamespace = Str::of($presenterKey)->replace('Presenter', '')->plural()->ucfirst();

return "'$presenterKey' => Presenters\\" . $presenterNamespace . '\\' . $presenter;
},
)->implode(",\n\t\t\t") . ',';
}

if ($this->presenters->isEmpty()) {
return '';
}
Expand All @@ -164,6 +176,8 @@ protected function getArguments()
['name', InputArgument::REQUIRED, 'The name of the ' . strtolower($this->type)],
['type', InputArgument::OPTIONAL, 'The type of resource to create'],
['model', InputArgument::OPTIONAL, 'The model that the resource references'],
['filters', InputArgument::OPTIONAL, 'The filters to include in the resource'],
['presenters', InputArgument::OPTIONAL, 'The presenters to include in the resource'],
['kit_namespace', InputArgument::OPTIONAL, 'The namespace of the ' . strtolower($this->type)],
];
}
Expand Down
6 changes: 3 additions & 3 deletions src/Commands/Generator/stubs/new/presenter.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace {{ namespace }};

use {{ namespace }}\Data\{{ class }}Data;
use {{ namespace }}\Data\{{ dataClass }};
use {{ modelClassImport }} as {{ modelClassName }}Model;
use Illuminate\Http\Request;
use Spatie\LaravelData\Data;
Expand All @@ -18,8 +18,8 @@ class {{ class }} implements Presentable
protected ?{{ modelClassName }}Model $model,
) {}

public function transform(): {{ class }}Data | Data
public function transform(): {{ dataClass }} | Data
{
return {{ class }}Data::from($this->model);
return {{ dataClass }}::from($this->model);
}
}
34 changes: 28 additions & 6 deletions src/Commands/XtendStarterKit.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,34 @@ protected function autoDiscoverResources(string $kitPath): void
->value();

collect($resources)->each(function ($resource, $resourceNamespace) use ($kitNamespace) {
$this->call('rest-presenter:make-resource', [
'kit_namespace' => $kitNamespace . '\\' . $resourceNamespace,
'name' => Str::of($resourceNamespace)->classBasename()->value(),
'model' => $resource['model'],
'type' => 'new',
]);
$resourceName = Str::of($resourceNamespace)
->classBasename()
->singular()
->value();

if ($resource['fields']) {
$this->call(
command: 'rest-presenter:make-presenter',
arguments: [
'kit_namespace' => $kitNamespace . '\\' . $resourceNamespace,
'name' => $resourceName . 'Presenter',
'type' => 'new',
'model' => $resource['model'],
'resource' => $resourceName,
'fields' => $resource['fields'],
],
);

$this->call('rest-presenter:make-resource', [
'kit_namespace' => $kitNamespace . '\\' . $resourceNamespace,
'name' => $resourceName,
'model' => $resource['model'],
'presenters' => [
strtolower($resourceName) => $resourceName . 'Presenter::class',
],
'type' => 'new',
]);
}
});
}

Expand Down

0 comments on commit 84c06cf

Please sign in to comment.