EndpointData.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace Knuckles\Camel\Output;
  3. use Illuminate\Http\UploadedFile;
  4. use Illuminate\Routing\Route;
  5. use Knuckles\Camel\BaseDTO;
  6. use Knuckles\Camel\Extraction\ResponseCollection;
  7. use Knuckles\Camel\Extraction\ResponseField;
  8. use Knuckles\Scribe\Extracting\Extractor;
  9. use Knuckles\Scribe\Tools\Utils as u;
  10. class EndpointData extends BaseDTO
  11. {
  12. /**
  13. * @var array<string>
  14. */
  15. public array $methods;
  16. public string $uri;
  17. public Metadata $metadata;
  18. /**
  19. * @var array<string,string>
  20. */
  21. public array $headers = [];
  22. /**
  23. * @var array<string,\Knuckles\Camel\Output\Parameter>
  24. */
  25. public array $urlParameters = [];
  26. /**
  27. * @var array<string,mixed>
  28. */
  29. public array $cleanUrlParameters = [];
  30. /**
  31. * @var array<string,\Knuckles\Camel\Output\Parameter>
  32. */
  33. public array $queryParameters = [];
  34. /**
  35. * @var array<string,mixed>
  36. */
  37. public array $cleanQueryParameters = [];
  38. /**
  39. * @var array<string, \Knuckles\Camel\Output\Parameter>
  40. */
  41. public array $bodyParameters = [];
  42. /**
  43. * @var array<string,mixed>
  44. */
  45. public array $cleanBodyParameters = [];
  46. /**
  47. * @var array<string,\Illuminate\Http\UploadedFile>
  48. */
  49. public array $fileParameters = [];
  50. /**
  51. * @var \Knuckles\Camel\Extraction\ResponseCollection|array
  52. */
  53. public $responses;
  54. /**
  55. * @var array<string,\Knuckles\Camel\Extraction\ResponseField>
  56. */
  57. public array $responseFields = [];
  58. /**
  59. * Authentication info for this endpoint. In the form [{where}, {name}, {sample}]
  60. * Example: ["query", "api_key", "njiuyiw97865rfyvgfvb1"]
  61. */
  62. public array $auth = [];
  63. /**
  64. * @var array<string, array>
  65. */
  66. public array $nestedBodyParameters = [];
  67. public ?string $boundUri;
  68. public ?string $output;
  69. public function __construct(array $parameters = [])
  70. {
  71. // spatie/dto currently doesn't auto-cast nested DTOs like that
  72. $parameters['responses'] = new ResponseCollection($parameters['responses']);
  73. $parameters['bodyParameters'] = array_map(fn($param) => new Parameter($param), $parameters['bodyParameters']);
  74. $parameters['queryParameters'] = array_map(fn($param) => new Parameter($param), $parameters['queryParameters']);
  75. $parameters['urlParameters'] = array_map(fn($param) => new Parameter($param), $parameters['urlParameters']);
  76. $parameters['responseFields'] = array_map(fn($param) => new ResponseField($param), $parameters['responseFields']);
  77. parent::__construct($parameters);
  78. $this->boundUri = u::getUrlWithBoundParameters($this->uri, $this->cleanUrlParameters);
  79. $this->nestedBodyParameters = Extractor::nestArrayAndObjectFields($this->bodyParameters);
  80. $this->cleanBodyParameters = Extractor::cleanParams($this->bodyParameters);
  81. $this->cleanQueryParameters = Extractor::cleanParams($this->queryParameters);
  82. $this->cleanUrlParameters = Extractor::cleanParams($this->urlParameters);
  83. [$files, $regularParameters] = collect($this->cleanBodyParameters)
  84. ->partition(
  85. fn($example) => $example instanceof UploadedFile
  86. || (is_array($example) && ($example[0] ?? null) instanceof UploadedFile)
  87. );
  88. if (count($files)) {
  89. $this->headers['Content-Type'] = 'multipart/form-data';
  90. }
  91. $this->fileParameters = $files->toArray();
  92. $this->cleanBodyParameters = $regularParameters->toArray();
  93. }
  94. /**
  95. * @param Route $route
  96. *
  97. * @return array<string>
  98. */
  99. public static function getMethods(Route $route): array
  100. {
  101. $methods = $route->methods();
  102. // Laravel adds an automatic "HEAD" endpoint for each GET request, so we'll strip that out,
  103. // but not if there's only one method (means it was intentional)
  104. if (count($methods) === 1) {
  105. return $methods;
  106. }
  107. return array_diff($methods, ['HEAD']);
  108. }
  109. public function name()
  110. {
  111. return sprintf("[%s] {$this->route->uri}.", implode(',', $this->route->methods));
  112. }
  113. public function endpointId()
  114. {
  115. return $this->methods[0].str_replace(['/', '?', '{', '}', ':'], '-', $this->uri);
  116. }
  117. public function hasResponses()
  118. {
  119. return count($this->responses) > 0;
  120. }
  121. }