/** @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'); function findAndRender(filter, req, res) { catchErrs(Favorite.find(filter), res).then(favs => { renderFav(req, res, favs); }); } router.post('/', (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(); } catchErrs(favourite.save(), res).then(fav => { res.status = 201; renderFav(req, res, fav, false); }); }); router.get('/', (req, res) => { findAndRender({}, req, res); }); router.get('/search', (req, res) => { const filter = Object.assign({}, req.query); delete filter['dataURL']; delete filter['_method']; findAndRender(filter, req, res); }); function findOne(id) { return (req, res) => { catchErrs(Favorite.findById(id(req)), res).then(fav => { if (notFound(fav, res)) { return; } renderFav(req, res, fav, false); }); }; } router.get('/:id', findOne(req => parseId(req))); function handleUpdate(partial = false) { return (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; } catchErrs(Favorite.findByIdAndUpdate(parseId(req), { $set: edit }, { new: false, upsert: true, setDefaultsOnInsert: true, }), res).then(fav => { if (fav == null) { res.status = 201; findOne(() => parseId(req))(req, res); return; } res.status = 200; renderFav(req, res, fav, false); }); }; } router.put('/:id', handleUpdate()); router.patch('/:id', handleUpdate(true)); router.delete('/:id', (req, res) => { catchErrs(Favorite.findByIdAndDelete(parseId(req)), res).then(fav => { if (notFound(fav, res)) { return; } res.format({ json: () => res.writeHead(204), html: () => res.writeHead(302, { 'Location': '/favorites' }) }); res.end(); }); }); router.put('/:id/bookmarked', (req, res) => { catchErrs(Favorite.findByIdAndUpdate(parseId(req), { $set: { bookmarked: req.body.bookmarked } }, { new: true }), res).then(fav => { 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); } }); }); /** router for /root */ module.exports = router;