Skip to content

Commit

Permalink
Support enum in output
Browse files Browse the repository at this point in the history
  • Loading branch information
shalvah committed Aug 20, 2023
1 parent d3970ae commit 81fbec9
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 12 deletions.
4 changes: 4 additions & 0 deletions resources/views/components/field-details.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@
}
@endphp
{!! Parsedown::instance()->text(trim($description)) !!}
@if(!empty($enumValues))
Must be one of:
<ul style="list-style-type: square;">{!! implode(" ", array_map(fn($val) => "<li><code>$val</code></li>", $enumValues)) !!}</ul>
@endif
3 changes: 3 additions & 0 deletions resources/views/components/nested-fields.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
'required' => $subfield['required'] ?? false,
'description' => $subfield['description'] ?? '',
'example' => $subfield['example'] ?? '',
'enumValues' => $subfield['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
Expand Down Expand Up @@ -66,6 +67,7 @@
'required' => $subfield['required'] ?? false,
'description' => $subfield['description'] ?? '',
'example' => $subfield['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
Expand All @@ -86,6 +88,7 @@
'required' => $field['required'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => false,
'component' => 'body',
Expand Down
2 changes: 2 additions & 0 deletions resources/views/themes/default/endpoint.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
'required' => $parameter->required,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'url',
'isInput' => true,
Expand All @@ -156,6 +157,7 @@
'required' => $parameter->required,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'query',
'isInput' => true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class="svg-inline--fa fa-chevron-right fa-fw fa-sm sl-icon" role="img"
{!! Parsedown::instance()->text($description) !!}
</div>
@endif
@if(!empty($enumValues))
Must be one of:
<ul style="list-style-position: inside; list-style-type: square;">{!! implode(" ", array_map(fn($val) => "<li><code>$val</code></li>", $enumValues)) !!}</ul>
@endif
@if($isArrayBody)
<div class="sl-flex sl-items-baseline sl-text-base">
<div class="sl-font-mono sl-font-semibold sl-mr-2">array of:</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
'required' => $field['required'] ?? false,
'description' => $field['description'] ?? '',
'example' => $field['example'] ?? '',
'enumValues' => $field['enumValues'] ?? null,
'endpointId' => $endpointId,
'hasChildren' => !empty($field['__fields']),
'component' => 'body',
Expand Down
2 changes: 2 additions & 0 deletions resources/views/themes/elements/endpoint.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class="sl-overflow-x-hidden sl-truncate sl-text-muted">{{ rtrim($baseUrl, '/') }
'required' => $parameter->required,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'url',
'isInput' => true,
Expand All @@ -104,6 +105,7 @@ class="sl-overflow-x-hidden sl-truncate sl-text-muted">{{ rtrim($baseUrl, '/') }
'required' => $parameter->required,
'description' => $parameter->description,
'example' => $parameter->example ?? '',
'enumValues' => $parameter->enumValues,
'endpointId' => $endpoint->endpointId(),
'component' => 'query',
'isInput' => true,
Expand Down
3 changes: 0 additions & 3 deletions src/Extracting/ParsesValidationRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ protected function parseRule($rule, array &$parameterData, bool $independentOnly
$cases = array_map(fn ($case) => $case->value, $type::cases());
$parameterData['type'] = gettype($cases[0]);
$parameterData['enumValues'] = $cases;
$parameterData['description'] .= ' Must be one of ' . w::getListOfValuesAsFriendlyHtmlString($cases) . ' ';
$parameterData['setter'] = fn () => Arr::random($cases);
}

Expand Down Expand Up @@ -466,8 +465,6 @@ protected function parseRule($rule, array &$parameterData, bool $independentOnly
*/
case 'in':
$parameterData['enumValues'] = $arguments;
// Not using the rule description here because it only says "The attribute is invalid"
$parameterData['description'] .= ' Must be one of ' . w::getListOfValuesAsFriendlyHtmlString($arguments) . ' ';
$parameterData['setter'] = function () use ($arguments) {
return Arr::random($arguments);
};
Expand Down
5 changes: 4 additions & 1 deletion src/Extracting/Strategies/GetParamsFromAttributeStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ protected function normalizeParameterData(array $data): array
{
$data['type'] = static::normalizeTypeName($data['type']);
if (is_null($data['example'])) {
$data['example'] = $this->generateDummyValue($data['type'], ['name' => $data['name']]);
$data['example'] = $this->generateDummyValue($data['type'], [
'name' => $data['name'],
'enumValues' => $data['enumValues'],
]);
} else if ($data['example'] == 'No-example' || $data['example'] == 'No-example.') {
$data['example'] = null;
}
Expand Down
21 changes: 13 additions & 8 deletions src/Writing/OpenAPISpecWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,16 @@ public function generateFieldData($field): array
})->all()),
];
} else {
return [
$schema = [
'type' => static::normalizeTypeName($field->type),
'description' => $field->description ?: '',
'example' => $field->example,
];
if (!empty($field->enumValues)) {
$schema['enum'] = $field->enumValues;
}

return $schema;
}
}

Expand All @@ -523,30 +528,30 @@ protected function operationId(OutputEndpointData $endpoint): string
if ($endpoint->metadata->title) return preg_replace('/[^\w+]/', '', Str::camel($endpoint->metadata->title));

$parts = preg_split('/[^\w+]/', $endpoint->uri, -1, PREG_SPLIT_NO_EMPTY);
return Str::lower($endpoint->httpMethods[0]) . join('', array_map(fn ($part) => ucfirst($part), $parts));
return Str::lower($endpoint->httpMethods[0]) . join('', array_map(fn($part) => ucfirst($part), $parts));
}

/**
* Given an array, return an object if the array is empty. To be used with fields that are
* required by OpenAPI spec to be objects, since empty arrays get serialised as [].
*/
protected function objectIfEmpty(array $field): array | \stdClass
protected function objectIfEmpty(array $field): array|\stdClass
{
return count($field) > 0 ? $field : new \stdClass();
}

/**
* Given a value, generate the schema for it. The schema consists of: {type:, example:, properties: (if value is an object)},
* and possibly a description for each property.
* The $endpoint and $path are used for looking up response field descriptions.
* Given a value, generate the schema for it. The schema consists of: {type:, example:, properties: (if value is an
* object)}, and possibly a description for each property. The $endpoint and $path are used for looking up response
* field descriptions.
*/
public function generateSchemaForValue(mixed $value, OutputEndpointData $endpoint, string $path): array
{
if ($value instanceof \stdClass) {
$value = (array) $value;
$value = (array)$value;
$properties = [];
// Recurse into the object
foreach($value as $subField => $subValue){
foreach ($value as $subField => $subValue) {
$subFieldPath = sprintf('%s.%s', $path, $subField);
$properties[$subField] = $this->generateSchemaForValue($subValue, $endpoint, $subFieldPath);
}
Expand Down

0 comments on commit 81fbec9

Please sign in to comment.