diff --git a/config/request-docs.php b/config/request-docs.php index fdca916..ef767a2 100644 --- a/config/request-docs.php +++ b/config/request-docs.php @@ -153,4 +153,8 @@ ], ], ], + + //export request docs as json file from terminal + //from project root directory + 'export_path' => 'api.json' ]; diff --git a/src/Commands/ExportRequestDocsCommand.php b/src/Commands/ExportRequestDocsCommand.php new file mode 100644 index 0000000..f4934aa --- /dev/null +++ b/src/Commands/ExportRequestDocsCommand.php @@ -0,0 +1,139 @@ +laravelRequestDocs = $laravelRequestDoc; + $this->laravelRequestDocsToOpenApi = $laravelRequestDocsToOpenApi; + } + + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'laravel-request-docs:export + {path? : Export file location} + {--force : Whether to overwrite existing file}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Generate OpenAPI collection as json file'; + + private string $exportFilePath; + + /** + * Execute the console command. + */ + public function handle() + { + if (!$this->confirmFilePathAvailability()) { + //silently stop command + return self::SUCCESS; + } + + try { + //get the excluded methods list from config + $excludedMethods = config('request-docs.open_api.exclude_http_methods', []); + $excludedMethods = array_map(fn($item) => strtolower($item), $excludedMethods); + + //filter while method apis to export + $showGet = !in_array('get', $excludedMethods); + $showPost = !in_array('post', $excludedMethods); + $showPut = !in_array('put', $excludedMethods); + $showPatch = !in_array('patch', $excludedMethods); + $showDelete = !in_array('delete', $excludedMethods); + $showHead = !in_array('head', $excludedMethods); + + // Get a list of Doc with route and rules information. + $docs = $this->laravelRequestDocs->getDocs( + $showGet, + $showPost, + $showPut, + $showPatch, + $showDelete, + $showHead, + ); + + // Loop and split Doc by the `methods` property. + $docs = $this->laravelRequestDocs->splitByMethods($docs); + $docs = $this->laravelRequestDocs->sortDocs($docs, 'default'); + $docs = $this->laravelRequestDocs->groupDocs($docs, 'default'); + + if (!$this->writeApiDocsToFile($docs)) { + throw new ErrorException("Failed to write on [{$this->exportFilePath}] file."); + } + } catch (Exception $exception) { + $this->error('Error : ' . $exception->getMessage()); + return self::FAILURE; + } + + return self::SUCCESS; + } + + /** + * @return bool + */ + private function confirmFilePathAvailability(): bool + { + $path = $this->argument('path'); + + if (!$path) { + $path = config('request-docs.export_path', 'api.json'); + } + + $this->exportFilePath = base_path($path); + + $path = str_replace(base_path('/'), '', $this->exportFilePath); + + if (file_exists($this->exportFilePath)) { + if (!$this->option('force')) { + if ($this->confirm("File exists on [{$path}]. Overwrite?", false) == true) { + return true; + } + return false; + } + } + + return true; + } + + /** + * @param $docs + * @return false|int + */ + private function writeApiDocsToFile(Collection $docs): bool + { + $content = json_encode( + $this->laravelRequestDocsToOpenApi->openApi($docs->all())->toArray(), + JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE + ); + + $targetDirectory = dirname($this->exportFilePath); + + //create parent directory if not exists + if (!is_dir($targetDirectory)) { + mkdir($targetDirectory, 0755, true); + } + + return (bool)file_put_contents($this->exportFilePath, $content); + } +} diff --git a/src/LaravelRequestDocsServiceProvider.php b/src/LaravelRequestDocsServiceProvider.php index c4178b0..0125d7e 100644 --- a/src/LaravelRequestDocsServiceProvider.php +++ b/src/LaravelRequestDocsServiceProvider.php @@ -3,6 +3,7 @@ namespace Rakutentech\LaravelRequestDocs; use Illuminate\Support\Facades\Route; +use Rakutentech\LaravelRequestDocs\Commands\ExportRequestDocsCommand; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -18,6 +19,7 @@ public function configurePackage(Package $package): void $package ->name('laravel-request-docs') ->hasConfigFile('request-docs') + ->hasCommand(ExportRequestDocsCommand::class) // ->hasAssets() ->hasViews(); // ->hasAssets();