// # Ghost Data API // Provides access to the data model /** * This is intended to replace the old dataProvider files and should access & manipulate the models directly */ var Ghost = require('../ghost'), _ = require('underscore'), when = require('when'), errors = require('./errorHandling'), ghost = new Ghost(), dataProvider = ghost.dataProvider, posts, users, notifications, settings, requestHandler, cachedSettingsRequestHandler, settingsObject, settingsCollection; // # Posts posts = { // takes filter / pagination parameters // returns a page of posts in a json response browse: function browse(options) { return dataProvider.Post.findPage(options); }, // takes an identifier (id or slug?) // returns a single post in a json response read: function read(args) { return dataProvider.Post.findOne(args); }, // takes a json object with all the properties which should be updated // returns the resulting post in a json response edit: function edit(postData) { return dataProvider.Post.edit(postData); }, // takes a json object representing a post, // returns the resulting post in a json response add: function add(postData) { return dataProvider.Post.add(postData); }, // takes an identifier (id or slug?) // returns a json response with the id of the deleted post destroy: function destroy(args) { return dataProvider.Post.destroy(args.id); } }; // # Users users = { browse: function browse(options) { return dataProvider.User.browse(options); }, read: function read(args) { return dataProvider.User.read(args); }, edit: function edit(postData) { return dataProvider.User.edit(postData); }, add: function add(postData) { return dataProvider.User.add(postData); }, check: function check(postData) { return dataProvider.User.check(postData); }, changePassword: function changePassword(postData) { return dataProvider.User.changePassword(postData); } }; // # Notifications notifications = { destroy: function destroy(i) { ghost.notifications = _.reject(ghost.notifications, function (element) { return element.id === i.id; }); return when(ghost.notifications); }, add: function add(notification) { return when(ghost.notifications.push(notification)); } }; // # Settings // Turn a settings collection into a single object/hashmap settingsObject = function (settings) { return (settings.toJSON ? settings.toJSON() : settings).reduce(function (res, item) { if (item.toJSON) { item = item.toJSON(); } if (item.key) { res[item.key] = item.value; } return res; }, {}); }; // Turn an object into a collection settingsCollection = function (settings) { return _.map(settings, function (value, key) { return { key: key, value: value }; }); }; settings = { browse: function browse(options) { return dataProvider.Settings.browse(options).then(settingsObject, errors.logAndThrowError); }, read: function read(options) { if (_.isString(options)) { options = { key: options }; } return dataProvider.Settings.read(options.key).then(function (setting) { if (!setting) { return when.reject("Unable to find setting: " + options.key); } return _.pick(setting.toJSON(), 'key', 'value'); }, errors.logAndThrowError); }, edit: function edit(key, value) { // Check for passing a collection of settings first if (_.isObject(key)) { key = settingsCollection(key); return dataProvider.Settings.edit(key).then(settingsObject, errors.logAndThrowError); } return dataProvider.Settings.read(key).then(function (setting) { if (!setting) { return when.reject("Unable to find setting: " + key); } if (!_.isString(value)) { value = JSON.stringify(value); } setting.set('value', value); return dataProvider.Settings.edit(setting); }, errors.logAndThrowError); } }; // categories: {}; // post_categories: {}; // requestHandler // decorator for api functions which are called via an HTTP request // takes the API method and wraps it so that it gets data from the request and returns a sensible JSON response requestHandler = function (apiMethod) { return function (req, res) { var options = _.extend(req.body, req.query, req.params); return apiMethod(options).then(function (result) { res.json(result || {}); }, function (error) { res.json(400, {error: error}); }); }; }; cachedSettingsRequestHandler = function (apiMethod) { if (!ghost.settings()) { return requestHandler(apiMethod); } return function (req, res) { var options = _.extend(req.body, req.query, req.params), promise; switch (apiMethod.name) { case 'browse': promise = when(ghost.settings()); break; case 'read': promise = when(ghost.settings()[options.key]); break; case 'edit': promise = apiMethod(options).then(function (result) { ghost.updateSettingsCache(result); return result; }); break; default: errors.logAndThrowError(new Error('Unknown method name for settings API: ' + apiMethod.name)); } return promise.then(function (result) { res.json(result || {}); }, function (error) { res.json(400, {error: error}); }); }; }; module.exports.posts = posts; module.exports.users = users; module.exports.notifications = notifications; module.exports.settings = settings; module.exports.requestHandler = requestHandler; module.exports.cachedSettingsRequestHandler = cachedSettingsRequestHandler;