Prechádzať zdrojové kódy

Improve OAS generation for array bod and files

shalvah 3 rokov pred
rodič
commit
8b51d839d2

+ 1 - 1
src/Commands/GenerateDocumentation.php

@@ -268,7 +268,7 @@ class GenerateDocumentation extends Command
         $fileNameIndex = 0;
         foreach ($grouped as $group) {
             $yaml = Yaml::dump(
-                $group, 10, 2,
+                $group, 20, 2,
                 Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP | Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK
             );
             if (count(Camel::$groupFileNames) == count($grouped)

+ 10 - 5
src/Extracting/Extractor.php

@@ -313,7 +313,8 @@ class Extractor
         while (Str::endsWith($baseNameInOriginalParams, '[]')) {
             $baseNameInOriginalParams = substr($baseNameInOriginalParams, 0, -2);
         }
-        // When the body is an array, param names will be  "[].paramname", so $baseNameInOriginalParams here will be empty
+        // When the body is an array, param names will be  "[].paramname",
+        // so $baseNameInOriginalParams here will be empty
         if (Str::startsWith($path, '[].')) {
             $baseNameInOriginalParams = '[]';
         }
@@ -440,16 +441,19 @@ class Extractor
 
                 // If the user didn't add a parent field, we'll helpfully add it for them
                 $parentName = rtrim(join('.', $parts), '[]');
-                // When the body is an array, param names will be  "[].paramname", so $parentName is empty
+
+                // When the body is an array, param names will be "[].paramname",
+                // so $parentName is empty. Let's fix that.
                 if (empty($parentName)) {
                     $parentName = '[]';
                 }
-                if (empty($parameters[$parentName])) {
+
+                if (empty($normalisedParameters[$parentName])) {
                     $normalisedParameters[$parentName] = new Parameter([
                         "name" => $parentName,
                         "type" => $parentName === '[]' ? "object[]" : "object",
                         "description" => "",
-                        "required" => $parentName === '[]' ? true : false,
+                        "required" => true,
                         "example" => [$fieldName => $parameter->example],
                     ]);
                 }
@@ -471,7 +475,8 @@ class Extractor
                 // The difference would be in the parent field's `type` property (object[] vs object)
                 // So we can get rid of all [] to get the parent name
                 $dotPathToParent = str_replace('[]', '', $baseName);
-                // When the body is an array, param names will be  "[].paramname", so $parts is ['[]']
+                // When the body is an array, param names will be  "[].paramname",
+                // so $parts is ['[]']
                 if ($parts[0] == '[]') {
                     $dotPathToParent = '[]'.$dotPathToParent;
                 }

+ 14 - 3
src/Writing/OpenAPISpecWriter.php

@@ -220,7 +220,6 @@ class OpenAPISpecWriter
                     $schema['required'][] = $name;
                 }
 
-
                 if ($details['type'] === 'file') {
                     $hasFileParameter = true;
                 }
@@ -399,7 +398,7 @@ class OpenAPISpecWriter
         }
     }
 
-    protected function generateSecurityPartialSpec()
+    protected function generateSecurityPartialSpec(): array
     {
         $isApiAuthed = $this->config->get('auth.enabled', false);
         if (!$isApiAuthed) {
@@ -483,6 +482,11 @@ class OpenAPISpecWriter
             ];
         } else if (Utils::isArrayType($field->type)) {
             $baseType = Utils::getBaseTypeFromArrayType($field->type);
+            $baseItem = ($baseType === 'file') ? [
+                'type' => 'string',
+                'format' => 'binary',
+            ] : ['type' => $baseType];
+
             $fieldData = [
                 'type' => 'array',
                 'description' => $field->description ?: '',
@@ -493,10 +497,17 @@ class OpenAPISpecWriter
                         'type' => $baseType,
                         'example' => ($field->example ?: [null])[0],
                     ])
-                    : ['type' => $baseType],
+                    : $baseItem,
             ];
+            if (str_replace('[]', "", $field->type) === 'file') {
+                // Don't include example for file params in OAS; it's hard to translate it correctly
+                unset($fieldData['example']);
+            }
 
             if ($baseType === 'object' && !empty($field->__fields)) {
+                if ($fieldData['items']['type'] === 'object') {
+                    $fieldData['items']['properties'] = [];
+                }
                 foreach ($field->__fields as $fieldSimpleName => $subfield) {
                     $fieldData['items']['properties'][$fieldSimpleName] = $this->generateFieldData($subfield);
                     if ($subfield['required']) {

+ 1 - 0
src/Writing/PostmanCollectionWriter.php

@@ -306,6 +306,7 @@ class PostmanCollectionWriter
             foreach ($response->headers as $header => $value) {
                 $headers[] = [
                     'key' => $header,
+                    // Todo remove array support in future
                     'value' => is_array($value) ? implode('; ', $value) : $value
                 ];
             }

+ 1 - 1
src/Writing/Writer.php

@@ -121,7 +121,7 @@ class Writer
                 data_set($spec, $key, $value);
             }
         }
-        return Yaml::dump($spec, 10, 2, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP);
+        return Yaml::dump($spec, 20, 2, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP);
     }
 
     protected function performFinalTasksForLaravelType(): void

+ 1 - 1
tests/GenerateDocumentationTest.php

@@ -353,7 +353,7 @@ class GenerateDocumentationTest extends BaseLaravelTest
         ];
         $group['endpoints'][0]['urlParameters']['a_param'] = $extraParam;
         file_put_contents($group1FilePath, Yaml::dump(
-            $group, 10, 2,
+            $group, 20, 2,
             Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP
         ));
         file_put_contents($authFilePath, 'Some other useful stuff.', FILE_APPEND);