Source: classes/books/Author.js

/** @module classes */

const AuthorController = require('../../controllers/AuthorController.js');
const BookController = require('../../controllers/BookController.js');
const BaseFactory = require('../Base.js');

/** Class representing an author. */
class Author {
    /**
     * Create an author.
     * @param {number} id
     * @param {string} name
     * @param {string} personalName
     * @param {date} createdAt
     * @param {date} updatedAt
     */
    constructor(id, name, personalName, createdAt, updatedAt) {
        this.id = id;
        this.name = name;
        this.personalName = personalName;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
    }

    /** Get the books of the author. */
    async getBooks(forceRefresh = false) {
        if (this.books && !forceRefresh) {
            return this.books;
        }

        this.books = await new BookController().byAuthor(this);

        return this.books;
    }

    /** Refreshes data from the database that has been pulled at least once before in this instance. */
    async refresh() {
        if (this.books) {
            await this.getBooks(true);
        }
    }

    /**
     * Link the author to a book.
     * 
     * @param {object} book
     * @returns {Promise<void>}
     */
    async linkToBook(book) {
        await new AuthorController().linkAuthorBook(this.id, book.id);
    }
}

/** Class representing an author factory. */
class AuthorFactory extends BaseFactory {
    /** Set the id of the author. */
    setId(id) {
        this.id = id;

        return this;
    }

    /** Set the name of the author. */
    setName(name) {
        this.name = name;
        
        return this;
    }
    
    /** Set the personal name of the author. */
    setPersonalName(personalName) {
        this.personalName = personalName;
        
        return this;
    }

    /** Set the created at date of the author. */
    setCreatedAt(createdAt) {
        this.createdAt = createdAt;
        
        return this;
    }

    /** Set the updated at date of the author. */
    setUpdatedAt(updatedAt) {
        this.updatedAt = updatedAt;
        
        return this;
    }

    /** Load an author from a database object. */
    load(dbObject) {
        this.setId(dbObject.id);
        this.setName(dbObject.name);
        this.setPersonalName(dbObject.personal_name);
        this.setCreatedAt(new Date(dbObject.created_at));
        this.setUpdatedAt(new Date(dbObject.updated_at));
        
        return this;
    }

    /** Create the author. */
    async create() {
        if (!this.id) {
            throw new Error('Missing required fields for Author');
        } else if (!this.name && !this.personalName && !this.createdAt && !this.updatedAt) {
            return await new AuthorController().byId(this.id);
        }
        
        return new Author(this.id, this.name, this.personalName, this.createdAt, this.updatedAt);
    }
}

module.exports = { AuthorFactory, Author };