knuckleswtf / knuckleswtf/scribe
Can't generate doc with file upload & sub object body params
- Dominant language
- PHP
- Stars
- 2.3k
- Forks
- 357
- PR merge metrics
- No merged PRs in 30d
Description
- [x] **I confirm that I have read and attempted the tips in the [Troubleshooting Guide](https://scribe.knuckles.wtf/laravel/troubleshooting).**
**What happened?**
1. I set my route configuration to.
```
* @bodyParam file file required File in mime audio/mpeg.
* Must not be greater than 66560 kilobytes. Example: storage/app/data/spot/dummy.mp3
* @bodyParam relations object
* @bodyParam relations.internal_tags integer[] Array of tags ids. Used for internal tags. Example: [1, 2]
*
* @bodyParam relations.spot_blocks object[] Create spot_blocks related on spot
* Example: [{"block": "10:00:00"}]
* @bodyParam relations.spot_blocks.block string required Must be a valid time. Example: 10:00:00
*
* @bodyParam relations.spot_states object[] Create spot_state related on spot
* Example: [{"state": true, "time": "10:00:00"}]
* @bodyParam relations.spot_states[].state boolean required Set state is active. Example: true
* @bodyParam relations.spot_states[].time integer required Must be a valid time. Example: 10:00:00
```
2. Then I ran `php artisan scribe:generate` and if `file` is required, file have been uploaded and after generating HTML get Object to string conversion error.
instead of...
**Screenshots and stack traces:**
```console
Illuminate\View\ViewException
Object of class stdClass could not be converted to string (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/partials/example-requests/javascript.md.blade.php) (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/themes/default/endpoint.blade.php) (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/themes/default/endpoint.blade.php) (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/themes/default/endpoint.blade.php)
at storage/framework/views/f8b71eaa04783499ae8bb8b4fb3cd824509e901b.php:31
27▕ hasFiles()): ?>
28▕ const body = new FormData();
29▕ cleanBodyParameters; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $parameter => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
30▕ addLoop($__currentLoopData); foreach($__currentLoopData as $key => $actualValue): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
➜ 31▕ body.append('', '');
32▕ popLoop(); $loop = $__env->getLastLoop(); ?>
33▕ popLoop(); $loop = $__env->getLastLoop(); ?>
34▕ fileParameters; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $parameter => $value): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
35▕ addLoop($__currentLoopData); foreach($__currentLoopData as $key => $file): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
+1 vendor frames
2 storage/framework/views/f8b71eaa04783499ae8bb8b4fb3cd824509e901b.php:31
Illuminate\View\ViewException::("Object of class stdClass could not be converted to string (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/partials/example-requests/javascript.md.blade.php) (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/themes/default/endpoint.blade.php) (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/themes/default/endpoint.blade.php)")
+1 vendor frames
4 storage/framework/views/f8b71eaa04783499ae8bb8b4fb3cd824509e901b.php:31
Illuminate\View\ViewException::("Object of class stdClass could not be converted to string (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/partials/example-requests/javascript.md.blade.php) (View: /var/www/html/vendor/knuckleswtf/scribe/resources/views/themes/default/endpoint.blade.php)")
```
**My environment:**
- PHP version (from `php -v`): PHP 8.0.21 (cli) (built: Jul 7 2022 13:02:07) ( NTS )
- Framework (Laravel/Lumen): 9
- Laravel/Lumen version (from `composer show laravel/framework` or `composer show laravel/lumen-framework`): 9.19
- Scribe version (from `composer show knuckleswtf/scribe`): 3.36.0
**My Scribe config (minus the comments):**
```php
'default',
'title' => null,
'description' => 'Complete API documentation for IS Media Radio API.',
'base_url' => null,
'routes' => [
[
'match' => [
'prefixes' => ['api/*'],
'domains' => ['*'],
'versions' => ['v1'],
],
'include' => [
// 'users.index', 'healthcheck*'
],
'exclude' => [
// '/health', 'admin.*'
],
'apply' => [
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'response_calls' => [
'methods' => ['GET', 'POST', 'PUT', 'DELETE'],
'config' => [
'app.env' => 'documentation',
// 'app.debug' => false,
],
'queryParams' => [
"skip" => 0,
"limit" => 10,
],
'bodyParams' => [
"name" => "Custom name",
"gong_url" => "https://example.com",
"twice_url" => "https://example.com",
"url" => "https://example.com",
"zip" => "7778-99999",
"company_id" => 1,
"interval" => 1,
// "start" => "2022-07-07 12:01:28"
"end" => null
// 'key' => 'value',
],
'fileParams' => [
// 'key' => 'storage/app/image.png',
],
'cookies' => [
// 'name' => 'value'
],
],
],
],
],
'type' => 'static',
'static' => [
'output_path' => 'public/docs',
],
'laravel' => [
'add_routes' => true,
'docs_url' => '/docs',
'assets_directory' => null,
'middleware' => [],
],
'try_it_out' => [
'enabled' => true,
'base_url' => null,
'use_csrf' => false,
'csrf_url' => '/sanctum/csrf-cookie',
],
'auth' => [
'enabled' => true,
'default' => true,
'in' => 'bearer',
'name' => 'key',
'use_value' => env('SCRIBE_AUTH_KEY'),
'placeholder' => '{YOUR_AUTH_KEY}',
'extra_info' => 'You can retrieve your token by visiting
your dashboard and clicking Generate API token.',
],
'intro_text' => <<As you scroll, you'll see code examples for working with the API in different programming
languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the
top left on mobile).
INTRO
,
'example_languages' => [
'javascript',
'php',
'bash'
],
'postman' => [
'enabled' => true,
'overrides' => [
// 'info.version' => '2.0.0',
],
],
'openapi' => [
'enabled' => true,
'overrides' => [
// 'info.version' => '2.0.0',
],
],
'default_group' => 'Endpoints',
'logo' => '../images/logo-horizontal.png',
'faker_seed' => null,
'strategies' => [
'metadata' => [
Strategies\Metadata\GetFromDocBlocks::class,
],
'urlParameters' => [
Strategies\UrlParameters\GetFromLaravelAPI::class,
Strategies\UrlParameters\GetFromLumenAPI::class,
Strategies\UrlParameters\GetFromUrlParamTag::class,
],
'queryParameters' => [
Strategies\QueryParameters\GetFromFormRequest::class,
Strategies\QueryParameters\GetFromInlineValidator::class,
Strategies\QueryParameters\GetFromQueryParamTag::class,
],
'headers' => [
Strategies\Headers\GetFromRouteRules::class,
Strategies\Headers\GetFromHeaderTag::class,
],
'bodyParameters' => [
Strategies\BodyParameters\GetFromFormRequest::class,
Strategies\BodyParameters\GetFromInlineValidator::class,
Strategies\BodyParameters\GetFromBodyParamTag::class,
],
'responses' => [
Strategies\Responses\UseTransformerTags::class,
Strategies\Responses\UseApiResourceTags::class,
Strategies\Responses\UseResponseTag::class,
Strategies\Responses\UseResponseFileTag::class,
Strategies\Responses\ResponseCalls::class,
],
'responseFields' => [
Strategies\ResponseFields\GetFromResponseFieldTag::class,
],
],
'fractal' => [
'serializer' => null,
],
'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class,
'database_connections_to_transact' => [config('database.default')]
];
```
**Additional info:**
I have found bug in every file in `vendor/knuckleswtf/scribe/resources/views/partials/example-requests`. Example of bug: https://github.com/knuckleswtf/scribe/blob/a739d2441dd60e97398d2dfee5373ecc09074ef3/resources/views/partials/example-requests/javascript.md.blade.php#L31
Hotfix solution, but not work for automatic HTTP response. Create custom language output or change in vendor, then update line with `body.append('{!! $key !!}', '{!! $actualValue !!}')` (`~L31`) and change it for object value. _This solutions only show good view in documentation. **Does not fix any response output & fetch request in automatic response.**_
```blade
@if(is_object($actualValue))
{{-- @foreach(u::getParameterNamesAndValuesForFormData($parameter, (array) $actualValue) as $keyObj => $valueObj)
Better way, but does not create perfect array syntax
--}}
@foreach(u::getParameterNamesAndValuesForFormData($parameter, $actualValue) as $keyObj => $valueObj)
body.append('{!! $key !!}', '{!! json_encode($valueObj) !!}');
@endforeach
@else
body.append('{!! $key !!}', '{!! $actualValue !!}')
@endif
```
Contributor guide
Research direction
Reproduce the failure with `php artisan scribe:generate`, then inspect `resources/views/partials/example-requests/javascript.md.blade.php` and the other example-request templates around `u::getParameterNamesAndValuesForFormData`. Verify the generated documentation and automatic request output handle file uploads together with nested object and array body parameters without an object-to-string error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, laravel, php
- Domain
- documentation, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100