Cleanup plugin API

This commit is contained in:
shalvah
2021-05-28 13:21:14 +01:00
parent 2f27600d22
commit e7a0e2e161
23 changed files with 80 additions and 479 deletions

View File

@@ -1,85 +0,0 @@
/* Base16 Atelier Cave Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Cave Comment */
.hljs-comment,
.hljs-quote {
color: #655f6d;
}
/* Atelier-Cave Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #be4678;
}
/* Atelier-Cave Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #aa573c;
}
/* Atelier-Cave Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #2a9292;
}
/* Atelier-Cave Blue */
.hljs-title,
.hljs-section {
color: #576ddb;
}
/* Atelier-Cave Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #955ae7;
}
.hljs-deletion,
.hljs-addition {
color: #19171c;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #be4678;
}
.hljs-addition {
background-color: #2a9292;
}
.hljs {
display: block;
overflow-x: auto;
background: #efecf4;
color: #585260;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View File

@@ -1,74 +0,0 @@
/*
Darcula color scheme from the JetBrains family of IDEs
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #2b2b2b;
color: #bababa;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-link,
.hljs-number,
.hljs-regexp,
.hljs-literal {
color: #6896ba;
}
.hljs-code,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-attribute,
.hljs-name,
.hljs-variable {
color: #cb7832;
}
.hljs-params {
color: #b9b9b9;
}
.hljs-string {
color: #6a8759;
}
.hljs-subst,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-symbol,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-template-tag,
.hljs-template-variable,
.hljs-addition {
color: #e0c46c;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #7f7f7f;
}

View File

@@ -1,83 +0,0 @@
/*
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #23241f;
}
.hljs,
.hljs-tag,
.hljs-subst {
color: #f8f8f2;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #ae81ff;
}
.hljs-code,
.hljs-title,
.hljs-section,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-attr {
color: #f92672;
}
.hljs-symbol,
.hljs-attribute {
color: #66d9ef;
}
.hljs-params,
.hljs-class .hljs-title {
color: #f8f8f2;
}
.hljs-string,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-variable {
color: #e6db74;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}

View File

@@ -1,71 +0,0 @@
/*
Monokai style - ported by Luigi Maselli - http://grigio.org
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #272822;
color: #ddd;
}
.hljs-tag,
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-strong,
.hljs-name {
color: #f92672;
}
.hljs-code {
color: #66d9ef;
}
.hljs-class .hljs-title {
color: white;
}
.hljs-attribute,
.hljs-symbol,
.hljs-regexp,
.hljs-link {
color: #bf79db;
}
.hljs-string,
.hljs-bullet,
.hljs-subst,
.hljs-title,
.hljs-section,
.hljs-emphasis,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #a6e22e;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-selector-id {
font-weight: bold;
}

View File

@@ -1,115 +0,0 @@
/*
* Visual Studio 2015 dark style
* Author: Nicolas LLOBERA <nllobera@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #1E1E1E;
color: #DCDCDC;
}
.hljs-keyword,
.hljs-literal,
.hljs-symbol,
.hljs-name {
color: #569CD6;
}
.hljs-link {
color: #569CD6;
text-decoration: underline;
}
.hljs-built_in,
.hljs-type {
color: #4EC9B0;
}
.hljs-number,
.hljs-class {
color: #B8D7A3;
}
.hljs-string,
.hljs-meta-string {
color: #D69D85;
}
.hljs-regexp,
.hljs-template-tag {
color: #9A5334;
}
.hljs-subst,
.hljs-function,
.hljs-title,
.hljs-params,
.hljs-formula {
color: #DCDCDC;
}
.hljs-comment,
.hljs-quote {
color: #57A64A;
font-style: italic;
}
.hljs-doctag {
color: #608B4E;
}
.hljs-meta,
.hljs-meta-keyword,
.hljs-tag {
color: #9B9B9B;
}
.hljs-variable,
.hljs-template-variable {
color: #BD63C5;
}
.hljs-attr,
.hljs-attribute,
.hljs-builtin-name {
color: #9CDCFE;
}
.hljs-section {
color: gold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
/*.hljs-code {
font-family:'Monospace';
}*/
.hljs-bullet,
.hljs-selector-tag,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #D7BA7D;
}
.hljs-addition {
background-color: #144212;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #600;
display: inline-block;
width: 100%;
}

View File

@@ -221,16 +221,19 @@ th {
padding: 0
}
body,
html {
font-family: 'PT Sans', Helvetica Neue, Helvetica, Arial, Microsoft Yahei, , STXihei, , sans-serif;
font-size: 16px;
}
.content h1,
.content h2,
.content h3,
.content h4,
.content h5,
.content h6,
body,
html {
.content h6 {
font-family: 'PT Sans', Helvetica Neue, Helvetica, Arial, Microsoft Yahei, , STXihei, , sans-serif;
font-size: 15px;
}
.content h1,
@@ -807,7 +810,6 @@ html {
}
.content code {
background-color: rgba(0, 0, 0, .05);
padding: 3px;
border-radius: 3px
}

View File

@@ -15,9 +15,10 @@
<link rel="stylesheet" href="css/theme-default.print.css" media="print">
<script src="{{ u::getVersionedAsset('js/theme-default.js') }}"></script>
<link href="https://unpkg.com/prismjs@v1.x/themes/prism-twilight.css" rel="stylesheet" />
<script src="https://unpkg.com/prismjs@v1.x/components/prism-core.min.js"></script>
<script src="https://unpkg.com/prismjs@v1.x/plugins/autoloader/prism-autoloader.min.js"></script>
<link rel="stylesheet"
href="//unpkg.com/@highlightjs/cdn-assets@10.7.2/styles/obsidian.min.css">
<script src="//unpkg.com/@highlightjs/cdn-assets@10.7.2/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
@if($tryItOut['enabled'] ?? false)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>

View File

@@ -8,7 +8,6 @@ class MakeStrategy extends GeneratorCommand
{
protected $signature = 'scribe:strategy
{name : Name of the class.}
{stage : The stage the strategy belongs to. One of "metadata", "urlParameters", "queryParameters", "bodyParameters", "headers", "responses", "responseFields".}
{--force : Overwrite file if it exists}
';

View File

@@ -9,22 +9,23 @@ use Knuckles\Camel\Extraction\ExtractedEndpointData;
class DummyClass extends Strategy
{
/**
* Trait containing some helper methods for dealing with "parameters".
* Trait containing some helper methods for dealing with "parameters",
* such as generating examples and casting values to types.
* Useful if your strategy extracts information about parameters or generates examples.
*/
use ParamHelpers;
/**
* @link https://scribe.readthedocs.io/en/latest/plugins.html
* @link https://scribe.knuckles.wtf/laravel/advanced/plugins
* @param ExtractedEndpointData $endpointData The endpoint we are currently processing.
* Contains details about controller, method, route, url, etc, as well as already extracted data.
* Contains details about httpMethods, controller, method, route, url, etc, as well as already extracted data.
* @param array $routeRules Array of rules for the ruleset which this route belongs to.
*
* See the documentation linked above for more details about writing custom strategies.
*
* @return array|null
*/
public function __invoke(ExtractedEndpointData $endpointData, array $routeRules)
public function __invoke(ExtractedEndpointData $endpointData, array $routeRules): ?array
{
return [];
}

View File

@@ -142,6 +142,9 @@ class Extractor
{
$this->iterateThroughStrategies('urlParameters', $endpointData, $rulesToApply, function ($results) use ($endpointData) {
foreach ($results as $key => $item) {
if (empty($item['name'])) {
$item['name'] = $key;
}
$endpointData->urlParameters[$key] = Parameter::create($item);
}
});
@@ -151,6 +154,9 @@ class Extractor
{
$this->iterateThroughStrategies('queryParameters', $endpointData, $rulesToApply, function ($results) use ($endpointData) {
foreach ($results as $key => $item) {
if (empty($item['name'])) {
$item['name'] = $key;
}
$endpointData->queryParameters[$key] = Parameter::create($item);
}
});
@@ -163,6 +169,9 @@ class Extractor
}
$this->iterateThroughStrategies('bodyParameters', $endpointData, $rulesToApply, function ($results) use ($endpointData) {
foreach ($results as $key => $item) {
if (empty($item['name'])) {
$item['name'] = $key;
}
$endpointData->bodyParameters[$key] = Parameter::create($item);
}
});

View File

@@ -15,7 +15,7 @@ use ReflectionClass;
*/
class RouteDocBlocker
{
protected static $docBlocks = [];
protected static array $docBlocks = [];
/**
* @param Route $route
@@ -23,7 +23,7 @@ class RouteDocBlocker
* @throws \ReflectionException
* @throws \Exception
*
* @return array<string, DocBlock> Method and class docblocks
* @return array<"method"|"class", DocBlock> Method and class docblocks
*/
public static function getDocBlocksFromRoute(Route $route): array
{

View File

@@ -10,6 +10,7 @@ use Knuckles\Scribe\Extracting\ParamHelpers;
use Knuckles\Scribe\Extracting\RouteDocBlocker;
use Knuckles\Scribe\Extracting\Strategies\Strategy;
use Mpociot\Reflection\DocBlock;
use Mpociot\Reflection\DocBlock\Tag;
use ReflectionClass;
use ReflectionException;
use ReflectionFunctionAbstract;
@@ -62,7 +63,12 @@ class GetFromBodyParamTag extends Strategy
return $this->getBodyParametersFromDocBlock($methodDocBlock->getTags());
}
public function getBodyParametersFromDocBlock($tags)
/**
* @param Tag[] $tags
*
* @return array
*/
public function getBodyParametersFromDocBlock(array $tags): array
{
$parameters = [];

View File

@@ -68,7 +68,7 @@ class GetFromQueryParamTag extends Strategy
*
* @return array[]
*/
public function getQueryParametersFromDocBlock(array $tags)
public function getQueryParametersFromDocBlock(array $tags): array
{
$parameters = [];
@@ -85,7 +85,7 @@ class GetFromQueryParamTag extends Strategy
preg_match('/(.+?)\s+([a-zA-Z\[\]]+\s+)?(required\s+)?([\s\S]*)/', $tagContent, $content);
if (empty($content)) {
// this means only name was supplied
// This means only name was supplied
$name = $tagContent;
$required = false;
$description = '';

View File

@@ -41,7 +41,7 @@ class GetFromResponseFieldTag extends Strategy
// @responseField user_id integer The ID of the user.
preg_match('/(.+?)\s+(.+?)\s+([\s\S]*)/', $tag->getContent(), $content);
if (empty($content)) {
// this means only name and type were supplied
// This means only name and type were supplied
[$name, $type] = preg_split('/\s+/', $tag->getContent());
$description = '';
} else {

View File

@@ -34,10 +34,15 @@ class UseApiResourceTags extends Strategy
$docBlocks = RouteDocBlocker::getDocBlocksFromRoute($endpointData->route);
$methodDocBlock = $docBlocks['method'];
$tags = $methodDocBlock->getTags();
if (empty($apiResourceTag = $this->getApiResourceTag($tags))) {
return null;
}
$this->startDbTransaction();
try {
return $this->getApiResourceResponse($methodDocBlock->getTags(), $endpointData);
return $this->getApiResourceResponse($apiResourceTag, $tags, $endpointData);
} catch (Exception $e) {
c::warn('Exception thrown when fetching Eloquent API resource response for ' . $endpointData->name());
e::dumpExceptionIfVerbose($e);
@@ -51,20 +56,17 @@ class UseApiResourceTags extends Strategy
/**
* Get a response from the @apiResource/@apiResourceCollection and @apiResourceModel tags.
*
* @param array $tags
* @param Tag $apiResourceTag
* @param Tag[] $allTags
* @param ExtractedEndpointData $endpointData
*
* @return array[]|null
* @throws Exception
*/
public function getApiResourceResponse(array $tags, ExtractedEndpointData $endpointData)
public function getApiResourceResponse(Tag $apiResourceTag, array $allTags, ExtractedEndpointData $endpointData): ?array
{
if (empty($apiResourceTag = $this->getApiResourceTag($tags))) {
return null;
}
[$statusCode, $apiResourceClass] = $this->getStatusCodeAndApiResourceClass($apiResourceTag);
[$model, $factoryStates, $relations, $pagination] = $this->getClassToBeTransformedAndAttributes($tags);
[$model, $factoryStates, $relations, $pagination] = $this->getClassToBeTransformedAndAttributes($allTags);
$modelInstance = $this->instantiateApiResourceModel($model, $factoryStates, $relations);
try {
@@ -219,11 +221,11 @@ class UseApiResourceTags extends Strategy
}
/**
* @param array $tags
* @param Tag[] $tags
*
* @return Tag|null
*/
private function getApiResourceTag(array $tags)
public function getApiResourceTag(array $tags): ?Tag
{
$apiResourceTags = array_values(
array_filter($tags, function ($tag) {

View File

@@ -25,11 +25,11 @@ class UseResponseFileTag extends Strategy
/**
* Get the response from the file if available.
*
* @param array $tags
* @param Tag[] $tags
*
* @return array|null
*/
public function getFileResponses(array $tags)
public function getFileResponses(array $tags): ?array
{
// Avoid "holes" in the keys of the filtered array, by using array_values on the filtered array
$responseFileTags = array_values(

View File

@@ -24,11 +24,11 @@ class UseResponseTag extends Strategy
/**
* Get the response from the docblock if available.
*
* @param array $tags
* @param Tag[] $tags
*
* @return array|null
*/
public function getDocBlockResponses(array $tags)
public function getDocBlockResponses(array $tags): ?array
{
$responseTags = array_values(
array_filter($tags, function ($tag) {

View File

@@ -54,7 +54,7 @@ class UseTransformerTags extends Strategy
*
* @return array|null
*/
public function getTransformerResponse(array $tags)
public function getTransformerResponse(array $tags): ?array
{
if (empty($transformerTag = $this->getTransformerTag($tags))) {
return null;
@@ -189,11 +189,11 @@ class UseTransformerTags extends Strategy
}
/**
* @param array $tags
* @param Tag[] $tags
*
* @return Tag|null
*/
private function getTransformerTag(array $tags)
private function getTransformerTag(array $tags): ?Tag
{
$transformerTags = array_values(
array_filter($tags, function ($tag) {
@@ -208,11 +208,11 @@ class UseTransformerTags extends Strategy
* Gets pagination data from the `@transformerPaginator` tag, like this:
* `@transformerPaginator League\Fractal\Pagination\IlluminatePaginatorAdapter 15`
*
* @param array $tags
* @param Tag[] $tags
*
* @return array
*/
private function getTransformerPaginatorData(array $tags)
private function getTransformerPaginatorData(array $tags): array
{
$transformerTags = array_values(
array_filter($tags, function ($tag) {

View File

@@ -62,7 +62,7 @@ class GetFromUrlParamTag extends Strategy
*
* @return array[]
*/
public function getUrlParametersFromDocBlock($tags)
public function getUrlParametersFromDocBlock(array $tags): array
{
$parameters = [];

View File

@@ -14,7 +14,16 @@ class DocumentationConfig
$this->data = $config;
}
public function get($key, $default = null)
/**
* Get a config item with dot notation.
* If the key does not exist, $default (or null) will be returned.
*
* @param string $key
* @param mixed $default
*
* @return array|mixed
*/
public function get(string $key, $default = null)
{
return data_get($this->data, $key, $default);
}

View File

@@ -98,8 +98,7 @@ class Utils
{
$adapter = new Local($workingDir ?: getcwd());
$fs = new Filesystem($adapter);
$dir = ltrim($dir, '/');
$dir = ltrim($dir, $adapter->getPathPrefix());
$dir = str_replace($adapter->getPathPrefix(), '', $dir);
$fs->deleteDir($dir);
}

View File

@@ -325,7 +325,8 @@ class GenerateDocumentationTest extends BaseLaravelTest
$this->artisan('scribe:generate');
$this->assertFileExists('static/docs/index.html');
Utils::deleteDirectoryAndContents('static/docs');
Utils::deleteDirectoryAndContents('static/');
}
/** @test */

View File

@@ -63,7 +63,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -92,7 +92,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -118,7 +118,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser states=state1,random-state'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -156,7 +156,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -198,7 +198,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser with=children'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -233,7 +233,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResourceCollection', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -268,7 +268,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResourceCollection', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResourceCollection'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[
@@ -306,7 +306,7 @@ class UseApiResourceTagsTest extends BaseLaravelTest
new Tag('apiResourceCollection', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResourceCollection'),
new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser paginate=1,simple'),
];
$results = $strategy->getApiResourceResponse($tags, ExtractedEndpointData::fromRoute($route));
$results = $strategy->getApiResourceResponse($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
$this->assertArraySubset([
[