From 29b01e832f42de436501b41a2e022653fdfc5ee9 Mon Sep 17 00:00:00 2001 From: Benjamin Gaussorgues Date: Thu, 18 Dec 2025 11:15:15 +0100 Subject: [PATCH 1/3] feat: add new response type StreamTraversableResponse Signed-off-by: Benjamin Gaussorgues --- src/ResponseType.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ResponseType.php b/src/ResponseType.php index da9da47c..164a32dd 100644 --- a/src/ResponseType.php +++ b/src/ResponseType.php @@ -135,6 +135,14 @@ public static function getAll(): array { null, null, ), + new ResponseType( + 'StreamTraversableResponse', + false, + false, + null, + null, + null, + ), new ResponseType( 'TemplateResponse', false, From c4502aa8a7a27e749b03320bf3268fc0a709e923 Mon Sep 17 00:00:00 2001 From: Benjamin Gaussorgues Date: Fri, 30 Jan 2026 09:56:19 +0100 Subject: [PATCH 2/3] chore: add StreamTraversableResponse example Signed-off-by: Benjamin Gaussorgues --- .../lib/Controller/OpenMetricsController.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/lib/Controller/OpenMetricsController.php diff --git a/tests/lib/Controller/OpenMetricsController.php b/tests/lib/Controller/OpenMetricsController.php new file mode 100644 index 00000000..d3bd92fd --- /dev/null +++ b/tests/lib/Controller/OpenMetricsController.php @@ -0,0 +1,30 @@ +, array{}> + * + * 200: Export OK + */ + public function export(): StreamTraversableResponse { + return new StreamTraversableResponse($this->generator()); + } + + private function generator(): \Generator { + yield from []; + } +} From c877b0627d4c93bdfb86549962f20a353eac5407 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 30 Jan 2026 10:13:41 +0100 Subject: [PATCH 3/3] test: Add ApiRoute so it executes Signed-off-by: Joas Schilling --- ...Controller.php => StreamingController.php} | 8 +- tests/openapi-administration.json | 91 +++++++++++++++++++ tests/openapi-full.json | 91 +++++++++++++++++++ 3 files changed, 187 insertions(+), 3 deletions(-) rename tests/lib/Controller/{OpenMetricsController.php => StreamingController.php} (63%) diff --git a/tests/lib/Controller/OpenMetricsController.php b/tests/lib/Controller/StreamingController.php similarity index 63% rename from tests/lib/Controller/OpenMetricsController.php rename to tests/lib/Controller/StreamingController.php index d3bd92fd..8a0c004e 100644 --- a/tests/lib/Controller/OpenMetricsController.php +++ b/tests/lib/Controller/StreamingController.php @@ -10,17 +10,19 @@ namespace OCA\Notifications\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\ApiRoute; use OCP\AppFramework\OCSController; -class OpenMetricsController extends OCSController { +class StreamingController extends OCSController { /** * Use StreamTraversableResponse response type * - * @return StreamTraversableResponse, array{}> + * @return StreamTraversableResponse * * 200: Export OK */ - public function export(): StreamTraversableResponse { + #[ApiRoute(verb: 'GET', url: '/streaming/traversable')] + public function traversable(): StreamTraversableResponse { return new StreamTraversableResponse($this->generator()); } diff --git a/tests/openapi-administration.json b/tests/openapi-administration.json index 4bc36595..76ffb3dc 100644 --- a/tests/openapi-administration.json +++ b/tests/openapi-administration.json @@ -9648,6 +9648,97 @@ } } }, + "/ocs/v2.php/apps/notifications/streaming/traversable": { + "get": { + "operationId": "streaming-traversable", + "summary": "Use StreamTraversableResponse response type", + "description": "This endpoint requires admin access", + "tags": [ + "streaming" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Export OK" + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, "/index.php/tests/attribute-index/{param}": { "get": { "operationId": "routing-attribute-index-route", diff --git a/tests/openapi-full.json b/tests/openapi-full.json index afb019c4..a6a30974 100644 --- a/tests/openapi-full.json +++ b/tests/openapi-full.json @@ -9848,6 +9848,97 @@ } } }, + "/ocs/v2.php/apps/notifications/streaming/traversable": { + "get": { + "operationId": "streaming-traversable", + "summary": "Use StreamTraversableResponse response type", + "description": "This endpoint requires admin access", + "tags": [ + "streaming" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Export OK" + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, "/index.php/tests/attribute-index/{param}": { "get": { "operationId": "routing-attribute-index-route",