92 lines
2.4 KiB
PHP
92 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Docs;
|
|
|
|
use Illuminate\Routing\Route;
|
|
use Illuminate\Support\Facades\Route as RouteFacade;
|
|
|
|
class OpenApiRouteExporter
|
|
{
|
|
public function exportFromFile(string $path): array
|
|
{
|
|
$base = [];
|
|
if (is_file($path)) {
|
|
$json = json_decode((string) file_get_contents($path), true);
|
|
if (is_array($json)) {
|
|
$base = $json;
|
|
}
|
|
}
|
|
|
|
$base['paths'] = $base['paths'] ?? [];
|
|
|
|
foreach (RouteFacade::getRoutes() as $route) {
|
|
$this->mergeRoute($base['paths'], $route);
|
|
}
|
|
|
|
return $base;
|
|
}
|
|
|
|
private function mergeRoute(array &$paths, Route $route): void
|
|
{
|
|
$uriRaw = ltrim($route->uri(), '/');
|
|
if (str_starts_with($uriRaw, 'api/')) {
|
|
$uri = '/' . $uriRaw;
|
|
} elseif (str_starts_with($uriRaw, 'v1/')) {
|
|
$uri = '/api/' . $uriRaw;
|
|
} elseif ($uriRaw === 'v1') {
|
|
$uri = '/api/v1';
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
if (!str_starts_with($uri, '/api/v1')) {
|
|
return;
|
|
}
|
|
|
|
$methods = array_diff($route->methods(), ['HEAD']);
|
|
if (empty($methods)) {
|
|
return;
|
|
}
|
|
|
|
$tag = $this->resolveTag($uri);
|
|
foreach ($methods as $method) {
|
|
$lower = strtolower($method);
|
|
if (!isset($paths[$uri][$lower])) {
|
|
$paths[$uri][$lower] = [
|
|
'tags' => [$tag],
|
|
'summary' => $this->summaryFromAction($route),
|
|
'responses' => [
|
|
'200' => [
|
|
'description' => 'OK',
|
|
],
|
|
],
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
private function resolveTag(string $uri): string
|
|
{
|
|
$trimmed = trim(str_replace('/api/v1', '', $uri), '/');
|
|
if ($trimmed === '') {
|
|
return 'api';
|
|
}
|
|
$segments = explode('/', $trimmed);
|
|
return $segments[0] ?: 'api';
|
|
}
|
|
|
|
private function summaryFromAction(Route $route): string
|
|
{
|
|
$action = $route->getActionName();
|
|
if (is_string($action) && str_contains($action, '@')) {
|
|
[$controller, $method] = explode('@', $action, 2);
|
|
$base = class_basename($controller);
|
|
return $base . '::' . $method;
|
|
}
|
|
if (is_string($action)) {
|
|
return $action;
|
|
}
|
|
return 'Endpoint';
|
|
}
|
|
}
|