290 lines
7.2 KiB
JavaScript
290 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;
|