diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
index 9eb35dc..e418b25 100644
--- a/.php-cs-fixer.php
+++ b/.php-cs-fixer.php
@@ -15,6 +15,7 @@
'concat_space' => ['spacing' => 'one'],
'constant_case' => true,
'dir_constant' => true,
+ 'curly_braces_position' => true,
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
@@ -83,6 +84,7 @@
'single_line_after_imports' => true,
'single_line_comment_style' => ['comment_types' => ['hash']],
'single_quote' => true,
+ 'single_space_around_construct' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'switch_case_semicolon_to_colon' => true,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2f43ab4..49a3a37 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,23 @@
+### 2.1.0 (2023-11-23)
+
+#### New
+
+* Now possible to specify the OpenApi version when generating the spec (3.0.0 or 3.1.0).
+
+#### Fixed
+
+* The spec generator now supports the new Mako 10 directory structure as well as the legacy structure.
+
+--------------------------------------------------------
+
+### 2.0.0 (2023-11-23)
+
+#### Changes
+
+* Bumped requirements to Mako 10+ and PHP 8.1+
+
+--------------------------------------------------------
+
### 1.2.4 (2023-04-18)
#### Fixed
diff --git a/src/console/commands/GenerateRoutes.php b/src/console/commands/GenerateRoutes.php
index c090a90..ce51678 100644
--- a/src/console/commands/GenerateRoutes.php
+++ b/src/console/commands/GenerateRoutes.php
@@ -37,8 +37,7 @@ public function __construct(
Output $output,
protected Application $app,
protected FileSystem $fileSystem
- )
- {
+ ) {
parent::__construct($input, $output);
}
@@ -47,8 +46,7 @@ public function __construct(
*/
public function getArguments(): array
{
- return
- [
+ return [
new Argument('-i|--input', 'The path to the OpenApi specification file you want to generate routes from.', Argument::IS_OPTIONAL),
new Argument('-o|--output', 'The path to where you want to store the generated route file.', Argument::IS_OPTIONAL),
];
@@ -69,19 +67,16 @@ public function execute(?string $input = null, ?string $output = null): int
{
$input = $this->getInputFilePath($input);
- if(!$this->fileSystem->has($input))
- {
+ if (!$this->fileSystem->has($input)) {
$this->error("The [ {$input} ] specification file does not exist.");
return static::STATUS_ERROR;
}
- if($output === null)
- {
+ if ($output === null) {
$path = "{$this->app->getPath()}/routing";
}
- else
- {
+ else {
$path = rtrim($output, '/\\');
}
diff --git a/src/console/commands/GenerateSpec.php b/src/console/commands/GenerateSpec.php
index 1ee3642..8f9c83e 100644
--- a/src/console/commands/GenerateSpec.php
+++ b/src/console/commands/GenerateSpec.php
@@ -14,6 +14,7 @@
use mako\file\FileSystem;
use mako\openapi\generators\spec\Generator as SpecGenerator;
use mako\reactor\Command;
+use OpenApi\Annotations\OpenApi;
use function dirname;
use function strpos;
@@ -36,8 +37,7 @@ public function __construct(
Output $output,
protected Application $app,
protected FileSystem $fileSystem
- )
- {
+ ) {
parent::__construct($input, $output);
}
@@ -46,13 +46,13 @@ public function __construct(
*/
public function getArguments(): array
{
- return
- [
+ return [
new Argument('-f|--filename', 'The filename you want to use for the documentation (default: openapi).', Argument::IS_OPTIONAL),
new Argument('-s|--scan', 'The director(y|ies) you want to scan (default: app).', Argument::IS_ARRAY | Argument::IS_OPTIONAL),
new Argument('-e|--exclude', 'The director(y|ies) or filename(s) to exclude (as absolute or relative paths).', Argument::IS_ARRAY | Argument::IS_OPTIONAL),
new Argument('-p|--pattern', 'File pattern to scan (default: *.php).', Argument::IS_OPTIONAL),
new Argument('-o|--output', 'The output directory where you want to save the OpenAPI documentation (default: project root).', Argument::IS_OPTIONAL),
+ new Argument('-v|--version', 'The OpenAPI version to use (default: ' . OpenApi::DEFAULT_VERSION . ').', Argument::IS_OPTIONAL),
];
}
@@ -61,17 +61,20 @@ public function getArguments(): array
*/
protected function getScanPaths(?array $paths): array
{
- if(empty($paths))
- {
- return [$this->app->getPath() . '/controllers', $this->app->getPath() . '/models'];
+ if (empty($paths)) {
+ if ($this->fileSystem->has("{$this->app->getPath()}/controllers")) {
+ $controllers = "{$this->app->getPath()}/controllers";
+ } else {
+ $controllers = "{$this->app->getPath()}/http/controllers";
+ }
+
+ return [$controllers, "{$this->app->getPath()}'/models"];
}
$root = dirname($this->app->getPath());
- foreach($paths as $key => $value)
- {
- if(strpos($value, DIRECTORY_SEPARATOR) !== 0)
- {
+ foreach ($paths as $key => $value) {
+ if (strpos($value, DIRECTORY_SEPARATOR) !== 0) {
$paths[$key] = "{$root}/{$value}";
}
}
@@ -86,8 +89,7 @@ protected function getOutputPath(?string $path): string
{
$root = dirname($this->app->getPath());
- if(empty($path))
- {
+ if (empty($path)) {
return $root;
}
@@ -97,11 +99,20 @@ protected function getOutputPath(?string $path): string
/**
* Generates the API documentation.
*/
- public function execute(string $filename = 'openapi', ?array $scan = null, ?array $exclude = null, ?string $pattern = null, ?string $output = null): void
+ public function execute(string $filename = 'openapi', ?array $scan = null, ?array $exclude = null, ?string $pattern = null, ?string $output = null, string $version = OpenApi::DEFAULT_VERSION): void
{
$output = "{$this->getOutputPath($output)}/{$filename}.yml";
- (new SpecGenerator($this->fileSystem, $output, $this->getScanPaths($scan), $exclude, $pattern))->generate();
+ $generator = new SpecGenerator(
+ $this->fileSystem,
+ $output,
+ $this->getScanPaths($scan),
+ $exclude,
+ $pattern,
+ $version
+ );
+
+ $generator->generate();
$this->write("Successfully wrote OpenApi specification to [ {$output} ].");
}
diff --git a/src/generators/routing/Cached.php b/src/generators/routing/Cached.php
index cdae5bf..098de33 100644
--- a/src/generators/routing/Cached.php
+++ b/src/generators/routing/Cached.php
@@ -46,8 +46,7 @@ protected function registerRoute(string $method, string $path, array|Closure|str
$registerPatterns = '';
- if(!empty($patterns))
- {
+ if (!empty($patterns)) {
$patterns = var_export($patterns, true);
$registerPatterns = "->patterns({$patterns})";
diff --git a/src/generators/routing/Generator.php b/src/generators/routing/Generator.php
index 7ee84bd..aecc478 100644
--- a/src/generators/routing/Generator.php
+++ b/src/generators/routing/Generator.php
@@ -30,16 +30,14 @@ abstract class Generator
[
// String formats
- 'string' =>
- [
+ 'string' => [
'no-dot' => '[^/.]++',
'uuid' => '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}',
],
// Integer formats
- 'integer' =>
- [
+ 'integer' => [
'_' => '-?[0-9]+',
'auto-increment' => '[1-9][0-9]{0,}',
],
@@ -55,10 +53,8 @@ public function mergeParameters(array $pathParameters, array $operationParameter
{
$merged = [];
- foreach([$pathParameters, $operationParameters] as $parameters)
- {
- foreach($parameters as $parameter)
- {
+ foreach ([$pathParameters, $operationParameters] as $parameters) {
+ foreach ($parameters as $parameter) {
$merged[$parameter->name] = $parameter;
}
}
@@ -71,8 +67,7 @@ public function mergeParameters(array $pathParameters, array $operationParameter
*/
protected function getRouteAction(string $operationId): array|string
{
- if(strpos($operationId, '::') !== false)
- {
+ if (strpos($operationId, '::') !== false) {
return explode('::', $operationId, 2);
}
@@ -87,10 +82,8 @@ protected function getRouteAction(string $operationId): array|string
*/
protected function getRoutePath(string $path, array $parameters): string
{
- foreach($parameters as $parameter)
- {
- if($parameter->in === 'path' && $parameter->required === false)
- {
+ foreach ($parameters as $parameter) {
+ if ($parameter->in === 'path' && $parameter->required === false) {
$path = str_replace("{{$parameter->name}}", "{{$parameter->name}}?", $path);
}
}
@@ -107,16 +100,12 @@ protected function getRoutePatterns(array $parameters): array
{
$patterns = [];
- foreach($parameters as $parameter)
- {
- if($parameter->in === 'path')
- {
- if(isset($this->parameterPatterns[$parameter->schema->type][$parameter->schema->format ?? '_']))
- {
+ foreach ($parameters as $parameter) {
+ if ($parameter->in === 'path') {
+ if (isset($this->parameterPatterns[$parameter->schema->type][$parameter->schema->format ?? '_'])) {
$patterns[$parameter->name] = $this->parameterPatterns[$parameter->schema->type][$parameter->schema->format ?? '_'];
}
- elseif($parameter->schema->format !== null && str_starts_with($parameter->schema->format, 'regex:'))
- {
+ elseif ($parameter->schema->format !== null && str_starts_with($parameter->schema->format, 'regex:')) {
[, $regex] = explode(':', $parameter->schema->format);
$patterns[$parameter->name] = $regex;
@@ -141,12 +130,9 @@ protected function generateRoutes(SpecObjectInterface $openApi): void
{
$methods = ['get', 'post', 'put', 'patch', 'delete'];
- foreach($openApi->paths as $path => $definition)
- {
- foreach($methods as $method)
- {
- if($definition->{$method} !== null)
- {
+ foreach ($openApi->paths as $path => $definition) {
+ foreach ($methods as $method) {
+ if ($definition->{$method} !== null) {
$parameters = $this->mergeParameters($definition->parameters, $definition->{$method}->parameters);
$this->registerRoute(
diff --git a/src/generators/routing/Runtime.php b/src/generators/routing/Runtime.php
index 25093e9..9466324 100644
--- a/src/generators/routing/Runtime.php
+++ b/src/generators/routing/Runtime.php
@@ -20,8 +20,8 @@ class Runtime extends Generator
*/
public function __construct(
protected Routes $routes
- )
- {}
+ ) {
+ }
/**
* {@inheritDoc}
@@ -31,8 +31,7 @@ protected function registerRoute(string $method, string $path, array|Closure|str
/** @var \mako\http\routing\Route $route */
$route = $this->routes->{$method}($path, $action, $name);
- if(!empty($patterns))
- {
+ if (!empty($patterns)) {
$route->patterns($patterns);
}
}
diff --git a/src/generators/spec/Generator.php b/src/generators/spec/Generator.php
index 5242ec3..494c382 100644
--- a/src/generators/spec/Generator.php
+++ b/src/generators/spec/Generator.php
@@ -26,9 +26,10 @@ public function __construct(
protected string $outputFile,
protected $directory,
protected $exclude = null,
- protected ?string $pattern = null
- )
- {}
+ protected ?string $pattern = null,
+ protected string $version = OpenApi::DEFAULT_VERSION
+ ) {
+ }
/**
* Returns a finder instance.
@@ -43,7 +44,7 @@ protected function getFinder(): Finder
*/
protected function getGenerator(): ?OpenApi
{
- return OpenApiGenerator::scan($this->getFinder(), ['version' => OpenApi::DEFAULT_VERSION]);
+ return OpenApiGenerator::scan($this->getFinder(), ['version' => $this->version]);
}
/**