const express = require('express'); const paginate = require('express-paginate'); const Database = require('./db_interface.js'); const User = require('./user.js'); const { Op } = require('sequelize'); let router = express.Router(); router.use(express.json()); function map_todo(result) { return { id: result.id, content: result.content, tags: result.tags }; } function parse_tags(tags) { result = { complete: undefined, required: [], excluded: [] }; tags.map((tag) => { if (tag === 'complete') { complete = true; } else if (tag === '~complete') { complete = false; } else if (tag.startsWith('~')) { excluded.push(tag); } else { required.push(tag); } }); return result; } const todo_fields = ['currentPage', 'limit']; router.use(paginate.middleware(10, 50)); router.use('/todos', User.enforce_session_login); router.get('/todos', async (req, res) => { if (!req.query) { return res.status(400).json({ error: `query must include the fields: ${todo_fields.join(', ')}}` }); } else { let error = []; for (let field of todo_fields) { if (!req.query[field]) { error.push(field); } } if (error.length > 0) { return res.status(400).json({ error: `query must include the fields: ${error.join(', ')}}` }); } } let tag_options = {}; if (req.query.tags) { let parsed = parse_tags(req.query.tags.split(',')); tag_options['tags'] = { [Op.and]: parsed.required, [Op.not]: parsed.excluded }; if (parsed.complete !== undefined) { tag_options['complete'] = { [Op.is]: parsed.complete }; } } console.log(tag_options); let all_todos = await Database.schemas.todo.findAndCountAll({ where: { user: req.get('id'), ...tag_options }, limit: req.query.limit, offset: req.skip }); const item_count = all_todos.count; const page_count = Math.ceil(item_count / req.query.limit); res.json({ result: all_todos.map(map_todo), currentPage: req.query.currentPage, pageCount: page_count, itemCount: item_count, pages: paginate.getArrayPages(req)(5, page_count, req.query.currentPage) }); }); router.use('/todo', User.enforce_session_login); router.get('/todo/:id([a-f0-9-]+)', async (req, res) => { let userid = req.get('id'); let id = req.params?.id; let match = await Database.schemas.todo.findOne({ where: { user: userid, id: id } }); if (!match) { return res.sendStatus(404); } return res.json({ result: map_todo(match), tags: get_tags(match.id) }); }); router.use('/todo', User.enforce_session_login); router.post('/todo/:id([a-f0-9-]+)', async (req, res) => { let userid = req.get('id'); let id = req.params?.id; let body = req.body; if (!body) { return res.sendStatus(400); } let match = await Database.schemas.todo.findOne({ where: { user: userid, id: id } }); if (!match) { return res.sendStatus(404); } // return res.json({ result: map_todo(match), tags: get_tags(match.id) }); }); module.exports = { router: router };