Controllers_CrudController.js

const JsonResponse = require('./JsonResponse');
let logger = require('../Logger');
const crypto = require("crypto");

/**
 * contiens la documantation de tous les controller de l'application, applé dans le router
 * @namespace Controllers
 * @memberOf Myintranet
 */

/**
 * The controller controls the data from the front and Security then call the service that dose the work
 * @memberOf Myintranet.Controllers
 */
class CrudController {

    /**
     * Crée une nouvelle instance de CrudController.
     * @param service is the service responsible of data manipulation
     * @param validator the validator to use see @ahassani/validate
     * @param db the database object
     */
    constructor(service,addValidator, db,updateValidator) {
        this.service = service;
        this.db = db || null;
        this.validator = addValidator || {
            validate: () => []
        };
        this.uValidator = updateValidator || {
            validate: () => []
        };
    }

    /**
     * Récupére l'id depuis la request, en testant dans les params si pas d'id dans les params on regarde dans la query et si pas d'id dans la query on regarde dans le body
     * @param {Request} request the request object
     * @returns {Number|null} the id if found or null
     * @private
     */
    __getIdFromRequest(request){
        let id = null;
        if (request.params?.id) {
            id = request.params.id;
        } else if (request.query?.id) {
            id = request.query.id;
        } else if (request.body?.id) {
            id = request.body.id;
        }
        return id;
    }

    /**
     * transform un mot de passe en claire en mdp crypté et son slat
     * @private
     * @param clearPassword
     * @returns {{password: string, salt: string}}
     */
    getPasswordAndSalt(clearPassword) {
        let length = 32;
        let salt = crypto.randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, 32);
        let hash = crypto.createHmac('sha512', salt);
        hash.update(clearPassword);
        let password = hash.digest('hex');
        return {password, salt};
    }




    toDto(data){
        return data;
    }
    toDtoArray(arrayData){
      return  arrayData.map(this.toDto)
    }

    /**
     * si un id est passé retourne getOne sinon  return getAll
     * @param {Request} request the HttpRequest
     * @param {Response} response The HttpResponse
     */
    get(request, response) {
        let id = this.__getIdFromRequest(request);
        if (id === null) {
            this.service.getAll(request)
                .then(data => {
                    response.json(new JsonResponse(true, this.toDtoArray(data), ""));
                })
                .catch(err => {
                    logger.error(err.message, err);
                    response.json(new JsonResponse(false, err, err.message));
                })
        } else {
            this.service.getOne(request)
                .then(data => {
                    response.json(new JsonResponse(true, this.toDto(data), ""));
                })
                .catch(err => {
                    logger.error(err.message, err);
                    response.json(new JsonResponse(false, err, err.message));
                })
        }


    }

    /**
     *
     * @param {Request}  request the HttpRequest
     * @returns {Array} true if the request.body is valid for adding a record, or an array containing errors.
     */
    isValidForAdd(request) {
        let dataToValidate = JSON.parse(JSON.stringify(request.body));
        return this.validator.validate(dataToValidate)
    }

    /**
     * Ajoute un enregistrement a la base de donnée
     * @param {Request} request the HttpRequest
     * @param {Response} response The HttpResponse
     */
    add(request, response) {
        let errors = this.isValidForAdd(request);
        if (errors.length === 0) {
            this.service.add(request).then(data => {
                response.json(new JsonResponse(true, this.toDto(data), ""));
            }).catch(err => {
                logger.error(err.message, err);
                response.json(new JsonResponse(false, err, err.message));
            })
        } else {
            logger.error(errors);
            let e = errors.map((err) => {
                return err.message;
            })
            response.json(new JsonResponse(false, e, errors[0].message));
        }
    }

    /**
     * verifie la validité de la request avant de passer au service pour la mise a jour
     * @param request
     * @returns {boolean|Array}
     */
    isValidForUpdate(request) {
        let dataToValidate = JSON.parse(JSON.stringify(request.body));
        return this.uValidator.validate(dataToValidate)
    }

    /**
     * met a jour de l'entite concernée
     * @param {Request} request the HttpRequest
     * @param {Response} response The HttpResponse
     */
    update(request, response) {
        let errors = this.isValidForUpdate(request);
        if (errors.length === 0) {
            this.service.update(request).then(data => {
                this.service.getOne(request).then(element => {
                    response.json(new JsonResponse(true, this.toDto(element), ""));
                }).catch(err => {
                    logger.error(err.message, err);
                    response.json(new JsonResponse(false, err, err.message));
                })
            }).catch(err => {
                logger.error(err.message, err);
                response.json(new JsonResponse(false, err, err.message));
            })
        } else {
            logger.error(errors[0], errors);
            let e = errors.map((err) => {
                return err.message;
            })
            response.json(new JsonResponse(false, e, errors[0].message));
        }
    }

    /**
     * verifie la validité de la request avant de passer au service pour la suppression
     * @param {Request} request the HttpRequest
     * @returns {boolean}
     */
    isValidForDelete(request) {
        return true;
    }

    /**
     * supprime une entité depuis la base de donnée
     * @param {Request} request the HttpRequest
     * @param {Response} response The HttpResponse
     */
    delete(request, response) {

        let errors = this.isValidForDelete(request);
        if (errors === true) {
            this.service.delete(request).then(data => {
                response.json(new JsonResponse(true, data, "ok"));
            }).catch(err => {
                logger.error(err.message, err);
                response.json(new JsonResponse(false, {}, err.message));
            })
        } else {
            logger.error(errors[0], errors);
            response.json(new JsonResponse(false, errors, errors[0]));
        }
    }

    /**
     * @param {Request} request the HttpRequest
     * @param {Response} response The HttpResponse
     */
    filter(request, response) {
        this.service.findByText(request).then(data => {
            response.json(new JsonResponse(true, data, "ok"));
        }).catch(err => {
            logger.error(err.message, err)
            response.json(new JsonResponse(false, err, err.message));
        })
    }
}


module.exports = CrudController;