diff --git a/server/models/Book.js b/server/models/Book.js index 9537d7b3..6b179c36 100644 --- a/server/models/Book.js +++ b/server/models/Book.js @@ -18,6 +18,19 @@ const Logger = require('../Logger') * @property {string} title */ +/** + * @typedef SeriesExpandedProperties + * @property {{sequence:string}} bookSeries + * + * @typedef {import('./Series') & SeriesExpandedProperties} SeriesExpanded + * + * @typedef BookExpandedProperties + * @property {import('./Author')[]} authors + * @property {SeriesExpanded[]} series + * + * @typedef {Book & BookExpandedProperties} BookExpanded + */ + /** * @typedef AudioFileObject * @property {number} index @@ -54,6 +67,8 @@ class Book extends Model { /** @type {string} */ this.titleIgnorePrefix /** @type {string} */ + this.subtitle + /** @type {string} */ this.publishedYear /** @type {string} */ this.publishedDate diff --git a/server/models/LibraryItem.js b/server/models/LibraryItem.js index 508cf4c6..ee8a4bb8 100644 --- a/server/models/LibraryItem.js +++ b/server/models/LibraryItem.js @@ -15,6 +15,13 @@ const Podcast = require('./Podcast') * @property {{filename:string, ext:string, path:string, relPath:string, size:number, mtimeMs:number, ctimeMs:number, birthtimeMs:number}} metadata */ +/** + * @typedef LibraryItemExpandedProperties + * @property {Book.BookExpanded|Podcast.PodcastExpanded} media + * + * @typedef {LibraryItem & LibraryItemExpandedProperties} LibraryItemExpanded + */ + class LibraryItem extends Model { constructor(values, options) { super(values, options) @@ -412,6 +419,55 @@ class LibraryItem extends Model { }) } + /** + * + * @param {string} libraryItemId + * @returns {Promise} + */ + static async getExpandedById(libraryItemId) { + if (!libraryItemId) return null + + const libraryItem = await this.findByPk(libraryItemId) + if (!libraryItem) { + Logger.error(`[LibraryItem] Library item not found with id "${libraryItemId}"`) + return null + } + + if (libraryItem.mediaType === 'podcast') { + libraryItem.media = await libraryItem.getMedia({ + include: [ + { + model: this.sequelize.models.podcastEpisode + } + ] + }) + } else { + libraryItem.media = await libraryItem.getMedia({ + include: [ + { + model: this.sequelize.models.author, + through: { + attributes: [] + } + }, + { + model: this.sequelize.models.series, + through: { + attributes: ['sequence'] + } + } + ], + order: [ + [this.sequelize.models.author, this.sequelize.models.bookAuthor, 'createdAt', 'ASC'], + [this.sequelize.models.series, 'bookSeries', 'createdAt', 'ASC'] + ] + }) + } + + if (!libraryItem.media) return null + return libraryItem + } + /** * Get old library item by id * @param {string} libraryItemId diff --git a/server/models/Podcast.js b/server/models/Podcast.js index 82ae8fe2..940ae0ab 100644 --- a/server/models/Podcast.js +++ b/server/models/Podcast.js @@ -1,5 +1,12 @@ const { DataTypes, Model } = require('sequelize') +/** + * @typedef PodcastExpandedProperties + * @property {import('./PodcastEpisode')[]} podcastEpisodes + * + * @typedef {Podcast & PodcastExpandedProperties} PodcastExpanded + */ + class Podcast extends Model { constructor(values, options) { super(values, options)