const { DataTypes, Model } = require('sequelize') class PlaylistMediaItem extends Model { constructor(values, options) { super(values, options) /** @type {UUIDV4} */ this.id /** @type {UUIDV4} */ this.mediaItemId /** @type {string} */ this.mediaItemType /** @type {number} */ this.order /** @type {UUIDV4} */ this.playlistId /** @type {Date} */ this.createdAt } static removeByIds(playlistId, mediaItemId) { return this.destroy({ where: { playlistId, mediaItemId } }) } getMediaItem(options) { if (!this.mediaItemType) return Promise.resolve(null) const mixinMethodName = `get${this.sequelize.uppercaseFirst(this.mediaItemType)}` return this[mixinMethodName](options) } /** * Initialize model * @param {import('../Database').sequelize} sequelize */ static init(sequelize) { super.init({ id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true }, mediaItemId: DataTypes.UUIDV4, mediaItemType: DataTypes.STRING, order: DataTypes.INTEGER }, { sequelize, timestamps: true, updatedAt: false, modelName: 'playlistMediaItem' }) const { book, podcastEpisode, playlist } = sequelize.models book.hasMany(PlaylistMediaItem, { foreignKey: 'mediaItemId', constraints: false, scope: { mediaItemType: 'book' } }) PlaylistMediaItem.belongsTo(book, { foreignKey: 'mediaItemId', constraints: false }) podcastEpisode.hasOne(PlaylistMediaItem, { foreignKey: 'mediaItemId', constraints: false, scope: { mediaItemType: 'podcastEpisode' } }) PlaylistMediaItem.belongsTo(podcastEpisode, { foreignKey: 'mediaItemId', constraints: false }) PlaylistMediaItem.addHook('afterFind', findResult => { if (!findResult) return if (!Array.isArray(findResult)) findResult = [findResult] for (const instance of findResult) { if (instance.mediaItemType === 'book' && instance.book !== undefined) { instance.mediaItem = instance.book instance.dataValues.mediaItem = instance.dataValues.book } else if (instance.mediaItemType === 'podcastEpisode' && instance.podcastEpisode !== undefined) { instance.mediaItem = instance.podcastEpisode instance.dataValues.mediaItem = instance.dataValues.podcastEpisode } // To prevent mistakes: delete instance.book delete instance.dataValues.book delete instance.podcastEpisode delete instance.dataValues.podcastEpisode } }) playlist.hasMany(PlaylistMediaItem, { onDelete: 'CASCADE' }) PlaylistMediaItem.belongsTo(playlist) } } module.exports = PlaylistMediaItem