Hi, thank you both for your help!
Don’t know how I’ve missed creating that file in the correct folder. OpenAPI works now.
Psalm still complains because the declared type from ResponseDefinitions.php (BookshelfsBook) is still different from the actual underlying type (final class Book extends Entity implements JsonSerializable)
e.g. the comment
* @return DataResponse<Http::STATUS_OK, list<BookshelfsBook> , array{}> | DataResponse<Http::STATUS_BAD_REQUEST, list<string> , array{}>
Results in the Psalm errors:
ERROR: MoreSpecificReturnType - bookshelfs/lib/ControllerBooksController.php#L39\lib/Controller/BooksController.php:39:13
The declared return type ‘OCP\AppFramework\Http\DataResponse<200|400, list<array{author: string, colour: string, file: int, height: int, id: int, pattern: int, position: int, title: string, url: string}|string>, array<never, never>>
for OCA\Bookshelfs\Controller\BooksController::getUserBooks is more specific than the inferred return type
OCP\AppFramework\Http\DataResponse<200|400, array<array-key, OCA\Bookshelfs\Db\Book|string>, array<never, never>>’ (see ``https://psalm.dev/070``)
ERROR: LessSpecificReturnStatement
bookshelfs/lib/Controller/BooksController.php#L51\lib/Controller/BooksController.php:51:11]
The type 'OCP\AppFramework\Http\DataResponse<200, array<array-key, OCA\Bookshelfs\Db\Book>, array<never, never>>'
is more general than the declared return type 'OCP\AppFramework\Http\DataResponse<200|400, list<array{author: string, colour: string, file: int, height: int, id: int, pattern: int, position: int, title: string, url: string}|string>, array<never, never>>'
for OCA\Bookshelfs\Controller\BooksController::getUserBooks (see https://psalm.dev/129)
return new DataResponse($this->bookMapper->getBooksOfUser($this->userId));
ERROR: LessSpecificReturnStatement
bookshelfs/lib/Controller/BooksController.php#L53e\lib/Controller/BooksController.php:53:1-
The type 'OCP\AppFramework\Http\DataResponse<400, array{error: string}, array<never, never>>'
is more general than the declared return type 'OCP\AppFramework\Http\DataResponse<200|400, list<array{author: string, colour: string, file: int, height: int, id: int, pattern: int, position: int, title: string, url: string}|string>, array<never, never>>'
for OCA\Bookshelfs\Controller\BooksController::getUserBooks (see https://psalm.dev/129)
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
I think it is not possible to have a solution that covers both the types (Book:Entity and BookshelfsBook - Which are supposed to be the same) ?
(I know a workaround is increasing the errorlevel of psalm or adding issueHandlers, but that is my last resort)
Full code snippet I have so far (cfr. BooksController:addUserBook#L78 )
/**
* Create a new book for the current user
*
* @param string $title Title of the book
* @param string $author Author of the book
* @param int $position Position of the book in the shelf (array index)
* @param int $cover File ID of the book cover image
* @param int $file File ID of the (e-)book file
* @param string $colour Color of the book
* @param int $pattern Pattern of the book
* @param int $height Height of the book
* @param int $width Width of the book
* @param int $orientation Orientation of the book (e.g. Showing front or spine)
*
* @return DataResponse<Http::STATUS_OK, BookshelfsBook , array{}> | DataResponse<Http::STATUS_BAD_REQUEST, list<string>, array{}>
*
* @response 200: Created and returned the book successfully
* @response 400: Bad request
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'POST', url: '/api/v1/books')]
public function addUserBook(string $title, string $author, int $position, int $cover, int $file, string $colour, int $pattern, int $height, int $width, int $orientation): DataResponse {
try {
/** @var BookshelfsBook $book */
$book = $this->bookMapper->createBook($this->userId, $title, $author, $position, $colour, $pattern, $height, $width, $orientation, $cover, $file);
return new DataResponse($book);
} catch (Throwable $e) {
/** @var list<string> $error */
$error = ['error' => $e->getMessage()];
return new DataResponse($error, Http::STATUS_BAD_REQUEST);
}
}
Would there be a solution that both adheres to Psalm (errorlevel 1) as well as the checks of OpenAPI-generator?