import QueryBuilder from "./QueryBuilder"; import ErrorBuilder from "./ErrorBuilder"; class Middleware extends QueryBuilder { /** * Initialisation de la classe * @param {Object} params * @param {Object} models */ constructor(params, models) { super(params, models); this.params = params; this.models = models; this.includes = []; } /** * Fonction permettant de créer un nouvel élément * @param {Object} req * @param {Function} callback * @return {Boolean} */ createOne(req, callback) { // On test les droits if (!this.haveRight(req)) { callback(new ErrorBuilder(401.1, "You're not allowed")); return false; } // On teste le body this.checkCreateOneValues(req, (err, value) => { // Il manque un paramètre dans le body if (err) { callback(err, value); return false; } this.insertItem(req, value, callback); return true; }); return true; } /** * Fonction permettant de retourner une liste d'items * @param {Object} req * @param {Function} callback */ getAll(req, callback) { // On spécifie le type de requête (list ou item) req.getType = "list"; this.createQuery(req, (err, query, limit) => { if (err) { callback(err, query); return false; } this.models[this.params.model] .findAndCountAll(query) .then(res => { if (!res || res.count === 0) { callback(); return false; } const rows = []; for (let i = 0; i < res.rows.length; i += 1) { const current = res.rows[i]; let found = false; for (let j = 0; j < rows.length; j += 1) { if (rows[j].id === current.id) { found = true; rows[j].assign({}, rows[j], current); break; } } if (!found || rows.length === 0) { rows.push(current); } } const total = rows.length; const values = rows.slice(limit.start, limit.start + limit.limit); callback(null, { data: this.formatItems(req, values), ...QueryBuilder.createPagination( req, total, limit.limit, limit.start ) }); return true; }) .catch(callback); return true; }); } /** * Fonction permettant de retourner un item par son Id * @param {Object} req * @param {Function} callback */ getOne(req, callback) { // On spécifie le type de requête (list ou item) req.getType = "item"; this.createQuery(req, (err, query) => { if (err) { callback(err, query); return false; } this.models[this.params.model] .findOne(query) .then(item => { if (!item) { callback(new ErrorBuilder(404, "Item not found")); return false; } let formatedItem = item; if (req.method === "GET") { if (this.params.format) { const formatRules = this.params.format[req.user.role]; if (formatRules) { formatedItem = this.formatItem(item, formatRules); } } } callback(null, formatedItem); return true; }) .catch(callback); return true; }); } /** * Fonction permettant de mettre à jour un item * @param {Object} req * @param {Function} callback * @return {Boolean} */ patchOne(req, callback) { // On test les droits if (!this.haveRight(req)) { callback(new ErrorBuilder(401.1, "You're not allowed")); return false; } // On teste les params const { error, value } = this.params.validate.update.validate(req.body, { abortEarly: false }); // Un paramètre n'est pas bon dans les params if (error) { callback(new ErrorBuilder(406.1, error)); return false; } this.getOne(req, (err, item) => { if (err) { callback(err, item); return false; } item .update(value) .then(updated => { if (this.params.belongsToMany) { const needCreate = []; let created = 0; const _next = errNext => { if (errNext) { // TODO: break and revert } else { created += 1; if (created === needCreate.length) { callback(null, updated); } } }; Object.keys(this.params.belongsToMany).map(key => { if (value[key]) { needCreate.push(key); } return true; }); if (needCreate.length > 0) { for (let i = 0; i < needCreate.length; i += 1) { const currentKey = needCreate[i]; const currentValue = value[currentKey]; this.createBelonsTo( updated, currentKey, currentValue, "add", _next ); } } else { callback(null, updated); } } else { callback(null, updated); } }) .catch(callback); return true; }); return true; } /** * Fonction permettant de supprimer un item * @param {Object} req * @param {Function} callback * @return {Boolean} */ deleteOne(req, callback) { // On test les droits if (!this.haveRight(req)) { callback(new ErrorBuilder(401.1, "You're not allowed")); return false; } this.getOne(req, (err, item) => { if (err) { callback(err, item); } else { let deletedBelongs = 0; const needToDeleteBelongs = []; const _deleteItem = () => { item .destroy() .then(() => { callback(null, {}); }) .catch(callback); }; const _next = () => { deletedBelongs += 1; if (deletedBelongs === needToDeleteBelongs.length) { _deleteItem(); } }; if (this.params.belongsToMany) { Object.keys(this.params.belongsToMany).map(key => { const collection = this.params.belongsToMany[key]; if (item[collection].length) { needToDeleteBelongs.push(key); } return true; }); if (needToDeleteBelongs.length > 0) { for (let i = 0; i < needToDeleteBelongs.length; i += 1) { const currentKey = needToDeleteBelongs[i]; const collection = this.params.belongsToMany[currentKey]; const valuesToDelete = []; for (let j = 0; j < item[collection].length; j += 1) { valuesToDelete.push(item[collection][j].id); } this.deleteBelongsTo(item, currentKey, valuesToDelete, _next); } } else { _deleteItem(); } } else { _deleteItem(); } } }); return true; } } export default Middleware;