/** @module root/router */ 'use strict'; // vim: set ts=2 sw=2 et tw=80: const fs = require('fs'); const express = require('express'); const router = express.Router(); const mongoose = require('mongoose'); const Favorite = mongoose.model('Favorite'); const { error, catchErrs, renderFav, parseId, notFound } = require('../utils'); async function findAndRender(filter, req, res) { try { const favs = await Favorite.find(filter); renderFav(req, res, favs); } catch(e) { error(e, res); } } router.post('/', async (req, res) => { if (!req.body.name || !req.body.dataURL) { res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end('Bad create form parameters'); return; } const data = { name: req.body.name, dataURL: req.body.dataURL, bookmarked: req.body.bookmarked, }; const favourite = new Favorite(data); if (req.body._id) { favourite._id = req.body._id; } else { favourite._id = mongoose.Types.ObjectId(); } try { const fav = await favourite.save(); res.status = 201; renderFav(req, res, fav, false); } catch(e) { error(e, res); } }); router.get('/', async (req, res) => { await findAndRender({}, req, res); }); router.get('/search', async (req, res) => { const filter = Object.assign({}, req.query); delete filter['dataURL']; delete filter['_method']; await findAndRender(filter, req, res); }); function findOne(id) { return async (req, res) => { try { const fav = await Favorite.findById(id(req)); if (notFound(fav, res)) { return; } renderFav(req, res, fav, false); } catch(e) { error(e, res); } }; } router.get('/:id', findOne(req => parseId(req))); function handleUpdate(partial = false) { return async (req, res) => { const edit = {}; for (const key of ['dataURL', 'name']) { if (req.body[key]) { edit[key] = req.body[key]; } else if (!partial) { res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end('Bad PUT form parameters'); return; } } if (req.body.bookmarked !== undefined) { edit.bookmarked = req.body.bookmarked; } try { const fav = await Favorite.findByIdAndUpdate(parseId(req), { $set: edit }, { new: false, upsert: true, setDefaultsOnInsert: true, }); if (fav == null) { res.status = 201; await findOne(() => parseId(req))(req, res); return; } res.status = 200; renderFav(req, res, fav, false); } catch (e) { error(e, res); } }; } router.put('/:id', handleUpdate()); router.patch('/:id', handleUpdate(true)); router.delete('/:id', async (req, res) => { try { const fav = await Favorite.findByIdAndDelete(parseId(req)); if (notFound(fav, res)) { return; } res.format({ json: () => res.writeHead(204), html: () => res.writeHead(302, { 'Location': '/favorites' }) }); res.end(); } catch (e) { error(e, res); } }); router.put('/:id/bookmarked', (req, res) => { try { const fav = Favorite.findByIdAndUpdate(parseId(req), { $set: { bookmarked: req.body.bookmarked } }, { new: true }); if (notFound(fav, res)) { return; } if (!req.body.bookmarked) { res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end('Bad PUT bookmark form parameters'); } else { renderFav(req, res, fav, false); } } catch (e) { error(e, res); } }); /** router for /root */ module.exports = router;