OutputEndpointData.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 OutputEndpointData extends BaseDTO
  11. {
  12. /**
  13. * @var array<string>
  14. */
  15. public $methods;
  16. /** @var string */
  17. public $uri;
  18. /** @var \Knuckles\Camel\Extraction\Metadata */
  19. public $metadata;
  20. /**
  21. * @var array<string,string>
  22. */
  23. public $headers = [];
  24. /**
  25. * @var array<string,\Knuckles\Camel\Output\Parameter>
  26. */
  27. public $urlParameters = [];
  28. /**
  29. * @var array<string,mixed>
  30. */
  31. public $cleanUrlParameters = [];
  32. /**
  33. * @var array<string,\Knuckles\Camel\Output\Parameter>
  34. */
  35. public $queryParameters = [];
  36. /**
  37. * @var array<string,mixed>
  38. */
  39. public $cleanQueryParameters = [];
  40. /**
  41. * @var array<string, \Knuckles\Camel\Output\Parameter>
  42. */
  43. public $bodyParameters = [];
  44. /**
  45. * @var array<string,mixed>
  46. */
  47. public $cleanBodyParameters = [];
  48. /**
  49. * @var array
  50. * @var array<string,\Illuminate\Http\UploadedFile>
  51. */
  52. public $fileParameters = [];
  53. /**
  54. * @var \Knuckles\Camel\Extraction\ResponseCollection
  55. */
  56. public $responses;
  57. /**
  58. * @var array<string,\Knuckles\Camel\Extraction\ResponseField>
  59. */
  60. public $responseFields = [];
  61. /**
  62. * @var array<string, array>
  63. */
  64. public $nestedBodyParameters = [];
  65. /** @var string|null */
  66. public $boundUri;
  67. public function __construct(array $parameters = [])
  68. {
  69. // spatie/dto currently doesn't auto-cast nested DTOs like that
  70. $parameters['responses'] = new ResponseCollection($parameters['responses']);
  71. $parameters['bodyParameters'] = array_map(function ($param) {
  72. return new Parameter($param);
  73. }, $parameters['bodyParameters']);
  74. $parameters['queryParameters'] = array_map(function ($param) {
  75. return new Parameter($param);
  76. }, $parameters['queryParameters']);
  77. $parameters['urlParameters'] = array_map(function ($param) {
  78. return new Parameter($param);
  79. }, $parameters['urlParameters']);
  80. $parameters['responseFields'] = array_map(function ($param) {
  81. return new ResponseField($param);
  82. }, $parameters['responseFields']);
  83. parent::__construct($parameters);
  84. $this->nestedBodyParameters = Extractor::nestArrayAndObjectFields($this->bodyParameters);
  85. $this->cleanBodyParameters = Extractor::cleanParams($this->bodyParameters);
  86. $this->cleanQueryParameters = Extractor::cleanParams($this->queryParameters);
  87. $this->cleanUrlParameters = Extractor::cleanParams($this->urlParameters);
  88. $this->boundUri = u::getUrlWithBoundParameters($this->uri, $this->cleanUrlParameters);
  89. [$files, $regularParameters] = collect($this->cleanBodyParameters)
  90. ->partition(
  91. function ($example) {
  92. return $example instanceof UploadedFile
  93. || (is_array($example) && ($example[0] ?? null) instanceof UploadedFile);
  94. }
  95. );
  96. if (count($files)) {
  97. $this->headers['Content-Type'] = 'multipart/form-data';
  98. }
  99. $this->fileParameters = $files->toArray();
  100. $this->cleanBodyParameters = $regularParameters->toArray();
  101. }
  102. /**
  103. * @param Route $route
  104. *
  105. * @return array<string>
  106. */
  107. public static function getMethods(Route $route): array
  108. {
  109. $methods = $route->methods();
  110. // Laravel adds an automatic "HEAD" endpoint for each GET request, so we'll strip that out,
  111. // but not if there's only one method (means it was intentional)
  112. if (count($methods) === 1) {
  113. return $methods;
  114. }
  115. return array_diff($methods, ['HEAD']);
  116. }
  117. public static function fromExtractedEndpointArray(array $endpoint): OutputEndpointData
  118. {
  119. return new self($endpoint);
  120. }
  121. public function endpointId(): string
  122. {
  123. return $this->methods[0].str_replace(['/', '?', '{', '}', ':'], '-', $this->uri);
  124. }
  125. public function hasResponses(): bool
  126. {
  127. return count($this->responses) > 0;
  128. }
  129. public function hasFiles(): bool
  130. {
  131. return count($this->fileParameters) > 0;
  132. }
  133. public function isGet(): bool
  134. {
  135. return in_array('GET', $this->methods);
  136. }
  137. public function hasRequestOptions(): bool
  138. {
  139. return !empty($this->headers)
  140. || !empty($this->cleanQueryParameters)
  141. || !empty($this->cleanBodyParameters);
  142. }
  143. }