const Module = require('./Module'); const RepositorySystem = require('../systems/RepositorySystem'); const RoutingSystem = require('../systems/RoutingSystem'); const UserSystem = require('../systems/UserSystem'); const Logger = require('../systems/LoggerSystem'); const Actions = require('../systems/ActionSystem'); const Filter = require('../modules/Filters/FilterService'); const knex = require('../database/db')(); let ModulesLoaded = []; const ItemBasicScheme = { fields: [ { key: "createdAt", type: "timestamp", default: knex.fn.now() }, { key: "updatedAt", type: "timestamp" }, { key: "deleted", type: "boolean", default: 0, notNull: true } ] }; RoutingSystem.loadRoutes([{ type: 'custom', method: 'get', endpoint: '/CrudModules', customFn: (req, res) => { res.send(ModulesLoaded); } }]); class CrudModule extends Module { // Roles [ CREATE , READ , UPDATE , DELETE , READ ALL] constructor(prefix = '/', roles = [1,1,3,4,1], name = 'General', icon = '', Middlewares = []){ super(); this.routerPrefix = prefix; this.roles = roles; this.name = name; this.Middlewares = Middlewares; this.Model = { id: { type: 'Disabled' } }; ModulesLoaded.push({ Name: name, Route: prefix, Icon: icon }); this._initCrud(); } _initCrud() { let crudroutes = [ { type: 'custom', method: 'get', endpoint: '/Model', customFn: this.getModel.bind(this) }, { type: 'custom', method: 'post', endpoint: '/import', customFn: this.import.bind(this) }, { type: 'custom', method: 'get', endpoint: '/search/:search', customFn: (req, res) => { this.search(req, res); } }, { type: 'custom', method: 'get', endpoint: '/', customFn: this.getPage.bind(this) }, { type: 'custom', method: 'get', endpoint: '/count', customFn: this.count.bind(this) }, { type: 'custom', method: 'get', endpoint: '/:id', customFn: this.get.bind(this) }, { type: 'custom', method: 'post', endpoint: '/', customFn: this.post.bind(this) }, { type: 'custom', method: 'put', endpoint: '/:id', customFn: this.put.bind(this) }, { type: 'custom', method: 'delete', endpoint: '/:id', customFn: this.del.bind(this) } ]; RoutingSystem.loadRoutes(crudroutes, this.router, this.routerPrefix, this.Middlewares); Actions.on('post' + this.name, (item) => { delete item.createdAt; item.updatedAt = knex.fn.now(); return item; }); } getModel(req, res) { let ModelDTO = {}; return this._repository.columns().then((value) => { for(var i in value) { ModelDTO[i] = value[i]; } }).then(() => Actions.emit('model'+this.name, this.Model, req, res)) .then((model) => { for(var i in model) { ModelDTO[i] = { ...ModelDTO[i], ...model[i] }; } res.send(ModelDTO); }); } import(req, res) { let data = req.body; if(!data.rows || !data.cols) { res.status(400); res.send("No rows || no cols"); return; } let dict = data.cols.reduce((initial, item) => (initial[item.key] = item.name) && initial, {}) let dataset = data.rows.map((row) => { return row.reduce((initial, field, indx) => { (initial[dict[indx]] = field) return initial; }, {}); }); Actions.emit("import" + this.name, dataset, req, res) .then((batch) => Promise.all(batch.map((i) => this.clearObject(i)))) .then((batch) => { console.log("BATCH" , batch[0]); this._repository.batchInsert(batch) }) .then(() => res.sendStatus(200)) .catch((e) => { console.log(e); console.log("ERROR"); res.sendStatus(500) }); } setRepo(repo) { this._repository = repo; let name = this._repository.table; RepositorySystem.create(name, ItemBasicScheme); } search(req, res) { let searchParam = req.params.search; Filter.parseFilters( this.repository.raw(), req.filters ).where('name', 'like', '%'+searchParam+'%') .then((data) => Actions.emit('get' + this.name, data, req, res)) .then((data) => res.send(data)); } getPage(req, res) { UserSystem.role(req, res, this.roles[4]); let page = req.query.page; Filter.parseFilters( this._repository.getPage(page, req.query.perPage), req.filters ) .then((data) => Actions.emitArray('get'+this.name, data, req, res)) .then((data) => res.send(data || [])) .catch((e) => { Logger.error(e); return res.sendStatus(500); }); } get(req, res) { UserSystem.role(req, res, this.roles[1]); let id = req.params.id; this._repository.get('id', id) .then((data) => { if(!data.length) throw 404; return Actions.emit('get'+this.name, data[0], req, res); }) .then((data) => res.send(data)) .catch((e) => { if(e === 404) { return res.sendStatus(404); } Logger.error(e); }); } count(req, res) { UserSystem.role(req, res, this.roles[4]); Filter.parseFilters(this._repository.count(), req.filters) .then((data) => { res.send(data); }) .catch((e) => { if(e === 404) { return res.sendStatus(404); } Logger.error(e); }); } post(req, res) { UserSystem.role(req, res, this.roles[0]); let body = req.body; Actions.emit('post'+ this.name, body, req, res) .then((data) => { return this.clearObject(data); }) .then((data) => { return this._repository.insert(data) }) .then((data) => { res.sendStatus(200); }) .catch((e) => { res.sendStatus(500); Logger.error(e); }); } put(req, res) { UserSystem.role(req, res, this.roles[2]); let id = req.params.id; let body = {...req.body}; Actions.emit('post'+ this.name, body, req, res) .then((data) => { return this.clearObject(data) }) .then((data) => { return this._repository.update(id, body) }) .then((data) => { if(!data) throw 404; res.status(200).send(''+data); }) .catch((e) => { if(e === 404) { Logger.log("Not found"); return res.sendStatus(404); } Logger.error(e); }); } del(req, res) { UserSystem.role(req, res, this.roles[3]); let id = req.params.id; this._repository.delete(id) .then((data) => { if(!data.length) throw 404; res.send(data[0]); }) .catch((e) => { if(e === 404) { return res.sendStatus(404); } Logger.error(e); }); } clearObject(object) { return this._repository.columns().then((values) => { let fields = Object.keys(values); for(var i in object) { if(!fields.includes(i)) { delete object[i]; } } return object; }); } } module.exports = CrudModule;