Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Only list schemas that are used in this Scope
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Nov 8, 2023
commit 52198a2db1e29e640134d0ee1d510a07456ccfe8
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