Schema updates from August 3 (#1)

* Update: formatting

* Fix: libraryItemController `play` endpoint
+ Endpoints cannot have optional path parameters
+ Moved schemas to `components` section

* Fix: MeController optional path parameters

* Fix: Books do not have `episodeId` in `mediaProgress`

* Fix: `PlaybackSession` oneOf between book and podcast

* Update: bundled spec

* Fix: `allowReserved` in LibraryItem include query

* Add: tags to AuthController endpoints

* Fix: summary of play endpoints

* Update: bundled spec
This commit is contained in:
Nicholas W 2024-08-04 00:00:32 -07:00 committed by GitHub
parent 7274b87aca
commit 3a91092fbf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 561 additions and 441 deletions

View file

@ -4,6 +4,8 @@ paths:
summary: Login to the server summary: Login to the server
description: Logs in a client to the server, returning information about the user and server. description: Logs in a client to the server, returning information about the user and server.
operationId: login operationId: login
tags:
- Auth
requestBody: requestBody:
required: true required: true
content: content:
@ -15,9 +17,6 @@ paths:
$ref: '../objects/entities/User.yaml#/components/schemas/username' $ref: '../objects/entities/User.yaml#/components/schemas/username'
password: password:
$ref: '../objects/entities/User.yaml#/components/schemas/password' $ref: '../objects/entities/User.yaml#/components/schemas/password'
required:
- username
- password
responses: responses:
'200': '200':
description: Success description: Success
@ -40,6 +39,8 @@ paths:
summary: Logout from the server summary: Logout from the server
description: Logs out a client from the server. If the socketId parameter is provided, the server removes the socket from the client list. description: Logs out a client from the server. If the socketId parameter is provided, the server removes the socket from the client list.
operationId: logout operationId: logout
tags:
- Auth
requestBody: requestBody:
required: true required: true
content: content:

View file

@ -1,3 +1,69 @@
components:
schemas:
parameters:
include:
in: query
name: include
description: A comma separated list of what to include with the library item. The options are progress, rssfeed, authors (for books), and downloads (for podcasts). expanded must be 1 for include to have an effect.
allowReserved: true
schema:
type: string
expanded:
in: query
name: expanded
description: Whether to return Library Item Expanded instead. 0 for false, 1 for true.
schema:
type: integer
example: 1
episode:
in: query
name: episode
description: If requesting progress for a podcast, the episode ID to get progress for.
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
deviceInfo:
in: query
name: deviceInfo
description: The device information to send to the server.
schema:
$ref: '../objects/entities/Device.yaml#/components/schemas/deviceInfo'
forceDirectPlay:
in: query
name: forceDirectPlay
description: Whether to force direct play of the library item.
schema:
type: boolean
example: false
forceTranscode:
in: query
name: forceTranscode
description: Whether to force transcoding of the library item.
schema:
type: boolean
example: false
supportedMimeTypes:
in: query
name: supportedMimeTypes
description: The supported mime types for the device.
schema:
type: array
items:
type: string
mediaPlayer:
in: query
name: mediaPlayer
description: The media player to use.
schema:
type: string
responses:
libraryItem404:
description: Not Found
content:
text/html:
schema:
type: string
description: The library item does not exist.
example: Not Found
paths: paths:
/api/items/{id}: /api/items/{id}:
parameters: parameters:
@ -14,22 +80,9 @@ paths:
tags: tags:
- LibraryItem - LibraryItem
parameters: parameters:
- in: query - $ref: '#/components/schemas/parameters/include'
name: include - $ref: '#/components/schemas/parameters/expanded'
description: A comma separated list of what to include with the library item. The options are progress, rssfeed, authors (for books), and downloads (for podcasts). expanded must be 1 for include to have an effect. - $ref: '#/components/schemas/parameters/episode'
schema:
type: string
- in: query
name: expanded
description: Whether to return Library Item Expanded instead. 0 for false, 1 for true.
schema:
type: integer
example: 1
- in: query
name: episode
description: If requesting progress for a podcast, the episode ID to get progress for.
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
responses: responses:
'200': '200':
description: OK description: OK
@ -40,6 +93,37 @@ paths:
description: TODO description: TODO
oneOf: oneOf:
- $ref: '../objects/LibraryItem.yaml#/components/schemas/libraryItem' - $ref: '../objects/LibraryItem.yaml#/components/schemas/libraryItem'
'404':
$ref: '#/components/responses/libraryItem404'
/api/items/{id}/play:
parameters:
- name: id
in: path
description: The ID of the library item.
required: true
schema:
$ref: '../objects/LibraryItem.yaml#/components/schemas/libraryItemId'
post:
operationId: playLibraryItem
summary: Play a library item
description: Play a library item by ID.
tags:
- LibraryItem
parameters:
- $ref: '#/components/schemas/parameters/deviceInfo'
- $ref: '#/components/schemas/parameters/forceDirectPlay'
- $ref: '#/components/schemas/parameters/forceTranscode'
- $ref: '#/components/schemas/parameters/supportedMimeTypes'
- $ref: '#/components/schemas/parameters/mediaPlayer'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '../objects/entities/PlaybackSession.yaml#/components/schemas/playbackSessionExpanded'
'404':
$ref: '#/components/responses/libraryItem404'
/api/items/{id}/play/{episodeId}: /api/items/{id}/play/{episodeId}:
parameters: parameters:
- name: id - name: id
@ -51,45 +135,21 @@ paths:
- name: episodeId - name: episodeId
in: path in: path
description: The ID of the episode to play. description: The ID of the episode to play.
required: false required: true
schema: schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId' $ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
post: post:
operationId: playLibraryItem operationId: playLibraryItemPodcastEpisode
summary: Play a library item. summary: Play a podcast episode
description: Play a library item. description: Play a podcast by library item ID and episode ID.
tags: tags:
- LibraryItem - LibraryItem
parameters: parameters:
- in: query - $ref: '#/components/schemas/parameters/deviceInfo'
name: deviceInfo - $ref: '#/components/schemas/parameters/forceDirectPlay'
description: The device information to send to the server. - $ref: '#/components/schemas/parameters/forceTranscode'
schema: - $ref: '#/components/schemas/parameters/supportedMimeTypes'
$ref: '../objects/entities/Device.yaml#/components/schemas/deviceInfo' - $ref: '#/components/schemas/parameters/mediaPlayer'
- in: query
name: forceDirectPlay
description: Whether to force direct play of the library item.
schema:
type: boolean
example: false
- in: query
name: forceTranscode
description: Whether to force transcoding of the library item.
schema:
type: boolean
example: false
- in: query
name: supportedMimeTypes
description: The supported mime types for the device.
schema:
type: array
items:
type: string
- in: query
name: mediaPlayer
description: The media player to use.
schema:
type: string
responses: responses:
'200': '200':
description: OK description: OK
@ -98,10 +158,4 @@ paths:
schema: schema:
$ref: '../objects/entities/PlaybackSession.yaml#/components/schemas/playbackSessionExpanded' $ref: '../objects/entities/PlaybackSession.yaml#/components/schemas/playbackSessionExpanded'
'404': '404':
description: Not Found $ref: '#/components/responses/libraryItem404'
content:
text/html:
schema:
type: string
description: The library item does not have any audio tracks to play.
example: Not Found

View file

@ -4,6 +4,14 @@ components:
description: The total time listened in seconds. description: The total time listened in seconds.
type: integer type: integer
example: 123456 example: 123456
responses:
me404:
description: Not Found
content:
html/text:
schema:
type: string
example: Not Found
paths: paths:
/api/me: /api/me:
get: get:
@ -19,7 +27,7 @@ paths:
application/json: application/json:
schema: schema:
$ref: '../objects/entities/User.yaml#/components/schemas/user' $ref: '../objects/entities/User.yaml#/components/schemas/user'
/api/me/progress/{libraryItemId}/{episodeId}: /api/me/progress/{libraryItemId}:
parameters: parameters:
- name: libraryItemId - name: libraryItemId
in: path in: path
@ -27,14 +35,8 @@ paths:
required: true required: true
schema: schema:
$ref: '../objects/LibraryItem.yaml#/components/schemas/libraryItemId' $ref: '../objects/LibraryItem.yaml#/components/schemas/libraryItemId'
- name: episodeId
in: path
description: The ID of the episode to get progress for.
required: false
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
get: get:
operationId: getProgress operationId: getProgressLibraryItem
summary: Get the user's progress for a library item. summary: Get the user's progress for a library item.
description: Get the user's progress for a library item. description: Get the user's progress for a library item.
tags: tags:
@ -47,24 +49,25 @@ paths:
schema: schema:
$ref: '../objects/Media.yaml#/components/schemas/mediaProgress' $ref: '../objects/Media.yaml#/components/schemas/mediaProgress'
'404': '404':
description: Not Found $ref: '#/components/responses/me404'
content: /api/me/progress/{libraryItemId}/{episodeId}:
html/text:
schema:
type: string
example: Not Found
/api/me/progress/{mediaId}:
parameters: parameters:
- name: mediaId - name: libraryItemId
in: path in: path
description: The ID of the media progress. description: The ID of the library item.
required: true required: true
schema: schema:
$ref: '../objects/Media.yaml#/components/schemas/mediaProgressId' $ref: '../objects/LibraryItem.yaml#/components/schemas/libraryItemId'
- name: episodeId
in: path
description: The ID of the episode to get progress for.
required: true
schema:
$ref: '../objects/mediaTypes/Podcast.yaml#/components/schemas/podcastId'
get: get:
operationId: getProgressById operationId: getProgressPodcastEpisode
summary: Get the user's progress for a media item. summary: Get the user's progress for a podcast episode.
description: Get the user's progress for a media item. description: Get the user's progress for a podcast episode.
tags: tags:
- Me - Me
responses: responses:
@ -73,14 +76,9 @@ paths:
content: content:
application/json: application/json:
schema: schema:
$ref: '../objects/Media.yaml#/components/schemas/mediaProgress' $ref: '../objects/Media.yaml#/components/schemas/mediaProgressPodcastEpisode'
'404': '404':
description: Not Found $ref: '#/components/responses/me404'
content:
html/text:
schema:
type: string
example: Not Found
/api/me/listening-sessions: /api/me/listening-sessions:
get: get:
operationId: getListeningSessions operationId: getListeningSessions

View file

@ -7,7 +7,7 @@ components:
bookmark: bookmark:
properties: properties:
libraryItemId: libraryItemId:
$ref: 'LibraryItem.yaml#/components/schemas/libraryItemId' $ref: './LibraryItem.yaml#/components/schemas/libraryItemId'
title: title:
type: string type: string
description: The title of the bookmark. description: The title of the bookmark.

View file

@ -5,17 +5,6 @@ components:
description: The ID of the media progress. description: The ID of the media progress.
example: e4bb1afb-4a4f-4dd6-8be0-e615d233185b example: e4bb1afb-4a4f-4dd6-8be0-e615d233185b
format: uuid format: uuid
mediaProgress:
type: object
properties:
id:
$ref: '#/components/schemas/mediaProgressId'
libraryItemId:
$ref: 'LibraryItem.yaml#/components/schemas/libraryItemId'
episodeId:
$ref: 'mediaTypes/Podcast.yaml#/components/schemas/podcastId'
duration:
$ref: '../schemas.yaml#/components/schemas/durationSec'
progress: progress:
type: number type: number
description: The user's progress in the media item. description: The user's progress in the media item.
@ -32,11 +21,56 @@ components:
type: boolean type: boolean
description: Whether the media item should be hidden from the continue listening section. description: Whether the media item should be hidden from the continue listening section.
example: false example: false
finishedAt:
type: integer
nullable: true
description: The time (in ms since POSIX epoch) when the media was finished. Will be null if the media has is not finished.
example: 1616239000
mediaProgress:
type: object
properties:
id:
$ref: '#/components/schemas/mediaProgressId'
libraryItemId:
$ref: './LibraryItem.yaml#/components/schemas/libraryItemId'
duration:
$ref: '../schemas.yaml#/components/schemas/durationSec'
progress:
$ref: '#/components/schemas/progress'
currentTime:
$ref: '#/components/schemas/currentTime'
isFinished:
$ref: '#/components/schemas/isFinished'
hideFromContinueListening:
$ref: '#/components/schemas/hideFromContinueListening'
lastUpdate: lastUpdate:
$ref: '../schemas.yaml#/components/schemas/updatedAt' $ref: '../schemas.yaml#/components/schemas/updatedAt'
startedAt: startedAt:
$ref: '../schemas.yaml#/components/schemas/createdAt' $ref: '../schemas.yaml#/components/schemas/createdAt'
finishedAt: finishedAt:
type: integer $ref: '#/components/schemas/finishedAt'
description: The time (in ms since POSIX epoch) when the media was finished. Will be null if the media has is not finished. mediaProgressPodcastEpisode:
example: 1616239000 type: object
properties:
id:
$ref: '#/components/schemas/mediaProgressId'
libraryItemId:
$ref: './LibraryItem.yaml#/components/schemas/libraryItemId'
episodeId:
$ref: './mediaTypes/Podcast.yaml#/components/schemas/podcastId'
duration:
$ref: '../schemas.yaml#/components/schemas/durationSec'
progress:
$ref: '#/components/schemas/progress'
currentTime:
$ref: '#/components/schemas/currentTime'
isFinished:
$ref: '#/components/schemas/isFinished'
hideFromContinueListening:
$ref: '#/components/schemas/hideFromContinueListening'
lastUpdate:
$ref: '../schemas.yaml#/components/schemas/updatedAt'
startedAt:
$ref: '../schemas.yaml#/components/schemas/createdAt'
finishedAt:
$ref: '#/components/schemas/finishedAt'

View file

@ -11,15 +11,15 @@ components:
clientName: clientName:
description: The client name. description: The client name.
type: string type: string
example: "Audible" example: 'Audible'
manufacturer: manufacturer:
description: The manufacturer of the device. description: The manufacturer of the device.
type: string type: string
example: "Apple" example: 'Apple'
model: model:
description: The model of the device. description: The model of the device.
type: string type: string
example: "iPhone 12" example: 'iPhone 12'
sdkVersion: sdkVersion:
description: For an Android client, the Android SDK version of the client. description: For an Android client, the Android SDK version of the client.
type: integer type: integer

View file

@ -7,6 +7,17 @@ components:
playbackSession: playbackSession:
type: object type: object
description: A playback session object. description: A playback session object.
oneOf:
- $ref: '#/components/schemas/playbackSessionBook'
- $ref: '#/components/schemas/playbackSessionPodcast'
discriminator:
propertyName: mediaType
mapping:
book: '#/components/schemas/playbackSessionBook'
podcast: '#/components/schemas/playbackSessionPodcast'
playbackSessionBase:
type: object
description: Base playback session object.
properties: properties:
id: id:
$ref: '#/components/schemas/playbackSessionId' $ref: '#/components/schemas/playbackSessionId'
@ -16,20 +27,8 @@ components:
$ref: '../Library.yaml#/components/schemas/libraryId' $ref: '../Library.yaml#/components/schemas/libraryId'
libraryItemId: libraryItemId:
$ref: '../LibraryItem.yaml#/components/schemas/libraryItemId' $ref: '../LibraryItem.yaml#/components/schemas/libraryItemId'
episodeId:
$ref: '../mediaTypes/Podcast.yaml#/components/schemas/podcastId'
mediaType: mediaType:
$ref: '../mediaTypes/media.yaml#/components/schemas/mediaType' $ref: '../mediaTypes/media.yaml#/components/schemas/mediaType'
mediaMetadata:
description: The metadata of the media.
oneOf:
- $ref: '../mediaTypes/Book.yaml#/components/schemas/bookMinified'
- $ref: '../mediaTypes/Podcast.yaml#/components/schemas/Podcast'
chapters:
description: The chapters of the media.
type: array
items:
$ref: '../metadata/BookMetadata.yaml#/components/schemas/bookChapter'
displayTitle: displayTitle:
description: The display title of the media. description: The display title of the media.
type: string type: string
@ -66,10 +65,58 @@ components:
$ref: '../../schemas.yaml#/components/schemas/createdAt' $ref: '../../schemas.yaml#/components/schemas/createdAt'
updatedAt: updatedAt:
$ref: '../../schemas.yaml#/components/schemas/updatedAt' $ref: '../../schemas.yaml#/components/schemas/updatedAt'
playbackSessionExpanded: playbackSessionBook:
description: Expanded playback session schema. description: Book playback session schema.
allOf: allOf:
- $ref: '#/components/schemas/playbackSession' - $ref: '#/components/schemas/playbackSessionBase'
- properties:
mediaMetadata:
$ref: '../metadata/BookMetadata.yaml#/components/schemas/bookMetadata'
chapters:
description: The chapters of the media.
type: array
items:
$ref: '../metadata/BookMetadata.yaml#/components/schemas/bookChapter'
playbackSessionPodcast:
description: Podcast playback session schema.
allOf:
- $ref: '#/components/schemas/playbackSessionBase'
- properties:
mediaMetadata:
$ref: '../metadata/PodcastMetadata.yaml#/components/schemas/PodcastMetadata'
episodeId:
$ref: '../mediaTypes/Podcast.yaml#/components/schemas/podcastId'
playbackSessionExpanded:
type: object
description: A playback session object.
oneOf:
- $ref: '#/components/schemas/playbackSessionBookExpanded'
- $ref: '#/components/schemas/playbackSessionPodcastExpanded'
discriminator:
propertyName: mediaType
mapping:
book: '#/components/schemas/playbackSessionBookExpanded'
podcast: '#/components/schemas/playbackSessionPodcastExpanded'
playbackSessionBookExpanded:
description: Expanded book playback session schema.
allOf:
- $ref: '#/components/schemas/playbackSessionBook'
- properties:
audioTracks:
description: The audio tracks of the media.
type: array
items:
$ref: '../files/AudioTrack.yaml#/components/schemas/AudioTrack'
videoTrack:
description: The video track of the media. TODO
type: object
nullable: true
libraryItem:
$ref: '../LibraryItem.yaml#/components/schemas/libraryItem'
playbackSessionPodcastExpanded:
description: Expanded podcast playback session schema.
allOf:
- $ref: '#/components/schemas/playbackSessionPodcast'
- properties: - properties:
audioTracks: audioTracks:
description: The audio tracks of the media. description: The audio tracks of the media.

View file

@ -108,4 +108,3 @@ components:
example: audio example: audio
metadata: metadata:
$ref: '../metadata/FileMetadata.yaml#/components/schemas/fileMetadata' $ref: '../metadata/FileMetadata.yaml#/components/schemas/fileMetadata'

View file

@ -24,7 +24,7 @@ components:
type: array type: array
items: items:
type: string type: string
example: ["Fantasy", "Sci-Fi", "Nonfiction: History"] example: ['Fantasy', 'Sci-Fi', 'Nonfiction: History']
publishedYear: publishedYear:
description: The year the book was published. Will be null if unknown. description: The year the book was published. Will be null if unknown.
type: string type: string
@ -44,23 +44,9 @@ components:
type: string type: string
nullable: true nullable: true
example: >- example: >-
The masterpiece that started Terry Goodkind's New York Times bestselling The masterpiece that started Terry Goodkind's New York Times bestselling epic Sword of Truth In the aftermath of the brutal murder of his father, a mysterious woman, Kahlan Amnell, appears in Richard Cypher's forest sanctuary seeking help...and more. His world, his very beliefs, are shattered when ancient debts come due with thundering violence. In a dark age it takes courage to live, and more than mere courage to challenge those who hold dominion, Richard and Kahlan must take up that challenge or become the next victims. Beyond awaits a bewitching land where even the best of their hearts could betray them. Yet, Richard fears nothing so much as what secrets his sword might reveal about his own soul. Falling in love would destroy them - for reasons Richard can't imagine and Kahlan dare not say. In their darkest hour, hunted relentlessly, tormented by treachery and loss, Kahlan calls upon Richard to reach beyond his sword - to invoke within himself something more noble. Neither knows that the rules of battle have just changed...or that their time has run out. Wizard's First Rule is the beginning. One book. One Rule. Witness the birth of a legend.
epic Sword of Truth In the aftermath of the brutal murder of his father,
a mysterious woman, Kahlan Amnell, appears in Richard Cypher's forest
sanctuary seeking help...and more. His world, his very beliefs, are
shattered when ancient debts come due with thundering violence. In a
dark age it takes courage to live, and more than mere courage to
challenge those who hold dominion, Richard and Kahlan must take up that
challenge or become the next victims. Beyond awaits a bewitching land
where even the best of their hearts could betray them. Yet, Richard
fears nothing so much as what secrets his sword might reveal about his
own soul. Falling in love would destroy them - for reasons Richard can't
imagine and Kahlan dare not say. In their darkest hour, hunted
relentlessly, tormented by treachery and loss, Kahlan calls upon Richard
to reach beyond his sword - to invoke within himself something more
noble. Neither knows that the rules of battle have just changed...or
that their time has run out. Wizard's First Rule is the beginning. One
book. One Rule. Witness the birth of a legend.
isbn: isbn:
description: The ISBN of the book. Will be null if unknown. description: The ISBN of the book. Will be null if unknown.
type: string type: string
@ -147,4 +133,3 @@ components:
type: array type: array
items: items:
$ref: '../entities/Series.yaml#/components/schemas/seriesSequence' $ref: '../entities/Series.yaml#/components/schemas/seriesSequence'

Binary file not shown.

View file

@ -83,14 +83,16 @@ paths:
$ref: './controllers/AuthController.yaml#/paths/~1logout' $ref: './controllers/AuthController.yaml#/paths/~1logout'
/api/items/{id}: /api/items/{id}:
$ref: './controllers/LibraryItemController.yaml#/paths/~1api~1items~1{id}' $ref: './controllers/LibraryItemController.yaml#/paths/~1api~1items~1{id}'
/api/items/{id}/play:
$ref: './controllers/LibraryItemController.yaml#/paths/~1api~1items~1{id}~1play'
/api/items/{id}/play/{episodeId}: /api/items/{id}/play/{episodeId}:
$ref: './controllers/LibraryItemController.yaml#/paths/~1api~1items~1{id}~1play~1{episodeId}' $ref: './controllers/LibraryItemController.yaml#/paths/~1api~1items~1{id}~1play~1{episodeId}'
/api/me: /api/me:
$ref: './controllers/MeController.yaml#/paths/~1api~1me' $ref: './controllers/MeController.yaml#/paths/~1api~1me'
/api/me/progress/{libraryItemId}:
$ref: './controllers/MeController.yaml#/paths/~1api~1me~1progress~1{libraryItemId}'
/api/me/progress/{libraryItemId}/{episodeId}: /api/me/progress/{libraryItemId}/{episodeId}:
$ref: './controllers/MeController.yaml#/paths/~1api~1me~1progress~1{libraryItemId}~1{episodeId}' $ref: './controllers/MeController.yaml#/paths/~1api~1me~1progress~1{libraryItemId}~1{episodeId}'
/api/me/progress/{mediaId}:
$ref: './controllers/MeController.yaml#/paths/~1api~1me~1progress~1{mediaId}'
/api/session/{id}/sync: /api/session/{id}/sync:
$ref: './controllers/SessionController.yaml#/paths/~1api~1session~1{id}~1sync' $ref: './controllers/SessionController.yaml#/paths/~1api~1session~1{id}~1sync'
/api/sessions/{id}: /api/sessions/{id}: