sequelize-middleware/libs/Middleware.js
2020-02-13 22:36:14 +01:00

291 lines
7.2 KiB
JavaScript

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;