@@ -378,7 +378,7 @@ protected function generateResponseContentSpec(?string $responseContent, OutputE
378
378
379
379
case 'object ' :
380
380
$ properties = collect ($ decoded )->mapWithKeys (function ($ value , $ key ) use ($ endpoint ) {
381
- return $ this ->generateObjectPropertiesResponseSpec ($ value , $ endpoint , $ key );
381
+ return [ $ key => $ this ->generateSchemaForValue ($ value , $ endpoint , $ key )] ;
382
382
})->toArray ();
383
383
384
384
if (!count ($ properties )) {
@@ -521,59 +521,58 @@ public function generateFieldData($field): array
521
521
}
522
522
}
523
523
524
- function operationId (OutputEndpointData $ endpoint ): string
524
+ protected function operationId (OutputEndpointData $ endpoint ): string
525
525
{
526
526
if ($ endpoint ->metadata ->title ) return preg_replace ('/[^\w+]/ ' , '' , Str::camel ($ endpoint ->metadata ->title ));
527
527
528
528
$ parts = preg_split ('/[^\w+]/ ' , $ endpoint ->uri , -1 , PREG_SPLIT_NO_EMPTY );
529
529
return Str::lower ($ endpoint ->httpMethods [0 ]) . join ('' , array_map (fn ($ part ) => ucfirst ($ part ), $ parts ));
530
530
}
531
531
532
-
533
- public function generateObjectPropertiesResponseSpec ($ value , OutputEndpointData $ endpoint , $ key ): array
532
+ /**
533
+ * Given a value, generate the schema for it. The schema consists of: {type:, example:, properties: (if value is an object)},
534
+ * and possibly a description for each property.
535
+ * The $endpoint and $path are used for looking up response field descriptions.
536
+ */
537
+ public function generateSchemaForValue (mixed $ value , OutputEndpointData $ endpoint , string $ path ): array
534
538
{
535
- //Field is object
536
539
if ($ value instanceof \stdClass) {
537
- $ value = (array )$ value ;
538
- $ fieldObjectSpec = [];
539
- $ fieldObjectSpec ['type ' ] = 'object ' ;
540
- $ fieldObjectSpec ['properties ' ]= [];
541
- foreach ($ value as $ subKey => $ subValue ){
542
- $ newKey = sprintf ('%s.%s ' , $ key , $ subKey );
543
- $ generateResponseContentFieldSpec = $ this ->generateObjectPropertiesResponseSpec (
544
- $ subValue ,
545
- $ endpoint ,
546
- $ newKey
547
- );
548
- $ fieldObjectSpec ['properties ' ][$ subKey ] = $ generateResponseContentFieldSpec [$ newKey ];
549
-
540
+ $ value = (array ) $ value ;
541
+ $ schema = [
542
+ 'type ' => 'object ' ,
543
+ 'properties ' => [],
544
+ ];
545
+ // Recurse into the object
546
+ foreach ($ value as $ subField => $ subValue ){
547
+ $ subFieldPath = sprintf ('%s.%s ' , $ path , $ subField );
548
+ $ schema ['properties ' ][$ subField ] = $ this ->generateSchemaForValue ($ subValue , $ endpoint , $ subFieldPath );
550
549
}
551
- return [$ key => $ fieldObjectSpec ];
550
+
551
+ return $ schema ;
552
552
}
553
553
554
- $ spec = [
554
+ $ schema = [
555
555
'type ' => $ this ->convertScribeOrPHPTypeToOpenAPIType (gettype ($ value )),
556
556
'example ' => $ value ,
557
-
558
557
];
559
- if (isset ($ endpoint ->responseFields [$ key ]->description )) {
560
- $ spec ['description ' ] = $ endpoint ->responseFields [$ key ]->description ;
558
+ if (isset ($ endpoint ->responseFields [$ path ]->description )) {
559
+ $ schema ['description ' ] = $ endpoint ->responseFields [$ path ]->description ;
561
560
}
562
- if ($ spec ['type ' ] === 'array ' && !empty ($ value )) {
563
- $ handle = $ value [0 ];
564
- $ type = $ this ->convertScribeOrPHPTypeToOpenAPIType (gettype ($ handle ));
565
- $ spec ['items ' ]['type ' ] = $ type ;
566
- $ spec ['example ' ] = json_decode (json_encode ($ spec ['example ' ]), true );//Convert stdClass to array
567
-
568
- if ($ type === 'object ' ) {
569
- $ spec ['items ' ]['properties ' ] = collect ($ handle )->mapWithKeys (function ($ v , $ k ) use ($ endpoint ) {
570
- return $ this ->generateObjectPropertiesResponseSpec ($ v , $ endpoint , $ k );
561
+
562
+ if ($ schema ['type ' ] === 'array ' && !empty ($ value )) {
563
+ $ schema ['example ' ] = json_decode (json_encode ($ schema ['example ' ]), true ); // Convert stdClass to array
564
+
565
+ $ sample = $ value [0 ];
566
+ $ typeOfEachItem = $ this ->convertScribeOrPHPTypeToOpenAPIType (gettype ($ sample ));
567
+ $ schema ['items ' ]['type ' ] = $ typeOfEachItem ;
568
+
569
+ if ($ typeOfEachItem === 'object ' ) {
570
+ $ schema ['items ' ]['properties ' ] = collect ($ sample )->mapWithKeys (function ($ v , $ k ) use ($ endpoint , $ path ) {
571
+ return [$ k => $ this ->generateSchemaForValue ($ v , $ endpoint , "$ path. $ k " )];
571
572
})->toArray ();
572
573
}
573
574
}
574
575
575
- return [
576
- $ key => $ spec ,
577
- ];
576
+ return $ schema ;
578
577
}
579
578
}
0 commit comments