summaryrefslogtreecommitdiffstats
path: root/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/handlers.js
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/handlers.js')
-rw-r--r--common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/handlers.js221
1 files changed, 221 insertions, 0 deletions
diff --git a/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/handlers.js b/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/handlers.js
new file mode 100644
index 0000000..8423310
--- /dev/null
+++ b/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/handlers.js
@@ -0,0 +1,221 @@
+var _ = require('underscore');
+
+/*
+ * The last handler to be called in the chain of middleware
+ * This figures out what response format it should be in and sends it
+ */
+exports.last = function(req, res, next) {
+ if (res.locals.bundle) {
+ if (req.body.format === 'js') {
+ return res.send(res.locals.bundle);
+ } else if (req.body.format === 'html' || req.query.format === 'html') {
+ return res.render(this.templateRoot + '/' + req.templatePath, res.locals.bundle);
+ } else {
+ return res.status(res.locals.status_code).json(res.locals.bundle);
+ }
+ }
+ res.send();
+};
+
+exports.schema = function(req, res, next) {
+ // We can mount a model to multiple apps, so we need to get the base url from the request url
+ var baseuri = req.url.split('/');
+ baseuri = baseuri.slice(0, baseuri.length - 1).join('/');
+ var detailuri = baseuri + '/:id';
+ exports.respond(res, 200, {
+ resource: this.modelName,
+ allowed_methods: Object.keys(this.allowed_methods),
+ list_uri: baseuri,
+ detail_uri: detailuri,
+ fields: keep(this.schema.paths, ['regExp', 'path', 'instance', 'isRequired'])
+ });
+ next();
+};
+
+exports.get = function(req, res, next) {
+ req.quer.exec(function(err, list) {
+ if (err) {
+ exports.respond(res, 500, err);
+ } else if (req.params.id) {
+ exports.respondOrErr(res, 404, !list && exports.objectNotFound(), 200, (list && _.isArray(list)) ? list[0] : list);
+ } else {
+ exports.respondOrErr(res, 500, err, 200, list);
+ }
+ next();
+ });
+};
+
+exports.getDetail = function(req, res, next) {
+ req.quer.exec(function(err, one) {
+ exports.respondOrErr(res, 500, err, 200, one);
+ next();
+ });
+};
+
+/**
+ * Generates a handler that returns the object at @param pathName
+ * where pathName is the path to an objectId field
+ */
+exports.getPath = function(pathName) {
+ return function(req, res, next) {
+ req.quer = req.quer.populate(pathName);
+ req.quer.exec(function(err, one) {
+ var errStatus = ((err && err.status) ? err.status : 500);
+ exports.respondOrErr(res, errStatus, err, 200, (one && one.get(pathName)) || {});
+ next();
+ });
+ };
+};
+
+exports.post = function(req, res, next) {
+ var obj = new this(req.body);
+ obj.save(function(err) {
+ exports.respondOrErr(res, 400, err, 201, obj);
+ next();
+ });
+};
+
+exports.put = function(req, res, next) {
+ // Remove immutable ObjectId from update attributes to prevent request failure
+ if (req.body._id && req.body._id === req.params.id) {
+ delete req.body._id;
+ }
+
+ // Update in 1 atomic operation on the database if not specified otherwise
+ if (this.shouldUseAtomicUpdate) {
+ req.quer.findOneAndUpdate({}, req.body, this.update_options, function(err, newObj) {
+ if (err) {
+ exports.respond(res, 500, err);
+ } else if (!newObj) {
+ exports.respond(res, 404, exports.objectNotFound());
+ } else {
+ exports.respond(res, 200, newObj);
+ }
+ next();
+ });
+ } else {
+ // Preform the update in two operations allowing mongoose to fire its schema update hook
+ req.quer.findOne({"_id": req.params.id}, function(err, docToUpdate) {
+ if (err) {
+ exports.respond(res, 500, err);
+ }
+ var objNotFound = !docToUpdate && exports.objectNotFound();
+ if (objNotFound) {
+ exports.respond(res, 404, objNotFound);
+ return next();
+ }
+
+ docToUpdate.set(req.body);
+ docToUpdate.save(function (err, obj) {
+ exports.respondOrErr(res, 400, err, 200, obj);
+ next();
+ });
+ });
+ }
+};
+
+exports.delete = function(req, res, next) {
+ // Delete in 1 atomic operation on the database if not specified otherwise
+ if (this.shouldUseAtomicUpdate) {
+ req.quer.findOneAndRemove({}, this.delete_options, function(err, obj) {
+ if (err) {
+ exports.respond(res, 500, err);
+ }
+ exports.respondOrErr(res, 404, !obj && exports.objectNotFound(), 204, {});
+ next();
+ });
+ } else {
+ // Preform the remove in two steps allowing mongoose to fire its schema update hook
+ req.quer.findOne({"_id": req.params.id}, function(err, docToRemove) {
+ if (err) {
+ exports.respond(res, 500, err);
+ }
+ var objNotFound = !docToRemove && exports.objectNotFound();
+ if (objNotFound) {
+ exports.respond(res, 404, objNotFound);
+ return next();
+ }
+
+ docToRemove.remove(function (err, obj) {
+ exports.respondOrErr(res, 400, err, 204, {});
+ next();
+ });
+ });
+ }
+};
+
+// I'm going to leave these here because it might be nice to have standardized
+// error messages for common failures
+
+exports.objectNotFound = function() {
+ return {
+ status: 404,
+ message: 'Object not found',
+ name: 'ObjectNotFound',
+ errors: {
+ _id: {
+ message: "Could not find object with specified attributes"
+ }
+ }
+ };
+};
+exports.respond404 = function() {
+ return {
+ status: 404,
+ message: 'Page Not Found',
+ name: "PageNotFound",
+ errors: 'Endpoint not found for model ' + this.modelName
+ };
+};
+exports.authFailure = function() {
+ return {
+ status: 401,
+ message: 'Unauthorized',
+ name: "Unauthorized",
+ errors: 'Operation not authorzed on ' + this.modelName
+ };
+};
+exports.badRequest = function(errobj) {
+ return {
+ status: 400,
+ message: 'Bad Request',
+ name: "BadRequest",
+ errors: errobj || "Your request was invalid"
+ };
+};
+
+/**
+ * Takes a response, error, success statusCode and success payload
+ *
+ * If there is an error, it returns a 400 with the error as the payload
+ * If there is no error, it returns statusCode with the specified payload
+ *
+ */
+exports.respondOrErr = function(res, errStatusCode, err, statusCode, content) {
+ if (err) {
+ exports.respond(res, errStatusCode, err);
+ } else {
+ exports.respond(res, statusCode, content);
+ }
+};
+
+exports.respond = function(res, statusCode, content) {
+ res.locals.status_code = statusCode;
+ res.locals.bundle = content;
+};
+
+function keep(obj, keepers) {
+ var result = {};
+ for (var key in obj) {
+ result[key] = {};
+ for (var key2 in obj[key]) {
+ if (keepers.indexOf(key2) > -1) {
+ result[key][key2] = obj[key][key2];
+ }
+ if ('schema' === key2) {
+ result[key][key2] = keep(obj[key][key2].paths, keepers);
+ }
+ }
+ }
+ return result;
+}