mirror of
https://github.com/ambieco/scribe.git
synced 2026-03-27 22:45:58 +08:00
Merge branch 'master' into small-refactor-route-docblocker
This commit is contained in:
@@ -10,12 +10,12 @@ env:
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- php: 7.4
|
||||
env: COMPOSER=composer.dingo.json
|
||||
name: "With Dingo router"
|
||||
- php: 7.4
|
||||
env: SETUP=lint
|
||||
name: "Lint code"
|
||||
- php: 7.4
|
||||
env: COMPOSER=composer.dingo.json
|
||||
name: "With Dingo router"
|
||||
- php: 7.4.7
|
||||
- php: 7.4
|
||||
env: SETUP=lowest
|
||||
@@ -31,7 +31,6 @@ before_install:
|
||||
install:
|
||||
- if [[ $SETUP = 'stable' ]]; then travis_retry composer update --prefer-dist --prefer-stable; fi
|
||||
- if [[ $SETUP = 'lowest' ]]; then travis_retry composer require laravel/framework:^$LOWEST; composer require laravel/lumen-framework:^$LOWEST; fi
|
||||
- if [[ $SETUP = 'lint' ]]; then travis_retry composer update --prefer-dist --prefer-stable; composer lint; fi
|
||||
|
||||
script:
|
||||
- if [[ $SETUP = 'lint' ]]; then exit 0; fi; composer test-parallel-ci;
|
||||
|
||||
@@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
|
||||
### Removals
|
||||
|
||||
## 3.5.1 (Tuesday, 6 July 2021)
|
||||
### Fixed
|
||||
- Try It Out: Turn off autocomplete; make sure it works for array body; improve UI spacing ([579f672b57ad0417a5563aee1621b84c3b4ff1f2](https://github.com/knuckleswtf/scribe/commit/579f672b57ad0417a5563aee1621b84c3b4ff1f2), [2af8d8eacd661e0601b2d6f4dbc1766bf75e702a](https://github.com/knuckleswtf/scribe/commit/2af8d8eacd661e0601b2d6f4dbc1766bf75e702a))
|
||||
|
||||
## 3.5.0 (Monday, 5 July 2021)
|
||||
### Modified
|
||||
- Get URL parameter name from field bindings (https://github.com/knuckleswtf/scribe/commit/ce6be7ca68ed0e682258eca5bbeb2f7d84774714)
|
||||
|
||||
@@ -150,6 +150,12 @@ class OutputEndpointData extends BaseDTO
|
||||
return count($this->fileParameters) > 0;
|
||||
}
|
||||
|
||||
public function isArrayBody(): bool
|
||||
{
|
||||
return count($this->nestedBodyParameters) === 1
|
||||
&& array_keys($this->nestedBodyParameters)[0] === "[]";
|
||||
}
|
||||
|
||||
public function isGet(): bool
|
||||
{
|
||||
return in_array('GET', $this->httpMethods);
|
||||
|
||||
@@ -858,7 +858,7 @@ html {
|
||||
.content pre {
|
||||
background-color: #292929;
|
||||
color: #fff;
|
||||
padding: 2em 28px;
|
||||
padding: 1.5em 28px;
|
||||
margin: 0;
|
||||
width: 50%;
|
||||
float: right;
|
||||
|
||||
@@ -142,12 +142,15 @@ async function executeTryOut(endpointId, form) {
|
||||
|
||||
let body;
|
||||
let setter;
|
||||
if (form.dataset.hasfiles === "0") {
|
||||
body = {};
|
||||
setter = (name, value) => _.set(body, name, value);
|
||||
} else {
|
||||
if (form.dataset.hasfiles === "1") {
|
||||
body = new FormData();
|
||||
setter = (name, value) => body.append(name, value);
|
||||
} else if (form.dataset.isarraybody === "1") {
|
||||
body = [];
|
||||
setter = (name, value) => _.set(body, name, value);
|
||||
} else {
|
||||
body = {};
|
||||
setter = (name, value) => _.set(body, name, value);
|
||||
}
|
||||
const bodyParameters = form.querySelectorAll('input[data-component=body]');
|
||||
bodyParameters.forEach(el => {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
$fullName .= '.0';
|
||||
$baseType = substr($baseType, 0, -2);
|
||||
}
|
||||
// When the body is an array, the item names will be ".0.thing"
|
||||
$fullName = ltrim($fullName, '.');
|
||||
switch($baseType) {
|
||||
case 'number':
|
||||
case 'integer':
|
||||
|
||||
@@ -32,24 +32,20 @@
|
||||
<summary>
|
||||
<small onclick="textContent = parentElement.parentElement.open ? 'Show headers' : 'Hide headers'">Show headers</small>
|
||||
</summary>
|
||||
<pre>
|
||||
<code class="language-http">@foreach($response->headers as $header => $value)
|
||||
<pre><code class="language-http">@foreach($response->headers as $header => $value)
|
||||
{{ $header }}: {{ is_array($value) ? implode('; ', $value) : $value }}
|
||||
@endforeach </code>
|
||||
</pre>
|
||||
@endforeach </code></pre>
|
||||
</details> @endif
|
||||
<pre>
|
||||
<code class="language-json">
|
||||
@if(is_string($response->content) && Str::startsWith($response->content, "<<binary>>"))
|
||||
[Binary data] - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}
|
||||
<code>[Binary data] - {{ htmlentities(str_replace("<<binary>>", "", $response->content)) }}</code>
|
||||
@elseif($response->status == 204)
|
||||
[Empty response]
|
||||
<code>[Empty response]</code>
|
||||
@else
|
||||
@php($parsed = json_decode($response->content))
|
||||
{{-- If response is a JSON string, prettify it. Otherwise, just print it --}}
|
||||
{!! htmlentities($parsed != null ? json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) : $response->content) !!}
|
||||
@endif </code>
|
||||
</pre>
|
||||
<code class="language-json">{!! htmlentities($parsed != null ? json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) : $response->content) !!}</code>
|
||||
@endif </pre>
|
||||
@endforeach
|
||||
@endif
|
||||
</span>
|
||||
@@ -67,7 +63,9 @@
|
||||
data-path="{{ $endpoint->uri }}"
|
||||
data-authed="{{ $endpoint->metadata->authenticated ? 1 : 0 }}"
|
||||
data-hasfiles="{{ $endpoint->hasFiles() ? 1 : 0 }}"
|
||||
data-isarraybody="{{ $endpoint->isArrayBody() ? 1 : 0 }}"
|
||||
data-headers='@json($endpoint->headers)'
|
||||
autocomplete="off"
|
||||
onsubmit="event.preventDefault(); executeTryOut('{{ $endpoint->endpointId() }}', this);">
|
||||
<h3>
|
||||
Request
|
||||
|
||||
@@ -84,7 +84,7 @@ class GenerateDocumentation extends Command
|
||||
throw new \Exception("Can't use --force and --no-extraction together.");
|
||||
}
|
||||
|
||||
// Reset this map useful for tests)
|
||||
// Reset this map (useful for tests)
|
||||
Camel::$groupFileNames = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class GetFromHeaderTag extends Strategy
|
||||
return $this->getHeadersFromDocBlock($methodDocBlock->getTags());
|
||||
}
|
||||
|
||||
public function getHeadersFromDocBlock($tags)
|
||||
public function getHeadersFromDocBlock($tags): array
|
||||
{
|
||||
$headers = collect($tags)
|
||||
->filter(function ($tag) {
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Knuckles\Scribe\Tools;
|
||||
|
||||
class Globals
|
||||
{
|
||||
public const SCRIBE_VERSION = '3.5.0';
|
||||
public const SCRIBE_VERSION = '3.5.1';
|
||||
|
||||
public static bool $shouldBeVerbose = false;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
parent::setUp();
|
||||
|
||||
config(['scribe.database_connections_to_transact' => []]);
|
||||
// Skip these ones for faster tests
|
||||
config(['scribe.openapi.enabled' => false]);
|
||||
config(['scribe.postman.enabled' => false]);
|
||||
|
||||
$factory = app(\Illuminate\Database\Eloquent\Factory::class);
|
||||
$factory->define(TestUser::class, function () {
|
||||
@@ -206,7 +209,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
],
|
||||
]);
|
||||
config(['scribe.postman.enabled' => true]);
|
||||
config(['scribe.openapi.enabled' => false]);
|
||||
|
||||
$this->artisan('scribe:generate');
|
||||
|
||||
@@ -230,7 +232,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
|
||||
// We want to have the same values for params each time
|
||||
config(['scribe.faker_seed' => 1234]);
|
||||
config(['scribe.postman.enabled' => false]);
|
||||
config(['scribe.openapi.enabled' => true]);
|
||||
config(['scribe.openapi.overrides' => [
|
||||
'info.version' => '3.9.9',
|
||||
@@ -372,8 +373,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
]);
|
||||
});
|
||||
config(['scribe.routes.0.match.prefixes' => ['*']]);
|
||||
config(['scribe.openapi.enabled' => false]);
|
||||
config(['scribe.postman.enabled' => false]);
|
||||
|
||||
$this->artisan('scribe:generate');
|
||||
|
||||
@@ -387,8 +386,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
public function will_not_extract_if_noExtraction_flag_is_set()
|
||||
{
|
||||
config(['scribe.routes.0.exclude' => ['*']]);
|
||||
config(['scribe.openapi.enabled' => false]);
|
||||
config(['scribe.postman.enabled' => false]);
|
||||
Utils::copyDirectory(__DIR__.'/Fixtures/.scribe', '.scribe');
|
||||
|
||||
$output = $this->artisan('scribe:generate', ['--no-extraction' => true]);
|
||||
@@ -412,8 +409,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
RouteFacade::get('/api/action1', [TestGroupController::class, 'action1']);
|
||||
RouteFacade::get('/api/action2', [TestGroupController::class, 'action2']);
|
||||
config(['scribe.routes.0.match.prefixes' => ['api/*']]);
|
||||
config(['scribe.openapi.enabled' => false]);
|
||||
config(['scribe.postman.enabled' => false]);
|
||||
if (!is_dir('.scribe/endpoints'))
|
||||
mkdir('.scribe/endpoints', 0777, true);
|
||||
copy(__DIR__ . '/Fixtures/custom.0.yaml', '.scribe/endpoints/custom.0.yaml');
|
||||
@@ -443,8 +438,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
RouteFacade::get('/api/action1b', [TestGroupController::class, 'action1b']);
|
||||
RouteFacade::get('/api/action2', [TestGroupController::class, 'action2']);
|
||||
config(['scribe.routes.0.match.prefixes' => ['api/*']]);
|
||||
config(['scribe.openapi.enabled' => false]);
|
||||
config(['scribe.postman.enabled' => false]);
|
||||
|
||||
$this->artisan('scribe:generate');
|
||||
|
||||
@@ -485,4 +478,35 @@ class GenerateDocumentationTest extends BaseLaravelTest
|
||||
$this->assertEquals("Another endpoint.", $expectedEndpoints->getNode(1)->textContent);
|
||||
$this->assertEquals("Some endpoint.", $expectedEndpoints->getNode(2)->textContent);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function will_auto_set_content_type_to_multipart_if_file_params_are_present()
|
||||
{
|
||||
/**
|
||||
* @bodyParam param string required
|
||||
*/
|
||||
RouteFacade::post('no-file', fn() => null);
|
||||
/**
|
||||
* @bodyParam a_file file required
|
||||
*/
|
||||
RouteFacade::post('top-level-file', fn() => null);
|
||||
/**
|
||||
* @bodyParam data object
|
||||
* @bodyParam data.thing string
|
||||
* @bodyParam data.a_file file
|
||||
*/
|
||||
RouteFacade::post('nested-file', fn() => null);
|
||||
config(['scribe.routes.0.match.prefixes' => ['*']]);
|
||||
|
||||
$this->artisan('scribe:generate');
|
||||
|
||||
$group = Yaml::parseFile('.scribe/endpoints/0.yaml');
|
||||
$this->assertEquals('no-file', $group['endpoints'][0]['uri']);
|
||||
$this->assertEquals('application/json', $group['endpoints'][0]['headers']['Content-Type']);
|
||||
$this->assertEquals('top-level-file', $group['endpoints'][1]['uri']);
|
||||
$this->assertEquals('multipart/form-data', $group['endpoints'][1]['headers']['Content-Type']);
|
||||
$this->assertEquals('nested-file', $group['endpoints'][2]['uri']);
|
||||
$this->assertEquals('multipart/form-data', $group['endpoints'][2]['headers']['Content-Type']);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user