knuckleswtf / scribe

Generate API documentation for humans from your Laravel codebase.✍
https://scribe.knuckles.wtf/laravel/
MIT License
1.75k stars 314 forks source link

PostmanCollectionWriter json encodes "items" as Object instead of Array #278

Closed fadugyamfi closed 3 years ago

fadugyamfi commented 3 years ago

What happened?

  1. I set my configuration to the default configuration for scribe v3 with basic additions
  2. Then I ran php artisan scribe:generate to generate the docs and the postman collection. I then attempted to load the Postman Collection into the Postman application but the imported collection was empty.
  3. I checked the JSON for the created collection and I saw the items property was an object instead of an array.

Screenshots and stack traces:

Here is a screenshot of the items as an object in the JSON output

image

instead of...

image

My environment:

My Scribe config (minus the comments):

<?php

use Knuckles\Scribe\Extracting\Strategies;

return [

    'theme' => 'default',
    'title' => null,
    'description' => '',
    'base_url' => "https://api.mergdata.net",
    'routes' => [[
        'match' => [
            'domains' => [env('API_DOMAIN')],
            'prefixes' => ['*'],
            'versions' => ['v1'],
        ],
        'include' => [],
        'exclude' => [],
        'apply' => [
            'headers' => ['Content-Type' => 'application/json', 'Accept' => 'application/json', 'user-token' => '{{user-token}}', 'org-token' => '{{org-token}}'],
            'response_calls' => [
                'methods' => ['GET'],
                'config' => ['app.env' => 'documentation'],
                'queryParams' => [],
                'bodyParams' => [],
                'fileParams' => [],
                'cookies' => [],
            ],
        ],
    ]],

    'type' => 'static',

    'static' => [
        'output_path' => 'public/docs',
    ],

    'laravel' => [
        'add_routes' => true,
        'docs_url' => '/docs',
        'middleware' => [],
    ],

    'try_it_out' => [
        'enabled' => true,
        'base_url' => null,
    ],

    'auth' => [
        'enabled' => true,
        'default' => true,
        'in' => 'header',
        'name' => 'auth-token',
        'use_value' => env('SCRIBE_AUTH_KEY'),
        'placeholder' => '{{auth-token}}',
        'extra_info' => 'You can retrieve your token by visiting your dashboard and clicking <b>Generate API token</b>.',
    ],

    'intro_text' => <<<INTRO
This documentation aims to provide all the information you need to work with our API.

<aside>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).</aside>
INTRO

    ,

    'example_languages' => [
        'bash',
        'javascript',
        'php',
    ],

    'postman' => [
        'enabled' => true,

        'overrides' => [
            'variable' => [
                [
                    "id" => "baseUrl",
                    "key" => "baseUrl",
                    "type" => "string",
                    "name" => "string",
                    "value" => "api.mergdata.net"
                ],
                [
                    "id" => "user-token",
                    "key" => "user-token",
                    "type" => "string",
                    "name" => "string",
                    "value" => "b"
                ],
                [
                    "id" => "org-token",
                    "key" => "org-token",
                    "type" => "string",
                    "name" => "string",
                    "value" => "b"
                ],
                [
                    "id" => "auth-token",
                    "key" => "auth-token",
                    "type" => "string",
                    "name" => "string",
                    "value" => "c68db2f385cd10b5c8a08e7041055d93"
                ],
            ]
        ],
    ],

    'openapi' => [
        'enabled' => true,

        'overrides' => [
            // 'info.version' => '2.0.0',
        ],
    ],

    'default_group' => 'Endpoints',

    'logo' => false,

    '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\UseResponseTag::class,
            Strategies\Responses\UseResponseFileTag::class,
            Strategies\Responses\UseApiResourceTags::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:

to

            'item' => array_values(array_map(function (array $group) {
                return [
                    'name' => $group['name'],
                    'description' => $group['description'],
                    'item' => array_map(\Closure::fromCallable([$this, 'generateEndpointItem']), $group['endpoints']),
                ];
            }, $groupedEndpoints)),

somewhat fixes the issue for me. However, more investigation might required to resolve the issue permanently. The resulting items array from the fix above isn't ordered alphabetically as expected

shalvah commented 3 years ago

Thanks, fixed in 3.6.2