const bodyParser = require(`body-parser`); const CustomErrors = require(`./utilities/errors.JS`); const Messaging = require(`./utilities/messaging.JS`); class DBManagement {}; DBManagement.Activities = require(`./database/management/management_activity.JS`); DBManagement.Users = require(`./database/management/management_user.JS`); class ResponseGenerator {}; ResponseGenerator.Activities = require(`./response/activity.JS`); ResponseGenerator.Users = require(`./response/user.JS`); ResponseGenerator.Log = require(`./response/log.JS`); class ExerciseTrackerAPI { #paths = { "users": ["users"], "exercises": ["users/:ID/exercises"], "logs": ["users/:ID/logs"] } constructor(INSTANCE) { this[`instance`] = INSTANCE; this[`instance`].use(bodyParser.json()); this[`instance`].use(bodyParser.urlencoded({extended: true})); const init_management = () => { this[`management`] = {}; Object.keys(DBManagement).forEach((DATABASE) => { this.management[DATABASE] = new DBManagement[DATABASE](); }); this.manageUsers(); this.manageActivities(); }; init_management(); } /* Manage the activities. */ manageActivities () { /* Create the new activities. */ const activity_creation = async (REQUEST, RESPONSE) => { try { if (((REQUEST.body) ? Object.keys(REQUEST.body).length : false) ? Object.keys(REQUEST.params).includes(`ID`) : false) { let CORRESPONDING_USERS = await this.management[`Users`].search({"ID": REQUEST.params[`ID`]}); if (!CORRESPONDING_USERS.length || !CORRESPONDING_USERS) { throw new CustomErrors.Data.Incorrect(REQUEST.body); }; let RESULT = await this.management[`Activities`].create(Object.assign({}, REQUEST.body, {"username": CORRESPONDING_USERS[0].name})); let FORMATTED = new ResponseGenerator.Activities(Object.assign({},RESULT, {"ID": REQUEST.params[`ID`]})); FORMATTED[`data`][`date`] = FORMATTED.convert_date(); FORMATTED = FORMATTED.format(); RESPONSE.send(FORMATTED); } else { throw new CustomErrors.Data.Missing(REQUEST.body); } } catch(ERR) { Messaging.exception(RESPONSE, ERR); } } /* Display a log of activities. */ const activity_log = async (REQUEST, RESPONSE) => { const find_users = async () => { let USERS = await this.management[`Users`].search({"ID": REQUEST.params[`ID`]}); if (!USERS.length || !USERS) { throw new CustomErrors.Data.Incorrect(REQUEST.params); }; return (USERS) } const find_activities = async (USERNAME, CRITERIA) => { let FILTER = {}; if (CRITERIA[`from`] || CRITERIA[`to`]) { [`from`, `to`].forEach((KEY) => { if (CRITERIA[KEY]) {CRITERIA[KEY] = (new Date(CRITERIA[KEY])).getTime();}; }) FILTER[`date`] = {}; if (CRITERIA[`from`]) {FILTER[`date`][`$gte`] = CRITERIA[`from`]}; if (CRITERIA[`to`]) {FILTER[`date`][`$lte`] = CRITERIA[`to`]}; } let RESULT = await this.management[`Activities`].search_User(USERNAME, FILTER, (CRITERIA[`limit`] ? CRITERIA[`limit`] : 0)); return (RESULT); } try { let USERS = await find_users(); let LOG = Object.assign({}, await find_activities(USERS[0].name, (((REQUEST.query) ? Object.keys(REQUEST.query).length : false) || ((REQUEST.body) ? Object.keys(REQUEST.body).length : false)) ? (((REQUEST.body) ? Object.keys(REQUEST.body).length : false) ? REQUEST.body : REQUEST.query) : {}), {"ID": REQUEST.params[`ID`]}); let FORMATTED = (new ResponseGenerator.Log(LOG)).format(); RESPONSE.send(FORMATTED); } catch(ERR) { Messaging.exception(RESPONSE, ERR); } } this.#paths[`exercises`].forEach((PATH) => { this[`instance`].post(`/api/${PATH}`, activity_creation) console.log(`Activity creation is ready on ${PATH}.`); }); this.#paths[`logs`].forEach((PATH) => { this[`instance`].get(`/api/${PATH}`, activity_log); console.log(`Activity log generation is ready on ${PATH}.`); }); } /* Manage the users. */ manageUsers () { /* Create new users. */ const users_creation = async (REQUEST, RESPONSE) => { try { if (((REQUEST.body) ? Object.keys(REQUEST.body).length : false) ? Object.keys(REQUEST.body).includes(`username`) : false) { this.management[`Users`].create(REQUEST.body[`username`]).then((RESULT) => { let FORMATTED = (new ResponseGenerator.Users(RESULT)).format(); RESPONSE.send(FORMATTED); }) } else { throw new CustomErrors.Data.Missing(REQUEST.body); } } catch(ERR) { Messaging.exception(RESPONSE, ERR); } } /* Search for all users. */ const users_display = (REQUEST, RESPONSE) => { try { let CRITERIA = (((REQUEST.query) ? Object.keys(REQUEST.query).length : false) || ((REQUEST.body) ? Object.keys(REQUEST.body).length : false)) ? (((REQUEST.body) ? Object.keys(REQUEST.body).length : false) ? REQUEST.body : REQUEST.query) : {}; this.management[`Users`].search(CRITERIA).then((RESULT) => { let FORMATTED = (new ResponseGenerator.Users(RESULT)).format(); RESPONSE.send(FORMATTED); }) } catch(ERR) { Messaging.exception(RESPONSE, ERR); } } this.#paths[`users`].forEach((PATH) => { this[`instance`].get(`/api/${PATH}`, users_display) console.log(`User search is ready on ${PATH}.`); }); this.#paths[`users`].forEach((PATH) => { this[`instance`].post(`/api/${PATH}`, users_creation) console.log(`User creation is ready on ${PATH}.`); }); } } module.exports = ExerciseTrackerAPI;