فهرست منبع

Set examples for nested file parameters properly

shalvah 3 سال پیش
والد
کامیت
6354b5592d

+ 26 - 11
camel/Output/OutputEndpointData.php

@@ -103,20 +103,13 @@ class OutputEndpointData extends BaseDTO
 
         $this->boundUri = u::getUrlWithBoundParameters($this->uri, $this->cleanUrlParameters);
 
-        [$files, $regularParameters] = collect($this->cleanBodyParameters)
-            ->partition(
-                function ($example) {
-                    // We'll only check two levels: a file, or an array of files
-                    return is_array($example) && isset($example[0])
-                        ? $example[0] instanceof UploadedFile
-                        : $example instanceof UploadedFile;
-                }
-            );
+        [$files, $regularParameters] = static::getFileParameters($this->cleanBodyParameters);
+
         if (count($files)) {
             $this->headers['Content-Type'] = 'multipart/form-data';
         }
-        $this->fileParameters = $files->toArray();
-        $this->cleanBodyParameters = $regularParameters->toArray();
+        $this->fileParameters = $files;
+        $this->cleanBodyParameters = $regularParameters;
     }
 
     /**
@@ -168,4 +161,26 @@ class OutputEndpointData extends BaseDTO
             || !empty($this->cleanQueryParameters)
             || !empty($this->cleanBodyParameters);
     }
+
+    public static function getFileParameters(array $parameters): array
+    {
+        $files = [];
+        $regularParameters = [];
+        foreach ($parameters as $name => $example) {
+            if ($example instanceof UploadedFile) {
+                $files[$name] = $example;
+            } else if (is_array($example)) {
+                [$subFiles, $subRegulars] = static::getFileParameters($example);
+                foreach ($subFiles as $subName => $subExample) {
+                    $files[$name][$subName] = $subExample;
+                }
+                foreach ($subRegulars as $subName => $subExample) {
+                    $regularParameters[$name][$subName] = $subExample;
+                }
+            } else {
+                $regularParameters[$name] = $example;
+            }
+        }
+        return [$files, $regularParameters];
+    }
 }

+ 53 - 30
resources/views/components/field-details.blade.php

@@ -1,36 +1,59 @@
 <b><code>{{ $name }}</code></b>&nbsp;&nbsp;@if($type)<small>{{ $type }}</small>@endif @if(!$required)
     <i>optional</i>@endif &nbsp;
 @if(($isInput ?? true) && empty($hasChildren))
-@php
-    $isList = Str::endsWith($type, '[]');
-    $fullName =str_replace('[]', '.0', $name);
-    $baseType = $isList ? substr($type, 0, -2) : $type;
-    // Ignore the first '[]': the frontend will take care of it
-    while (\Str::endsWith($baseType, '[]')) {
-        $fullName .= '.0';
-        $baseType = substr($baseType, 0, -2);
-    }
-    switch($baseType) {
-        case 'number':
-        case 'integer':
-            $inputType = 'number';
-            break;
-        case 'file':
-            $inputType = 'file';
-            break;
-        default:
-            $inputType = 'text';
-    }
-@endphp
-@if($type === 'boolean')
-<label data-endpoint="{{ $endpointId }}" hidden><input type="radio" name="{{ $fullName }}" value="{{$component === 'body' ? 'true' : 1}}" data-endpoint="{{ $endpointId }}" data-component="{{ $component }}" @if($required)required @endif><code>true</code></label>
-<label data-endpoint="{{ $endpointId }}" hidden><input type="radio" name="{{ $fullName }}" value="{{$component === 'body' ? 'false' : 0}}" data-endpoint="{{ $endpointId }}" data-component="{{ $component }}" @if($required)required @endif><code>false</code></label>
-@elseif($isList)
-<input type="{{ $inputType }}" name="{{ $fullName.".0" }}" data-endpoint="{{ $endpointId }}" data-component="{{ $component }}" @if($required)required @endif hidden>
-<input type="{{ $inputType }}" name="{{ $fullName.".1" }}" data-endpoint="{{ $endpointId }}" data-component="{{ $component }}" hidden>
-@else
-<input type="{{ $inputType }}" name="{{ $fullName }}" data-endpoint="{{ $endpointId }}" data-component="{{ $component }}" @if($required)required @endif hidden>
-@endif
+    @php
+        $isList = Str::endsWith($type, '[]');
+        $fullName =str_replace('[]', '.0', $name);
+        $baseType = $isList ? substr($type, 0, -2) : $type;
+        // Ignore the first '[]': the frontend will take care of it
+        while (\Str::endsWith($baseType, '[]')) {
+            $fullName .= '.0';
+            $baseType = substr($baseType, 0, -2);
+        }
+        switch($baseType) {
+            case 'number':
+            case 'integer':
+                $inputType = 'number';
+                break;
+            case 'file':
+                $inputType = 'file';
+                break;
+            default:
+                $inputType = 'text';
+        }
+    @endphp
+    @if($type === 'boolean')
+        <label data-endpoint="{{ $endpointId }}" hidden>
+            <input type="radio" name="{{ $fullName }}"
+                   value="{{$component === 'body' ? 'true' : 1}}"
+                   data-endpoint="{{ $endpointId }}"
+                   data-component="{{ $component }}" @if($required)required @endif
+            >
+            <code>true</code>
+        </label>
+        <label data-endpoint="{{ $endpointId }}" hidden>
+            <input type="radio" name="{{ $fullName }}"
+                   value="{{$component === 'body' ? 'false' : 0}}"
+                   data-endpoint="{{ $endpointId }}"
+                   data-component="{{ $component }}" @if($required)required @endif
+            >
+            <code>false</code>
+        </label>
+    @elseif($isList)
+        <input type="{{ $inputType }}"
+               name="{{ $fullName.".0" }}"
+               data-endpoint="{{ $endpointId }}"
+               data-component="{{ $component }}" @if($required)required @endif hidden>
+        <input type="{{ $inputType }}"
+               name="{{ $fullName.".1" }}"
+               data-endpoint="{{ $endpointId }}"
+               data-component="{{ $component }}" hidden>
+    @else
+        <input type="{{ $inputType }}"
+               name="{{ $fullName }}"
+               data-endpoint="{{ $endpointId }}"
+               data-component="{{ $component }}" @if($required)required @endif hidden>
+    @endif
 @endif
 <br>
 {!! Parsedown::instance()->text($description) !!}

+ 7 - 10
src/Extracting/Extractor.php

@@ -12,6 +12,7 @@ use Illuminate\Routing\Route;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Str;
 use Knuckles\Camel\Extraction\ResponseField;
+use Knuckles\Camel\Output\OutputEndpointData;
 use Knuckles\Scribe\Extracting\Strategies\Strategy;
 use Knuckles\Scribe\Tools\DocumentationConfig;
 
@@ -102,19 +103,15 @@ class Extractor
             // Set content type if the user forgot to set it
             $endpointData->headers['Content-Type'] = 'application/json';
         }
-        // We need to do all this so response calls can work correctly
-        [$files, $regularParameters] = collect($endpointData->cleanBodyParameters)
-            ->partition(
-                function ($example) {
-                    return $example instanceof UploadedFile
-                        || (is_array($example) && ($example[0] ?? null) instanceof UploadedFile);
-                }
-            );
+        // We need to do all this so response calls can work correctly,
+        // even though they're only needed for output
+        // Note that this
+        [$files, $regularParameters] = OutputEndpointData::getFileParameters($endpointData->cleanBodyParameters);
         if (count($files)) {
             $endpointData->headers['Content-Type'] = 'multipart/form-data';
         }
-        $endpointData->fileParameters = $files->toArray();
-        $endpointData->cleanBodyParameters = $regularParameters->toArray();
+        $endpointData->fileParameters = $files;
+        $endpointData->cleanBodyParameters = $regularParameters;
 
         $this->fetchResponses($endpointData, $routeRules);
 

+ 1 - 1
tests/Fixtures/collection.json

@@ -47,7 +47,7 @@
             ],
             "body": {
               "mode": "raw",
-              "raw": "[{\"first_name\":\"John\",\"last_name\":\"Doe\",\"contacts\":[{\"first_name\":\"Janelle\",\"last_name\":\"Monáe\"},[]],\"roles\":[\"Admin\"]},{\"first_name\":\"John\",\"last_name\":\"Doe\",\"contacts\":[{\"first_name\":\"Janelle\",\"last_name\":\"Monáe\"},[]],\"roles\":[\"Admin\"]}]"
+              "raw": "[{\"first_name\":\"John\",\"last_name\":\"Doe\",\"contacts\":[{\"first_name\":\"Janelle\",\"last_name\":\"Monáe\"}],\"roles\":[\"Admin\"]},{\"first_name\":\"John\",\"last_name\":\"Doe\",\"contacts\":[{\"first_name\":\"Janelle\",\"last_name\":\"Monáe\"}],\"roles\":[\"Admin\"]}]"
             },
             "description": "",
             "auth": {