Repository: dedoc/scramble (php)

Issue:
Order of Validation Rules in Laravel Request Affects OpenAPI Documentation
Not sure it's actually a bug, but still: 
with these request rules
`[
            'items.*.name' => 'required|string',
            'items.*.email'=> 'email',
            'items' => ['array', 'min:1', 'max:10'],
            'items.*' => 'array',
        ];`
the last rule, with a trailing wildcard, seems to be overwriting every previous more specific rule (items.*.name and items.*.email). 
Output: `{
    "schema": {
        "type": "object",
        "properties": {
            "items": {
                "type": "array",
                "items": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "minItems": 1,
                "maxItems": 10
            }
        }
    }
}`
I didn't dig particularly deep into it, so I'm not sure where the problem stands (yet), although ksorting $rules in `RulesToParameters` constructor seems to fix it (but it is kinda a lazy solution, and not ideal).

Pull request:
Sort validation rules by nesting deepness before documenting them to make results consistent
fixes #245 

Patch:
diff --git a/src/Support/OperationExtensions/RulesExtractor/RulesToParameters.php b/src/Support/OperationExtensions/RulesExtractor/RulesToParameters.php
index a5d0b7e..0a6a7ef 100644
--- a/src/Support/OperationExtensions/RulesExtractor/RulesToParameters.php
+++ b/src/Support/OperationExtensions/RulesExtractor/RulesToParameters.php
@@ -48,7 +48,9 @@ class RulesToParameters
 
     private function handleNested(Collection $parameters)
     {
-        [$nested, $parameters] = $parameters->partition(fn ($_, $key) => Str::contains($key, '.'));
+        [$nested, $parameters] = $parameters
+            ->sortBy(fn ($_, $key) => count(explode('.', $key)))
+            ->partition(fn ($_, $key) => Str::contains($key, '.'));
 
         $nestedParentsKeys = $nested->keys()->map(fn ($key) => explode('.', $key)[0]);
 


Test patch:
diff --git a/tests/Generator/Request/ValidationRulesDocumentationTest.php b/tests/Generator/Request/ValidationRulesDocumentationTest.php
index 44239bb..5986b11 100644
--- a/tests/Generator/Request/ValidationRulesDocumentationTest.php
+++ b/tests/Generator/Request/ValidationRulesDocumentationTest.php
@@ -30,3 +30,42 @@ it('supports multiple confirmed rule', function () {
         ->and($params[3])
         ->toMatchArray(['name' => 'email_confirmation']);
 });
+
+it('works when last validation item is items array', function () {
+    $rules = [
+        'items.*.name' => 'required|string',
+        'items.*.email' => 'email',
+        'items.*' => 'array',
+        'items' => ['array', 'min:1', 'max:10'],
+    ];
+
+    $params = app()->make(RulesToParameters::class, ['rules' => $rules])->handle();
+
+    expect($params = collect($params)->map->toArray()->all())
+        ->toBe([
+            [
+                'name' => 'items',
+                'in' => 'query',
+                'schema' => [
+                    'type' => 'array',
+                    'items' => [
+                        'type' => 'object',
+                        'properties' => [
+                            'name' => [
+                                'type' => 'string',
+                            ],
+                            'email' => [
+                                'type' => 'string',
+                                'format' => 'email',
+                            ],
+                        ],
+                        'required' => [
+                            0 => 'name',
+                        ],
+                    ],
+                    'minItems' => 1.0,
+                    'maxItems' => 10.0,
+                ],
+            ],
+        ]);
+});
diff --git a/tests/__snapshots__/ValidationRulesDocumentingTest__it_extract_rules_from_object_like_rules_heavy_case__1.yml b/tests/__snapshots__/ValidationRulesDocumentingTest__it_extract_rules_from_object_like_rules_heavy_case__1.yml
index b1c7140..94845bf 100644
--- a/tests/__snapshots__/ValidationRulesDocumentingTest__it_extract_rules_from_object_like_rules_heavy_case__1.yml
+++ b/tests/__snapshots__/ValidationRulesDocumentingTest__it_extract_rules_from_object_like_rules_heavy_case__1.yml
@@ -6,4 +6,4 @@
 -
     name: channels
     in: query
-    schema: { type: object, properties: { publisher: { type: object, properties: { id: { type: [integer, 'null'] }, name: { type: [string, 'null'] } } }, channel_url: { type: string }, agency: { type: [object, 'null'], properties: { id: { type: [integer, 'null'] }, name: { type: [string, 'null'] } } } } }
+    schema: { type: object, properties: { channel_url: { type: string }, agency: { type: [object, 'null'], properties: { id: { type: [integer, 'null'] }, name: { type: [string, 'null'] } } }, publisher: { type: object, properties: { id: { type: [integer, 'null'] }, name: { type: [string, 'null'] } } } } }