Skip to content

Commit

Permalink
Merge branch 'main' into feat/boolean-quirk-enum
Browse files Browse the repository at this point in the history
  • Loading branch information
nickvergessen authored Dec 21, 2023
2 parents 299fea3 + cc80ec1 commit bd9a003
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 38 deletions.
30 changes: 14 additions & 16 deletions generate-spec
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ $phpDocParser = new PhpDocParser($typeParser, $constExprParser);
$infoXMLPath = $dir . "/appinfo/info.xml";

if (file_exists($infoXMLPath)) {
$xml = simplexml_load_file($infoXMLPath);
$xml = simplexml_load_string(file_get_contents($infoXMLPath));
if ($xml === false) {
Logger::panic("appinfo", "info.xml file at " . $infoXMLPath . " is not parsable");
}

$appIsCore = false;
$appID = (string)$xml->id;
Expand Down Expand Up @@ -130,7 +133,7 @@ $tags = [];
$definitions = [];
$definitionsPath = $sourceDir . "/ResponseDefinitions.php";
if (file_exists($definitionsPath)) {
foreach ($nodeFinder->findInstanceOf(loadAST($definitionsPath), Class_::class) as $node) {
foreach ($nodeFinder->findInstanceOf($astParser->parse(file_get_contents($definitionsPath)), Class_::class) as $node) {
$doc = $node->getDocComment()?->getText();
if ($doc != null) {
$docNodes = $phpDocParser->parse(new TokenIterator($lexer->tokenize($doc)))->children;
Expand All @@ -145,7 +148,7 @@ if (file_exists($definitionsPath)) {
}
}
foreach (array_keys($definitions) as $name) {
$schemas[cleanSchemaName($name)] = OpenApiType::resolve("Response definitions", $definitions, $definitions[$name])->toArray($openapiVersion);
$schemas[Helpers::cleanSchemaName($name)] = OpenApiType::resolve("Response definitions", $definitions, $definitions[$name])->toArray($openapiVersion);
}
} else {
Logger::debug("Response definitions", "No response definitions were loaded");
Expand All @@ -167,7 +170,7 @@ foreach ($capabilitiesFiles as $path) {
/**
* @var Class_ $node
*/
foreach ($nodeFinder->findInstanceOf(loadAST($path), Class_::class) as $node) {
foreach ($nodeFinder->findInstanceOf($astParser->parse(file_get_contents($path)), Class_::class) as $node) {
$implementsCapability = count(array_filter($node->implements, fn (Name $name) => $name->getLast() == "ICapability")) > 0;
$implementsPublicCapability = count(array_filter($node->implements, fn (Name $name) => $name->getLast() == "IPublicCapability")) > 0;
if (!$implementsCapability && !$implementsPublicCapability) {
Expand Down Expand Up @@ -265,7 +268,7 @@ foreach ($parsedRoutes as $key => $value) {
$controllerName = ucfirst(str_replace("_", "", ucwords(explode("#", $routeName)[0], "_")));
$controllerClass = null;
/** @var Class_ $class */
foreach ($nodeFinder->findInstanceOf(loadAST($sourceDir . "/Controller/" . $controllerName . "Controller.php"), Class_::class) as $class) {
foreach ($nodeFinder->findInstanceOf($astParser->parse(file_get_contents($sourceDir . "/Controller/" . $controllerName . "Controller.php")), Class_::class) as $class) {
if ($class->name == $controllerName . "Controller") {
$controllerClass = $class;
break;
Expand Down Expand Up @@ -505,7 +508,12 @@ foreach ($routes as $route) {
}

$statusCodeResponses = array_filter($route->controllerMethod->responses, fn (?ControllerMethodResponse $response) => $response != null && $response->statusCode == $statusCode);
$headers = array_merge(...array_map(fn (ControllerMethodResponse $response) => $response->headers ?? [], $statusCodeResponses));
$headers = [];
foreach ($statusCodeResponses as $response) {
if ($response->headers !== null) {
$headers = array_merge($headers, $response->headers);
}
}

$mergedContentTypeResponses = [];
foreach (array_unique(array_map(fn (ControllerMethodResponse $response) => $response->contentType, array_filter($statusCodeResponses, fn (ControllerMethodResponse $response) => $response->contentType != null))) as $contentType) {
Expand Down Expand Up @@ -698,13 +706,3 @@ if ($useTags) {
}

file_put_contents($out, json_encode($openapi, Helpers::jsonFlags()));

function cleanSchemaName(string $name): string {
global $readableAppID;
return substr($name, strlen($readableAppID));
}

function loadAST(string $filename): array {
global $astParser;
return $astParser->parse(file_get_contents($filename));
}
9 changes: 5 additions & 4 deletions merge-specs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function loadSpec(string $path): array {

function rewriteRefs(array $spec): array {
$readableAppID = Helpers::generateReadableAppID($spec["info"]["title"]);
array_walk_recursive($spec, function (&$item, $key) use ($readableAppID) {
array_walk_recursive($spec, function (string &$item, string $key) use ($readableAppID) {
if ($key == "\$ref" && $item != "#/components/schemas/OCSMeta") {
$item = str_replace("#/components/schemas/", "#/components/schemas/" . $readableAppID, $item);
}
Expand All @@ -108,7 +108,7 @@ function rewriteRefs(array $spec): array {
function collectCapabilities(array $spec): array {
$capabilities = [];
$readableAppID = Helpers::generateReadableAppID($spec["info"]["title"]);
foreach ($spec["components"]["schemas"] as $name => $schema) {
foreach (array_keys($spec["components"]["schemas"]) as $name) {
if ($name == "Capabilities" || $name == "PublicCapabilities") {
$capabilities[] = $readableAppID . $name;
}
Expand Down Expand Up @@ -151,8 +151,9 @@ function rewriteOperations(array $spec): array {
$operation["tags"] = [$spec["info"]["title"]];
}
if ($firstStatusCode && array_key_exists("responses", $operation)) {
$firstStatusCode = array_key_first($operation["responses"]);
$operation["responses"] = [$firstStatusCode => $operation["responses"][$firstStatusCode]];
/** @var string $value */
$value = array_key_first($operation["responses"]);
$operation["responses"] = [$value => $operation["responses"][$value]];
}
if (array_key_exists("security", $operation)) {
for ($i = 0; $i < count($operation["security"]); $i++) {
Expand Down
4 changes: 2 additions & 2 deletions src/ControllerMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class ControllerMethod {
/**
* @param ControllerMethodParameter[] $parameters
* @param ControllerMethodResponse[] $responses
* @param list<ControllerMethodResponse|null> $responses
* @param OpenApiType[] $returns
* @param array<int, string> $responseDescription
* @param string[] $description
Expand Down Expand Up @@ -199,7 +199,7 @@ public static function parse(string $context, array $definitions, ClassMethod $m
Logger::warning($context, "Summary ends with a punctuation mark");
}

return new ControllerMethod($parameters, array_values($responses), $returns, $responseDescriptions, $methodDescription, $methodSummary, $isDeprecated);
return new ControllerMethod($parameters, $responses, $returns, $responseDescriptions, $methodDescription, $methodSummary, $isDeprecated);
}

}
2 changes: 1 addition & 1 deletion src/ControllerMethodParameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ private static function exprToValue(string $context, Expr $expr): mixed {
return -self::exprToValue($context, $expr->expr);
}
if ($expr instanceof Array_) {
$values = array_map(fn (ArrayItem $item) => self::exprToValue($context, $item), $expr->items);
$values = array_map(fn (ArrayItem $item): mixed => self::exprToValue($context, $item), $expr->items);
$filteredValues = array_filter($values, fn (mixed $value) => $value !== null);
if (count($filteredValues) != count($values)) {
return null;
Expand Down
30 changes: 19 additions & 11 deletions src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static function mapVerb(string $verb): string {
};
}

public static function mergeSchemas(array $schemas) {
public static function mergeSchemas(array $schemas): mixed {
if (!in_array(true, array_map(fn ($schema) => is_array($schema), $schemas))) {
$results = array_values(array_unique($schemas));
if (count($results) > 1) {
Expand All @@ -68,28 +68,31 @@ public static function mergeSchemas(array $schemas) {

$keys = [];
foreach ($schemas as $schema) {
foreach ($schema as $key => $value) {
foreach (array_keys($schema) as $key) {
$keys[] = $key;
}
}
$result = [];
/** @var string $key */
foreach ($keys as $key) {
if ($key == "required") {
$result["required"] = array_unique(array_merge(...array_map(function (array $schema) {
$required = [];
foreach ($schemas as $schema) {
if (array_key_exists("required", $schema)) {
return $schema["required"];
$required = array_merge($required, $schema["required"]);
}
return [];
}, $schemas)));
}
$result["required"] = array_unique($required);
continue;
}

$result[$key] = self::mergeSchemas(array_filter(array_map(function (array $schema) use ($key) {
$subSchemas = [];
foreach ($schemas as $schema) {
if (array_key_exists($key, $schema)) {
return $schema[$key];
$subSchemas[] = $schema[$key];
}
return null;
}, $schemas), fn ($schema) => $schema != null));
}
$result[$key] = self::mergeSchemas($subSchemas);
}

return $result;
Expand Down Expand Up @@ -123,7 +126,7 @@ public static function wrapOCSResponse(Route $route, ControllerMethodResponse $r
return $schema;
}

public static function cleanEmptyResponseArray(array|stdClass $schema): array|stdClass {
public static function cleanEmptyResponseArray(array $schema): array|stdClass {
if (key_exists("type", $schema) && $schema["type"] == "array" && key_exists("maxLength", $schema) && $schema["maxLength"] === 0) {
return new stdClass();
}
Expand All @@ -148,4 +151,9 @@ public static function classMethodHasAnnotationOrAttribute(ClassMethod|Class_|No

return false;
}

public static function cleanSchemaName(string $name): string {
global $readableAppID;
return substr($name, strlen($readableAppID));
}
}
7 changes: 7 additions & 0 deletions src/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public static function warning(string $context, string $text): void {
self::log(LoggerLevel::Warning, $context, $text);
}

/**
* @throws LoggerException
*/
public static function error(string $context, string $text): void {
if (self::$exitOnError) {
throw new LoggerException(LoggerLevel::Error, $context, $text);
Expand All @@ -42,6 +45,10 @@ public static function error(string $context, string $text): void {
}
}

/**
* @throws LoggerException
* @psalm-return no-return
*/
public static function panic(string $context, string $text): void {
throw new LoggerException(LoggerLevel::Error, $context, $text);
}
Expand Down
1 change: 1 addition & 0 deletions src/LoggerException.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;

class LoggerException extends Exception {
/** @psalm-suppress MissingParamType False-positive */
public function __construct(
public LoggerLevel $level,
public string $context,
Expand Down
5 changes: 3 additions & 2 deletions src/OpenApiType.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,9 @@ enum: [(int)$node->constExpr->value],

/**
* @param OpenApiType[] $types
* @return OpenApiType[]
*/
private static function mergeEnums(array $types) {
private static function mergeEnums(array $types): array {
$enums = [];
$nonEnums = [];

Expand Down Expand Up @@ -315,7 +316,7 @@ private static function resolveIdentifier(string $context, array $definitions, s
default => (function () use ($context, $definitions, $name) {
if (array_key_exists($name, $definitions)) {
return new OpenApiType(
ref: "#/components/schemas/" . cleanSchemaName($name),
ref: "#/components/schemas/" . Helpers::cleanSchemaName($name),
);
}
Logger::panic($context, "Unable to resolve OpenAPI type for identifier '" . $name . "'");
Expand Down
2 changes: 1 addition & 1 deletion src/ResponseType.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public static function getAll(): array {
/**
* @param string $context
* @param TypeNode $obj
* @return ControllerMethodResponse[]
* @return list<ControllerMethodResponse|null>
* @throws Exception
*/
public static function resolve(string $context, TypeNode $obj): array {
Expand Down
2 changes: 1 addition & 1 deletion src/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static function parseRoutes(string $path): array {
}
}

private static function includeRoutes(string $code) {
private static function includeRoutes(string $code): array {
$tmpPath = tempnam(sys_get_temp_dir(), "routes-");
file_put_contents($tmpPath, $code);
$routes = include($tmpPath);
Expand Down

0 comments on commit bd9a003

Please sign in to comment.