diff --git a/generate-spec b/generate-spec index 227eece..df3e7b6 100755 --- a/generate-spec +++ b/generate-spec @@ -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"); @@ -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; @@ -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) diff --git a/src/Helpers.php b/src/Helpers.php index ff8738e..b464b00 100644 --- a/src/Helpers.php +++ b/src/Helpers.php @@ -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); + } } diff --git a/tests/lib/Controller/SettingsController.php b/tests/lib/Controller/SettingsController.php index fdd42a1..e237f3f 100644 --- a/tests/lib/Controller/SettingsController.php +++ b/tests/lib/Controller/SettingsController.php @@ -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 { @@ -92,13 +96,24 @@ public function defaultAdminScope(): DataResponse { * * Route is only in the admin scope due to defined scope * - * @return DataResponse, array{}> + * @return DataResponse * * 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', + ]; } /** diff --git a/tests/openapi-administration.json b/tests/openapi-administration.json index 502151a..65f90fb 100644 --- a/tests/openapi-administration.json +++ b/tests/openapi-administration.json @@ -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": [ @@ -224,7 +126,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "$ref": "#/components/schemas/PushDevice" + } } } } diff --git a/tests/openapi-federation.json b/tests/openapi-federation.json index 2a492e3..fc38cea 100644 --- a/tests/openapi-federation.json +++ b/tests/openapi-federation.json @@ -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": [ @@ -141,25 +43,6 @@ "type": "string" } } - }, - "PushDevice": { - "type": "object", - "required": [ - "publicKey", - "deviceIdentifier", - "signature" - ], - "properties": { - "publicKey": { - "type": "string" - }, - "deviceIdentifier": { - "type": "string" - }, - "signature": { - "type": "string" - } - } } } }, diff --git a/tests/openapi.json b/tests/openapi.json index de51e19..c349739 100644 --- a/tests/openapi.json +++ b/tests/openapi.json @@ -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": [ @@ -141,25 +43,6 @@ "type": "string" } } - }, - "PushDevice": { - "type": "object", - "required": [ - "publicKey", - "deviceIdentifier", - "signature" - ], - "properties": { - "publicKey": { - "type": "string" - }, - "deviceIdentifier": { - "type": "string" - }, - "signature": { - "type": "string" - } - } } } },