const { DataTypes, Model, where, fn, col } = require('sequelize') const parseNameString = require('../utils/parsers/parseNameString') class Author extends Model { constructor(values, options) { super(values, options) /** @type {UUIDV4} */ this.id /** @type {string} */ this.name /** @type {string} */ this.lastFirst /** @type {string} */ this.asin /** @type {string} */ this.description /** @type {string} */ this.imagePath /** @type {UUIDV4} */ this.libraryId /** @type {Date} */ this.updatedAt /** @type {Date} */ this.createdAt } /** * * @param {string} name * @returns {string} */ static getLastFirst(name) { if (!name) return null return parseNameString.nameToLastFirst(name) } /** * Check if author exists * @param {string} authorId * @returns {Promise} */ static async checkExistsById(authorId) { return (await this.count({ where: { id: authorId } })) > 0 } /** * Get author by name and libraryId. name case insensitive * TODO: Look for authors ignoring punctuation * * @param {string} authorName * @param {string} libraryId * @returns {Promise} */ static async getByNameAndLibrary(authorName, libraryId) { return this.findOne({ where: [ where(fn('lower', col('name')), authorName.toLowerCase()), { libraryId } ] }) } /** * * @param {string} authorId * @returns {Promise} */ static async getAllLibraryItemsForAuthor(authorId) { const author = await this.findByPk(authorId, { include: [ { model: this.sequelize.models.book, include: [ { model: this.sequelize.models.libraryItem }, { model: this.sequelize.models.author, through: { attributes: [] } }, { model: this.sequelize.models.series, through: { attributes: ['sequence'] } } ] } ] }) const libraryItems = [] if (author.books) { for (const book of author.books) { const libraryItem = book.libraryItem libraryItem.media = book delete book.libraryItem libraryItems.push(libraryItem) } } return libraryItems } /** * Initialize model * @param {import('../Database').sequelize} sequelize */ static init(sequelize) { super.init( { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true }, name: DataTypes.STRING, lastFirst: DataTypes.STRING, asin: DataTypes.STRING, description: DataTypes.TEXT, imagePath: DataTypes.STRING }, { sequelize, modelName: 'author', indexes: [ { fields: [ { name: 'name', collate: 'NOCASE' } ] }, // { // fields: [{ // name: 'lastFirst', // collate: 'NOCASE' // }] // }, { fields: ['libraryId'] } ] } ) const { library } = sequelize.models library.hasMany(Author, { onDelete: 'CASCADE' }) Author.belongsTo(library) } toOldJSON() { return { id: this.id, asin: this.asin, name: this.name, description: this.description, imagePath: this.imagePath, libraryId: this.libraryId, addedAt: this.createdAt.valueOf(), updatedAt: this.updatedAt.valueOf() } } /** * * @param {number} numBooks * @returns */ toOldJSONExpanded(numBooks = 0) { const oldJson = this.toOldJSON() oldJson.numBooks = numBooks return oldJson } toJSONMinimal() { return { id: this.id, name: this.name } } } module.exports = Author