Skip to content

Commit

Permalink
Merge pull request #355 from fernandopiovezan1/generate-example-with-…
Browse files Browse the repository at this point in the history
…factory

Generate example with factory
  • Loading branch information
kevincobain2000 authored May 21, 2024
2 parents dc00352 + 43554a0 commit d1b557d
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 7 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ Read more: https://medium.com/web-developer/laravel-automatically-generate-api-d

| Lang | Versions |
| :------ |:--------------------------|
| PHP | 7.4 or 8.0 or 8.1 or 8.2 |
| Laravel | 6.* or 8.* or 9.* or 10.* |
| PHP | 8.0 or 8.1 or 8.2 |
| Laravel | 8.* or 9.* or 10.* |

# Installation

Expand Down Expand Up @@ -188,6 +188,21 @@ you are able to explicitly define what status codes can be returned by the serve
# Configuration
Please view the `request-docs.php` config file to see how you can customise your experience.
# Use Factory to example
To generate an example based on the project's factories, the `use_factory` option must be enabled in the project file.
settings. This way, the examples will be generated based on the output of your model's factories.
# Remove factory fields in examples
To ensure that a field is not generated in the example, it can be inserted as a new value in the `exclude_fields`
configuration array, this way this field will be removed when the example is generated, ensuring correct display
```
'exclude_fields' => [
'password',
'remember_token',
],
```
# Testing
```bash
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}
],
"require": {
"php": "^7.4|^8.0|^8.1|^8.2|^8.3",
"php": "^8.0|^8.1|^8.2|^8.3",
"illuminate/contracts": "^8.37|^9.0|^10.0|^11.0",
"kitloong/laravel-app-logger": "^1.0",
"spatie/laravel-package-tools": "^1.4.3",
Expand Down
7 changes: 6 additions & 1 deletion config/request-docs.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,5 +175,10 @@

//export request docs as json file from terminal
//from project root directory
'export_path' => 'api.json'
'export_path' => 'api.json',

'exclude_fields' => [
],

'use_factory' => false,
];
1 change: 1 addition & 0 deletions resources/dist/_astro/App.CFz-tFSm.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion resources/dist/_astro/App.D5ip0zGO.js

This file was deleted.

40 changes: 39 additions & 1 deletion src/Doc.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ class Doc implements Arrayable
*/
private array $rules;

/**
* The parsed validation rules.
*
* @var array<string, string[]>
*/
private array $examples;

/**
* The additional description about this route.
*
Expand Down Expand Up @@ -115,6 +122,7 @@ class Doc implements Arrayable
* @param string $httpMethod
* @param array<string, string[]> $rules
* @param string $docBlock
* @param array<string, string[]> $examples
*/
public function __construct(
string $uri,
Expand All @@ -126,7 +134,8 @@ public function __construct(
string $httpMethod,
array $pathParameters,
array $rules,
string $docBlock
string $docBlock,
array $examples,
) {
$this->uri = $uri;
$this->methods = $methods;
Expand All @@ -139,6 +148,7 @@ public function __construct(
$this->rules = $rules;
$this->docBlock = $docBlock;
$this->responses = [];
$this->examples = $rules;
}

/**
Expand Down Expand Up @@ -274,6 +284,33 @@ public function setRules(array $rules): void
$this->rules = $rules;
}

/**
* @param array<string, string[]> $examples
*/
public function mergeExamples(array $examples): void
{
$this->examples = array_merge(
$this->examples,
$examples,
);
}

/**
* @return array<string, string[]>
*/
public function getExamples(): array
{
return $this->examples;
}

/**
* @param array<string, string[]> $rules
*/
public function setExamples(array $rules): void
{
$this->examples = $examples;
}

public function getDocBlock(): string
{
return $this->docBlock;
Expand Down Expand Up @@ -351,6 +388,7 @@ public function toArray(): array
'rules' => $this->rules,
'doc_block' => $this->docBlock,
'responses' => $this->responses,
'examples' => $this->examples,
];

if (isset($this->group)) {
Expand Down
34 changes: 34 additions & 0 deletions src/LaravelRequestDocs.php
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ public function getControllersInfo(array $onlyMethods): Collection
$pathParameters,
[],
'',
[],
);

$docs->push($doc);
Expand Down Expand Up @@ -250,6 +251,7 @@ public function appendRequestRules(Collection $docs): Collection

try {
$requestClassName = $namedType->getName();

$reflectionClass = new ReflectionClass($requestClassName);
try {
$requestObject = $reflectionClass->newInstance();
Expand Down Expand Up @@ -277,6 +279,9 @@ public function appendRequestRules(Collection $docs): Collection

$lrdDocComments[] = $requestMethodLrdComment;
$doc->mergeRules($requestMethodDocRules);
if (config('request-docs.use_factory')) {
$this->appendExample($doc);
}
}
} catch (Throwable $e) {
// Do nothing.
Expand Down Expand Up @@ -318,6 +323,35 @@ public function lrdDocComment(string $docComment): string
return $lrdComment;
}

public function appendExample(Doc $doc): void
{
try {
$controllerName = class_basename($doc->getController());
$modelName = Str::replace('APIController', '', $controllerName);
$fullModelName = "App\\Models\\" . $modelName;

if (!class_exists($fullModelName)) {
return;
}

/** @var \Illuminate\Database\Eloquent\Model $model */
$model = app($fullModelName);

if (!method_exists($model, 'factory')) {
return;
}

$excludeFields = config('request-docs.exclude_fields') ?? [];
$example = $model->factory()->make()->toArray();
$example = array_filter($example, fn($key) => !in_array($key, $excludeFields), ARRAY_FILTER_USE_KEY);
$doc->mergeExamples($example);

} catch (Throwable $e) {
// Do nothing.
}

}

/**
* Parse rules from the request.
*
Expand Down
3 changes: 2 additions & 1 deletion ui/src/components/ApiAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,9 @@ export default function ApiAction(props: Props) {
return acc;
}, {})

const jsonBody = JSON.stringify(body, null, 2)
const jsonBody = lrdDocsItem.examples ? JSON.stringify(lrdDocsItem.examples, null, 2) : JSON.stringify(body, null, 2)
setBodyParams(jsonBody)
console.log(jsonBody)
setCurlCommand(makeCurlCommand(host, lrdDocsItem.uri, method, jsonBody, requestHeaders))
}
}, [])
Expand Down
5 changes: 5 additions & 0 deletions ui/src/libs/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export interface IConfig {
default_headers: string[];
}

export interface IAPIExample {
[key: string]: string[];
}

export interface IAPIInfo {
uri: string;
middlewares: string[];
Expand All @@ -20,6 +24,7 @@ export interface IAPIInfo {
group: string;
group_index: number;
responses: string[];
examples: IAPIExample;

}

Expand Down

0 comments on commit d1b557d

Please sign in to comment.