UNPKG

keystone

Version:

Web Application Framework and Admin GUI / Content Management System built on Express.js and Mongoose

119 lines (101 loc) 3.29 kB
var _ = require('lodash'); var async = require('async'); var listToArray = require('list-to-array'); module.exports = function (req, res) { var keystone = req.keystone; var query = req.list.model.findById(req.params.id); var fields = req.query.fields; if (fields === 'false') { fields = false; } if (typeof fields === 'string') { fields = listToArray(fields); } if (fields && !Array.isArray(fields)) { return res.status(401).json({ error: 'fields must be undefined, a string, or an array' }); } query.exec(function (err, item) { if (err) return res.status(500).json({ err: 'database error', detail: err }); if (!item) return res.status(404).json({ err: 'not found', id: req.params.id }); var tasks = []; var drilldown; /* Drilldown (optional, provided if ?drilldown=true in querystring) */ if (req.query.drilldown === 'true' && req.list.get('drilldown')) { drilldown = { def: req.list.get('drilldown'), items: [], }; tasks.push(function (cb) { // TODO: proper support for nested relationships in drilldown // step back through the drilldown list and load in reverse order to support nested relationships drilldown.def = drilldown.def.split(' ').reverse(); async.eachSeries(drilldown.def, function (path, done) { var field = req.list.fields[path]; if (!field || field.type !== 'relationship') { throw new Error('Drilldown for ' + req.list.key + ' is invalid: field at path ' + path + ' is not a relationship.'); } var refList = field.refList; if (field.many) { if (!item.get(field.path).length) { return done(); } refList.model.find().where('_id').in(item.get(field.path)).limit(4).exec(function (err, results) { if (err || !results) { done(err); } var more = (results.length === 4) ? results.pop() : false; if (results.length) { // drilldown.data[path] = results; drilldown.items.push({ list: refList.getOptions(), items: _.map(results, function (i) { return { label: refList.getDocumentName(i), href: '/' + keystone.get('admin path') + '/' + refList.path + '/' + i.id, }; }), more: (more) ? true : false, }); } done(); }); } else { if (!item.get(field.path)) { return done(); } refList.model.findById(item.get(field.path)).exec(function (err, result) { if (result) { // drilldown.data[path] = result; drilldown.items.push({ list: refList.getOptions(), items: [{ label: refList.getDocumentName(result), href: '/' + keystone.get('admin path') + '/' + refList.path + '/' + result.id, }], }); } done(err); }); } }, function (err) { // put the drilldown list back in the right order drilldown.def.reverse(); drilldown.items.reverse(); cb(err); }); }); } /* Process tasks & return */ async.parallel(tasks, function (err) { if (err) { return res.status(500).json({ err: 'database error', detail: err, }); } res.json(_.assign(req.list.getData(item, fields), { drilldown: drilldown, })); }); }); };