Skip to content

Commit

Permalink
Only list schemas that are used in this Scope
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Nov 8, 2023
1 parent 7f6cefb commit 52198a2
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 338 deletions.
38 changes: 35 additions & 3 deletions generate-spec
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,10 @@ foreach ($capabilitiesFiles as $path) {
}
}
if ($capabilities != null) {
$schemas["Capabilities"] = $capabilities;
$schemas['Capabilities'] = $capabilities;
}
if ($publicCapabilities != null) {
$schemas["PublicCapabilities"] = $publicCapabilities;
$schemas['PublicCapabilities'] = $publicCapabilities;
}
if ($capabilities == null && $publicCapabilities == null) {
Logger::warning("Capabilities", "No capabilities were loaded");
Expand Down Expand Up @@ -709,7 +709,6 @@ if (count($schemas) == 0 && count($routes) == 0) {
}

ksort($schemas);
$openapi["components"]["schemas"] = count($schemas) == 0 ? new stdClass() : $schemas;

if ($useTags) {
$openapi["tags"] = $tags;
Expand All @@ -726,6 +725,39 @@ foreach ($scopePaths as $scope => $paths) {
$openapiScope['info']['title'] .= $scopeSuffix;
$openapiScope['paths'] = $paths;

$usedSchemas = [];
foreach ($paths as $url => $urlRoutes) {
foreach ($urlRoutes as $httpMethod => $routeData) {
foreach ($routeData['responses'] as $statusCode => $responseData) {
$usedSchemas = array_merge($usedSchemas, Helpers::collectUsedRefs($responseData['content']['application/json']['schema']));
}
}
}

$scopedSchemas = [];
foreach ($usedSchemas as $usedSchema) {
if (!str_starts_with($usedSchema, '#/components/schemas/')) {
continue;
}

$schemaName = substr($usedSchema, strlen('#/components/schemas/'));

if (!isset($schemas[$schemaName])) {
Logger::error("app", "Schema $schemaName used by scope $scope is not defined");
}

$scopedSchemas[$schemaName] = $schemas[$schemaName];
}

if (isset($schemas['Capabilities'])) {
$scopedSchemas['Capabilities'] = $schemas['Capabilities'];
}
if (isset($schemas['PublicCapabilities'])) {
$scopedSchemas['PublicCapabilities'] = $schemas['PublicCapabilities'];
}

$openapiScope['components']['schemas'] = $scopedSchemas;

$startExtension = strrpos($out, '.');
if ($startExtension !== false) {
// Path + filename (without extension)
Expand Down
15 changes: 15 additions & 0 deletions src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,19 @@ static function getAttributeScopes(ClassMethod|Class_|Node $node, string $annota

return $scopes;
}

static function collectUsedRefs(array $data): array {
$refs = [];
if (isset($data['$ref'])) {
$refs[] = [$data['$ref']];
}
if (isset($data['properties'])) {
foreach ($data['properties'] as $property) {
if (is_array($property)) {
$refs[] = self::collectUsedRefs($property);
}
}
}
return array_merge(...$refs);
}
}
19 changes: 17 additions & 2 deletions tests/lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@

namespace OCA\Notifications\Controller;

use OCA\Notifications\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\OpenAPI;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;

/**
* @psalm-import-type NotificationsPushDevice from ResponseDefinitions
*/
#[OpenAPI(scope: OpenAPI::SCOPE_FEDERATION)]
class SettingsController extends OCSController {

Expand Down Expand Up @@ -92,13 +96,24 @@ public function defaultAdminScope(): DataResponse {
*
* Route is only in the admin scope due to defined scope
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @return DataResponse<Http::STATUS_OK, NotificationsPushDevice, array{}>
*
* 200: Admin settings updated
*/
#[OpenAPI(scope: OpenAPI::SCOPE_ADMINISTRATION)]
public function adminScope(): DataResponse {
return new DataResponse();
return new DataResponse($this->createNotificationsPushDevice());
}

/**
* @return NotificationsPushDevice
*/
protected function createNotificationsPushDevice(): array {
return [
'publicKey' => 'publicKey',
'deviceIdentifier' => 'deviceIdentifier',
'signature' => 'signature',
];
}

/**
Expand Down
102 changes: 3 additions & 99 deletions tests/openapi-administration.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,104 +20,6 @@
}
},
"schemas": {
"Notification": {
"type": "object",
"required": [
"notification_id",
"app",
"user",
"datetime",
"object_type",
"object_id",
"subject",
"message",
"link",
"actions"
],
"properties": {
"notification_id": {
"type": "integer",
"format": "int64"
},
"app": {
"type": "string"
},
"user": {
"type": "string"
},
"datetime": {
"type": "string"
},
"object_type": {
"type": "string"
},
"object_id": {
"type": "string"
},
"subject": {
"type": "string"
},
"message": {
"type": "string"
},
"link": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationAction"
}
},
"subjectRich": {
"type": "string"
},
"subjectRichParameters": {
"type": "object",
"additionalProperties": {
"type": "object"
}
},
"messageRich": {
"type": "string"
},
"messageRichParameters": {
"type": "object",
"additionalProperties": {
"type": "object"
}
},
"icon": {
"type": "string"
},
"shouldNotify": {
"type": "boolean"
}
}
},
"NotificationAction": {
"type": "object",
"required": [
"label",
"link",
"type",
"primary"
],
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
},
"type": {
"type": "string"
},
"primary": {
"type": "boolean"
}
}
},
"OCSMeta": {
"type": "object",
"required": [
Expand Down Expand Up @@ -224,7 +126,9 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
"data": {
"$ref": "#/components/schemas/PushDevice"
}
}
}
}
Expand Down
117 changes: 0 additions & 117 deletions tests/openapi-federation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,104 +20,6 @@
}
},
"schemas": {
"Notification": {
"type": "object",
"required": [
"notification_id",
"app",
"user",
"datetime",
"object_type",
"object_id",
"subject",
"message",
"link",
"actions"
],
"properties": {
"notification_id": {
"type": "integer",
"format": "int64"
},
"app": {
"type": "string"
},
"user": {
"type": "string"
},
"datetime": {
"type": "string"
},
"object_type": {
"type": "string"
},
"object_id": {
"type": "string"
},
"subject": {
"type": "string"
},
"message": {
"type": "string"
},
"link": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationAction"
}
},
"subjectRich": {
"type": "string"
},
"subjectRichParameters": {
"type": "object",
"additionalProperties": {
"type": "object"
}
},
"messageRich": {
"type": "string"
},
"messageRichParameters": {
"type": "object",
"additionalProperties": {
"type": "object"
}
},
"icon": {
"type": "string"
},
"shouldNotify": {
"type": "boolean"
}
}
},
"NotificationAction": {
"type": "object",
"required": [
"label",
"link",
"type",
"primary"
],
"properties": {
"label": {
"type": "string"
},
"link": {
"type": "string"
},
"type": {
"type": "string"
},
"primary": {
"type": "boolean"
}
}
},
"OCSMeta": {
"type": "object",
"required": [
Expand All @@ -141,25 +43,6 @@
"type": "string"
}
}
},
"PushDevice": {
"type": "object",
"required": [
"publicKey",
"deviceIdentifier",
"signature"
],
"properties": {
"publicKey": {
"type": "string"
},
"deviceIdentifier": {
"type": "string"
},
"signature": {
"type": "string"
}
}
}
}
},
Expand Down
Loading

0 comments on commit 52198a2

Please sign in to comment.