Repository: Lomkit/laravel-rest-api (php)

Issue:
Generate Documentation no message
### Description

Hello, when the documentation generate, there is no success message, would it be possible to notify the user it worked :) ?

Pull request description:
Feature/documentation
closes #63 

Patch:
diff --git a/src/Console/Commands/DocumentationCommand.php b/src/Console/Commands/DocumentationCommand.php
index c930043..76eeaa0 100644
--- a/src/Console/Commands/DocumentationCommand.php
+++ b/src/Console/Commands/DocumentationCommand.php
@@ -43,6 +43,9 @@ class DocumentationCommand extends GeneratorCommand implements PromptsForMissing
             $path,
             json_encode($openApi->jsonSerialize())
         );
+
+        $this->info('The documentation was generated successfully!');
+        $this->info('Open '.url(config('rest.documentation.routing.path')).'in a web browser.');
     }
 
     /**
diff --git a/src/Console/Commands/DocumentationProviderCommand.php b/src/Console/Commands/DocumentationProviderCommand.php
new file mode 100644
index 0000000..38d9d72
--- /dev/null
+++ b/src/Console/Commands/DocumentationProviderCommand.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Lomkit\Rest\Console\Commands;
+
+use Illuminate\Console\GeneratorCommand;
+use Illuminate\Contracts\Console\PromptsForMissingInput;
+use Lomkit\Rest\Console\ResolvesStubPath;
+
+class DocumentationProviderCommand extends GeneratorCommand implements PromptsForMissingInput
+{
+    use ResolvesStubPath;
+
+    /**
+     * The console command signature.
+     *
+     * @var string
+     */
+    protected $signature = 'rest:documentation-provider {name=RestDocumentationServiceProvider : The name of the service provider}
+        {--path= : The location where the service provider file should be created}';
+
+    /**
+     * The type of class being generated.
+     *
+     * @var string
+     */
+    protected $type = 'Service provider';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Create the documentation service provider class';
+
+    /**
+     * Get the stub file for the generator.
+     *
+     * @return string
+     */
+    protected function getStub()
+    {
+        return $this->resolveStubPath('/stubs/rest/rest-documentation-service-provider.stub');
+    }
+
+    /**
+     * Get the path where the action file should be created.
+     *
+     * @param string $name
+     *
+     * @return string
+     */
+    protected function getPath($name)
+    {
+        if (!is_null($this->option('path'))) {
+            return $this->option('path').'/'.$this->argument('name').'.php';
+        }
+
+        return parent::getPath($name);
+    }
+
+    /**
+     * Get the default namespace for the class.
+     *
+     * @param string $rootNamespace
+     *
+     * @return string
+     */
+    protected function getDefaultNamespace($rootNamespace)
+    {
+        return $rootNamespace.'\Providers';
+    }
+
+    /**
+     * Get the default namespace for the class.
+     *
+     * @return string
+     */
+    protected function getResourceNamespace()
+    {
+        $rootNamespace = $this->laravel->getNamespace();
+
+        return is_dir(app_path('Providers')) ? $rootNamespace.'Providers\\' : $rootNamespace;
+    }
+}
diff --git a/src/Console/stubs/rest-documentation-service-provider.stub b/src/Console/stubs/rest-documentation-service-provider.stub
new file mode 100644
index 0000000..2682131
--- /dev/null
+++ b/src/Console/stubs/rest-documentation-service-provider.stub
@@ -0,0 +1,45 @@
+<?php
+
+namespace {{ namespace }};
+
+use Illuminate\Support\ServiceProvider;
+use Lomkit\Rest\Documentation\Schemas\OpenAPI;
+use Lomkit\Rest\Documentation\Schemas\Operation;
+use Lomkit\Rest\Documentation\Schemas\Path;
+use Lomkit\Rest\Facades\Rest;
+
+class RestDocumentationServiceProvider extends ServiceProvider
+{
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        //
+    }
+
+    /**
+     * Bootstrap any application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        Rest::withDocumentationCallback(function (OpenAPI $openAPI) {
+            $openAPI->withPaths(
+                [
+                    'myPath' => (new Path)
+                        ->withDescription('my custom path')
+                        ->withGet(
+                            (new Operation)
+                                ->withTags(['Callable'])
+                                ->withSummary('You should call this !')
+                        )
+                ]
+            );
+            return $openAPI;
+        });
+    }
+}
diff --git a/src/Documentation/Schemas/RequestBody.php b/src/Documentation/Schemas/RequestBody.php
index 3e8e2b5..887e272 100644
--- a/src/Documentation/Schemas/RequestBody.php
+++ b/src/Documentation/Schemas/RequestBody.php
@@ -3,6 +3,9 @@
 namespace Lomkit\Rest\Documentation\Schemas;
 
 use Lomkit\Rest\Http\Controllers\Controller;
+use Lomkit\Rest\Http\Requests\RestRequest;
+use Lomkit\Rest\Instructions\Instruction;
+use Lomkit\Rest\Relations\Relation;
 
 class RequestBody extends Schema
 {
@@ -103,9 +106,9 @@ class RequestBody extends Schema
     /**
      * Generate and return the request body schema.
      *
-     * @return Schema
+     * @return RequestBody
      */
-    public function generate(): Schema
+    public function generate(): RequestBody
     {
         return $this;
     }
@@ -133,6 +136,8 @@ class RequestBody extends Schema
      */
     public function generateSearch(Controller $controller): RequestBody
     {
+        $request = app()->make(RestRequest::class);
+
         return $this
             ->withContent(
                 [
@@ -141,61 +146,83 @@ class RequestBody extends Schema
                             (new Example())
                                 ->withValue(
                                     [
-                                        'scopes' => [
-                                            ['name' => 'withTrashed', 'parameters' => [true]],
-                                        ],
-                                        'filters' => [
-                                            ['field' => 'id', 'operator' => '>', 'value' => 1, 'type' => 'or'],
-                                            ['nested' => [
-                                                ['field' => 'user.id', 'operator' => '<', 'value' => 2],
-                                                ['field' => 'id', 'operator' => '>', 'value' => 100, 'type' => 'or'],
-                                            ]],
-                                        ],
-                                        'sorts' => [
-                                            ['field' => 'user_id', 'direction' => 'desc'],
-                                            ['field' => 'id', 'direction' => 'asc'],
-                                        ],
-                                        'selects' => [
-                                            ['field' => 'id'],
-                                        ],
-                                        'includes' => [
+                                        'search' => array_merge(
+                                            // Scopes
                                             [
-                                                'relation' => 'posts',
-                                                'filters'  => [
-                                                    ['field' => 'id', 'operator' => 'in', 'value' => [1, 3]],
-                                                ],
-                                                'limit' => 2,
+                                                'scopes' => collect($controller::newResource()->getScopes($request))
+                                                        ->map(function ($scope) {
+                                                            return ['name' => $scope, 'parameters' => []];
+                                                        })
+                                                        ->toArray(),
                                             ],
-                                        ],
-                                        'aggregates' => [
+                                            // Filters
                                             [
-                                                'relation' => 'stars',
-                                                'type'     => 'max',
-                                                'field'    => 'rate',
-                                                'filters'  => [
-                                                    [
-                                                        'name'  => 'type',
-                                                        'value' => 'odd',
-                                                    ],
-                                                ],
+                                                'filters' => collect($controller::newResource()->getFields($request))
+                                                        ->map(function ($filter) {
+                                                            return ['field' => $filter, 'operator' => '=', 'value' => ''];
+                                                        })
+                                                        ->toArray(),
                                             ],
-                                        ],
-                                        'instructions' => [
+                                            // Sorts
+                                            [
+                                                'sorts' => collect($controller::newResource()->getFields($request))
+                                                        ->map(function ($sort) {
+                                                            return ['field' => $sort, 'direction' => 'desc'];
+                                                        })
+                                                        ->toArray(),
+                                            ],
+                                            // Selects
+                                            [
+                                                'selects' => collect($controller::newResource()->getFields($request))
+                                                        ->map(function ($select) {
+                                                            return ['field' => $select];
+                                                        })
+                                                        ->toArray(),
+                                            ],
+                                            // Includes
+                                            [
+                                                'includes' => collect($controller::newResource()->getRelations($request))
+                                                        ->map(function (Relation $relation) {
+                                                            return ['relation' => $relation->relation];
+                                                        })
+                                                        ->toArray(),
+                                            ],
+                                            // Aggregates
+                                            [
+                                                'aggregates' => [],
+                                            ],
+                                            // Instructions
+                                            [
+                                                'instructions' => collect($controller::newResource()->getInstructions($request))
+                                                        ->map(function (Instruction $instruction) use ($request) {
+                                                            return [
+                                                                'name'   => $instruction->name(),
+                                                                'fields' => collect($instruction->fields($request))
+                                                                    ->map(function ($field) {
+                                                                        return ['field' => $field, 'value' => ''];
+                                                                    })
+                                                                    ->toArray(),
+                                                            ];
+                                                        })
+                                                        ->toArray(),
+                                            ],
+                                            // Gates
                                             [
-                                                'name'   => 'odd-even-id',
-                                                'fields' => [
-                                                    [
-                                                        'name'  => 'type',
-                                                        'value' => 'odd',
-                                                    ],
+                                                'gates' => [
+                                                    'create',
+                                                    'update',
+                                                    'delete',
                                                 ],
                                             ],
-                                        ],
-                                        'gates' => [
-                                            'create',
-                                        ],
-                                        'page'  => 2,
-                                        'limit' => 10,
+                                            // Page
+                                            [
+                                                'page' => 1,
+                                            ],
+                                            // Limit
+                                            [
+                                                'limit' => $controller::newResource()->getLimits($request)[0],
+                                            ]
+                                        ),
                                     ]
                                 )
                                 ->generate()
@@ -215,6 +242,8 @@ class RequestBody extends Schema
      */
     public function generateMutate(Controller $controller): RequestBody
     {
+        $request = app()->make(RestRequest::class);
+
         return $this
             ->withContent(
                 [
@@ -226,25 +255,23 @@ class RequestBody extends Schema
                                         'mutate' => [
                                             [
                                                 'operation'  => 'create',
-                                                'attributes' => ['email' => 'me@email.com'],
-                                                'relations'  => [
-                                                    'star' => [
-                                                        'operation'  => 'create',
-                                                        'attributes' => ['number' => 2],
-                                                    ],
-                                                ],
+                                                // Attributes
+                                                'attributes' => collect($controller::newResource()->getFields($request))
+                                                        ->mapWithKeys(function ($field) {
+                                                            return [$field => ''];
+                                                        })
+                                                        ->toArray(),
+                                                // Relations
+                                                'relations'  => collect($controller::newResource()->getRelations($request))
+                                                        ->mapWithKeys(function (Relation $relation) {
+                                                            return [$relation->relation => [
+                                                                'operation' => 'update',
+                                                                'key'       => 1,
+                                                            ]];
+                                                        })
+                                                        ->toArray(),
                                             ],
-                                            [
-                                                'operation'  => 'update',
-                                                'key'        => 1,
-                                                'attributes' => ['email' => 'me@email.com'],
-                                                'relations'  => [
-                                                    'star' => [
-                                                        'operation' => 'detach',
-                                                        'key'       => 1,
-                                                    ],
-                                                ],
-                                            ]],
+                                        ],
                                     ]
                                 )
                                 ->generate()
diff --git a/src/RestServiceProvider.php b/src/RestServiceProvider.php
index f78c7d0..5de82e7 100644
--- a/src/RestServiceProvider.php
+++ b/src/RestServiceProvider.php
@@ -9,6 +9,7 @@ use Lomkit\Rest\Console\Commands\BaseControllerCommand;
 use Lomkit\Rest\Console\Commands\BaseResourceCommand;
 use Lomkit\Rest\Console\Commands\ControllerCommand;
 use Lomkit\Rest\Console\Commands\DocumentationCommand;
+use Lomkit\Rest\Console\Commands\DocumentationProviderCommand;
 use Lomkit\Rest\Console\Commands\InstructionCommand;
 use Lomkit\Rest\Console\Commands\QuickStartCommand;
 use Lomkit\Rest\Console\Commands\ResourceCommand;
@@ -95,6 +96,7 @@ class RestServiceProvider extends ServiceProvider
                 ActionCommand::class,
                 InstructionCommand::class,
                 DocumentationCommand::class,
+                DocumentationProviderCommand::class,
             ]);
         }
     }


Test patch:
diff --git a/tests/Feature/Commands/DocumentationCommandTest.php b/tests/Feature/Commands/DocumentationCommandTest.php
index df06f02..cb92ab0 100644
--- a/tests/Feature/Commands/DocumentationCommandTest.php
+++ b/tests/Feature/Commands/DocumentationCommandTest.php
@@ -12,4 +12,11 @@ class DocumentationCommandTest extends TestCase
 
         $this->assertFileExists('./.phpunit.cache/openapi.json');
     }
+
+    public function test_create_documentation_service_provider_class(): void
+    {
+        $this->artisan('rest:documentation-provider', ['--path' => './.phpunit.cache'])->assertOk();
+
+        $this->assertFileExists('./.phpunit.cache/RestDocumentationServiceProvider.php');
+    }
 }