/** @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, renderFav, parseId, notFound } = require('../utils'); function findAndRender(filter, req, res) { Favorite.find(filter, (err, favs) => { if (err) { return error(err, res); } 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(); } favourite.save((err, fav) => { if (err) { return error(err, res); } 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) => { Favorite.findById(id(req), (err, fav) => { if (err) { return error(err, res); } 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; } Favorite.findByIdAndUpdate(parseId(req), { $set: edit }, { new: false, upsert: true, setDefaultsOnInsert: true, passRawResult: true, }, (err, fav) => { if (err) { return error(err, res); } 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) => { Favorite.findByIdAndDelete(parseId(req), (err, fav) => { if (err) { return error(err, res); } 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) => { Favorite.findByIdAndUpdate(parseId(req), { $set: { bookmarked: req.body.bookmarked } }, { new: true }, (err, 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;