summaryrefslogtreecommitdiffstats
path: root/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/model.js
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/model.js')
-rw-r--r--common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/model.js479
1 files changed, 0 insertions, 479 deletions
diff --git a/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/model.js b/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/model.js
deleted file mode 100644
index 1531498..0000000
--- a/common/src/main/webapp/usageguide/appserver/node_modules/node-restful/lib/model.js
+++ /dev/null
@@ -1,479 +0,0 @@
-var mongoose = require('mongoose'),
- _ = require('underscore'),
- Model = mongoose.Model,
- handlers = require('./handlers');
-
-exports = module.exports = model;
-
-var methods = ['get', 'post', 'put', 'delete'], // All HTTP methods, PATCH not currently supported
- endpoints = ['get', 'post', 'put', 'delete', 'getDetail'],
- defaultroutes = ['schema'],
- lookup = {
- 'get': 'index',
- 'getDetail': 'show',
- 'put': 'updated',
- 'post': 'created',
- 'delete': 'deleted'
- },
- valid_alterables = filterable({
- 'populate': query('populate'),
- }, {});
- valid_filters = filterable({
- 'limit': query('limit'),
- 'skip': query('skip'),
- 'offset': query('offset'),
- 'select': query('select'),
- 'sort': query('sort'),
- }, {
- 'equals': query('equals'),
- 'gte': query('gte'),
- 'gt': query('gt'),
- 'lt': query('lt'),
- 'lte': query('lte'),
- 'ne': query('ne'),
- 'regex': function(val, query) {
- var regParts = val.match(/^\/(.*?)\/([gim]*)$/);
- if (regParts) {
- // the parsed pattern had delimiters and modifiers. handle them.
- val = new RegExp(regParts[1], regParts[2]);
- } else {
- // we got pattern string without delimiters
- val = new RegExp(val);
- }
-
- return query.regex(val);
- },
- 'in': query('in'),
- 'nin': query('nin'),
- });
- defaults = function() {
- return {
- routes: {},
- allowed_methods: {
- get: { detail: false }
- },
- update_options: {},
- remove_options: {},
- templateRoot: '',
- shouldIncludeSchema: true,
- shouldUseAtomicUpdate: true
- };
- };
-
-/**
- * Returns the model associated with the given name or
- * registers the model with mongoose
- */
-function model() {
- var result = mongoose.model.apply(mongoose, arguments),
- default_properties = defaults();
- if (1 === arguments.length) return result;
-
- for (var key in default_properties) {
- result[key] = default_properties[key];
- }
-
- return result;
-}
-
-Model.includeSchema = function(shouldIncludeSchema) {
- this.shouldIncludeSchema = shouldIncludeSchema;
- return this;
-};
-
-Model.methods = function(newmethods) {
- var self = this,
- get = contains(newmethods, 'get');
-
- methods.forEach(function(method) {
- delete self.routes[method];
- });
-
- this.allowed_methods = [];
- if (!Array.isArray(newmethods)) {
- newmethods = [newmethods];
- }
- if (get && !contains(newmethods, 'getDetail')) {
- newmethods.push({
- method: 'getDetail',
- before: (typeof get !== 'string') ? get.before : null,
- after: (typeof get !== 'string') ? get.after : null
- });
- }
- newmethods.forEach(function(meth) {
- var method = meth.method;
- if ('string' === typeof meth) {
- method = meth;
- meth = {};
- }
- if (!method) throw new Error("Method object must have a method property");
- self.allowed_methods.push(method);
-
- meth.handler = handlers[method];
- meth.detail = (method !== 'get' && method !== 'post');
- self.route(method, meth);
- });
- return this;
-};
-
-Model.updateOptions = function(options) {
- this['update_options'] = options;
- return this;
-};
-
-Model.removeOptions = function(options) {
- this['remove_options'] = options;
- return this;
-};
-
-Model.template = function(templatePath) {
- if (templatePath.substr(-1) == '/') {
- templatePath = templatePath.substr(0, templatePath.length - 1);
- }
- this.templateRoot = templatePath;
- return this;
-};
-
-/**
- * Adds the default routes for the HTTP methods and one to get the schema
- */
-Model.addDefaultRoutes = function() {
- if (this.shouldIncludeSchema) {
- this.route('schema', handlers.schema);
- }
- this.addSchemaRoutes();
-};
-
-Model.addSchemaRoutes = function() {
- var self = this;
- this.schema.eachPath(function(pathName, schemaType) {
- if (pathName.indexOf('_id') === -1 && schemaType.instance === 'ObjectID') {
- // Right now, getting nested models is the only operation supported
- ['get'].forEach(function(method) {
- self.route(pathName, method , {
- handler: handlers[method + 'Path'].call(self, pathName),
- detail: true
- });
- });
- }
- });
-};
-
-/**
- * Adds an internal route for a path and method or methods to a function
- *
- * @param {String|Object} path: absolute path (including method) or object of routes
- * @param {String|Function} method: the method to route to or the handler function
- * @param {Function} fn: The handler function
- * @return {Model} for chaining
- * @api public
- */
-Model.route = function(path, method, fn) {
- var route = getRoute(this.routes, path),
- meths = methods, // Default to all methods
- lastPath = path.substr(path.lastIndexOf('.') + 1);
-
- if (2 === arguments.length) {
- fn = method;
- if (!fn.methods && endpoints.indexOf(lastPath) > -1) {
- meths = [lastPath];
- } else if (fn.methods) {
- meths = fn.methods;
- }
- } else {
- meths = [method];
- }
-
- if (fn) {
- fn = normalizeHandler(fn);
-
- meths.forEach(function(meth) {
- route[meth] = merge(route[meth], fn);
- });
- }
- return this;
-};
-
-Model.before = function(path, method, fn) {
- if (2 == arguments.length) {
- arguments[1] = { before: arguments[1] };
- }
- return this.route.apply(this, arguments);
-};
-
-Model.after = function(path, method, fn) {
- if (2 == arguments.length) {
- arguments[1] = { after: arguments[1] };
- }
- return this.route.apply(this, arguments);
-};
-
-/**
- * Registers all of the routes in routeObj to the given app
- *
- * TODO(baugarten): refactor to make less ugly
- *
- * if (isEndpoint(routeObj, path)) { handleRegistration(app, prefix, path, routeObj); }
- * else {
- * for (var key in routeObj) { recurse }
- * }
- */
-Model.registerRoutes = function(app, prefix, path, routeObj) {
- var self = this;
- for (var key in routeObj) {
- if (isEndpoint(routeObj, key)) {
- var route = routeObj[key];
- var routehandlers = _.isArray(route.handler) ? route.handler : [route.handler];
- routehandlers = _.map(routehandlers, function(handler) { return handler.bind(self); });
- var detailGet = !route.detail && !path && key === 'get',
- handlerlist = route.before.concat(
- [preprocess.bind(self)],
- routehandlers,
- route.after,
- [handlers.last]
- );
- /**
- * TODO(baugarten): Add an enum type-thing to specify detail route, detail optional or list
- * aka prettify this
- */
- if (route.detail) {
- app[key](prefix + '/:id([0-9a-fA-F]{0,24})' + path , handlerlist);
- } else if (detailGet) {
- app[key](prefix + '/:id([0-9a-fA-F]{0,24}$)?', handlerlist);
- } else {
- app[key](prefix + path, handlerlist);
- }
- } else {
- this.registerRoutes(app, prefix, path + '/' + key, routeObj[key]);
- }
- }
-};
-
-/**
- * Registers this model to the given app
- *
- * This includes registering endpoints for all the methods desired
- * in the model definition
- *
- */
-Model.register = function(app, url) {
- this.addDefaultRoutes();
- app.getDetail = app.get;
- this.registerRoutes(app, url, '', this.routes);
-};
-
-// Will I still support handle()? I think maybe for default routes it might be nice, but
-// exposed via model.get, model.post, etc.
-/*Model.prototype.handle = function(route, filters, data, callback) {
- if (arguments.length === 3) {
- callback = data;
- data = {};
- } else if (arguments.length === 2) {
- callback = filters;
- filters = [];
- data = {};
- }
- route = route.replace(/\//g, /\./);
- data.format = 'js';
- var req = {
- url: route,
- filters: filters,
- body: data,
- format: 'js',
- }
- var res = {
- writeHeader: function() { },
- write: function(ret) { callback(ret); },
- send: function() {},
- };
- this.send(route.split(/\./), req, res);
-}
-
-Model.prototype.send = function(routes, req, res, next) {
- var handler = this.routes;
- req.quer = this.filter(req.filters, req.body, req.query, this.Model.find({}));
- req.templatePath = this.template(routes, req.filters);
- routes.forEach(function(route) {
- if (route in handler) handler = handler[route];
- else if (!('all' in handler)) {
- handlers.respond(res, 404, handlers.respond404());
- handlers.last(req, res);
- }
- });
- if ('all' in handler) handler = handler.all;
-
- if ('function' === typeof handler) {
- return handler.call(this, req, res, next);
- }
-
- handlers.respond(res, 404, handlers.respond404());
- handlers.last(req, res);
-}*/
-
-/**
- * Returns a query filtered by the data in the request
- * Looks in req.body and req.query to get the filterable data
- * Filters the query based on functions in valid_filters
- */
-Model.filter = function(req, quer) {
- var detail = false; // detail route
- // filter by id
- if (req.params.id) {
- quer = this.findById(req.params.id);
- detail = true
- }
-
- [req.body, req.query, req.headers].forEach(function(alterableResponse) {
- Object.keys(alterableResponse).filter(function(potential) {
- return valid_alterables.contains(potential, quer);
- }).forEach(function(valid_key) {
- query = valid_alterables.filter(valid_key, alterableResponse[valid_key], quer);
- });
- });
-
- if (!detail) {
- [req.body, req.query, req.headers].forEach(function(filterableData) {
- Object.keys(filterableData).filter(function(potential_filter) {
- return valid_filters.contains(potential_filter, quer);
- }).forEach(function(valid_key) {
- quer = valid_filters.filter(valid_key, filterableData[valid_key], quer);
- });
- });
- }
- return quer;
-}
-
-function preprocess(req, res, next) {
- req.body = req.body || {};
- req.query = req.query || {};
- req.quer = this.filter(req, this.find({}));
- if (!('locals' in res)) {
- res.locals = {};
- }
- res.locals.bundle = {};
-
- req.templatePath = resolveTemplate(req);
- next();
-}
-
-function query(key) {
- return function(val, query) {
- return query[key](val);
- };
-}
-
-function haveOneModel(req) {
- return !!req.params.id;
-}
-
-function resolveTemplate(req) {
- var method = req.method.toLowerCase(),
- tmplName;
- if (methods.indexOf(method) > -1) {
- if (haveOneModel(req) && method === 'get') {
- method += 'Detail';
- }
- tmplName = lookup[method];
- }
- return tmplName;
-}
-
-/**
- * Merges a route with another function object
- * fn.before is called after the old before
- * fn.after is called before the old after
- * If fn.handler is specified, then route.handler is overwritten
- */
-function merge(route, fn) {
- if (!route) return fn;
-
- route.before = route.before.concat(fn.before);
- route.handler = fn.handler || route.handler;
- route.after = fn.after.concat(route.after);
- return route;
-}
-
-function getRoute(routes, path) {
- path = path.replace(/\//g, /\./).split(/\./);
- if (1 === path.length && '' === path[0]) { // we got the empty string
- path = [];
- }
- if (endpoints.indexOf(path[path.length - 1]) > -1) {
- path.splice(path.length - 1, 1);
- }
- path.forEach(function(sub, i) {
- if (!routes[sub]) routes[sub] = {};
- routes = routes[sub];
- });
- return routes;
-}
-
-function normalizeHandler(fn) {
- var result = {};
- result.handler = fn.handler;
- result.detail = fn.detail;
- if ({}.toString.call(fn) == '[object Function]') {
- result = {
- handler: fn
- };
- }
- ['before', 'after'].forEach(function(hook) {
- result[hook] = fn[hook] || [];
- if (!Array.isArray(result[hook])) {
- result[hook] = [ result[hook] ];
- }
- });
- return result;
-}
-
-function isEndpoint(route, method) {
- return endpoints.indexOf(method) > -1 && route[method].handler;
-}
-
-function contains(arr, key) {
- if (arr.indexOf(key) > -1) return true;
- for (var obj in arr) {
- if (obj.method === key) {
- return true;
- }
- }
- return false;
-};
-
-function coerceData(filter_func, data) {
- // Assume data is a string
- if (data && data.toLowerCase && data.toLowerCase() === 'true') {
- return true;
- } else if (data && data.toLowerCase && data.toLowerCase() === 'false') {
- return false;
- } else if (filter_func === 'limit' || filter_func === 'skip') {
- return parseInt(data);
- }
- return data;
-};
-
-function filterable(props, subfilters) {
- return {
- filter: function(key, val, quer) {
- if (props[key]) {
- return props[key](val, quer);
- }
- var field = key.split('__'),
- filter_func = field[1] || 'equals',
- data = coerceData(filter_func, val);
-
- // Turn data into array for $in and $nin clause
- if (filter_func === 'in' || filter_func === 'nin') {
- data = data.split(',');
- }
-
- return subfilters[filter_func](data, quer.where(field[0]));
- },
- contains: function(key, quer) {
- if (key in props) return true;
- var field = key.split('__');
- var filter_func = field[1] || 'equals';
- return field[0] in quer.model.schema.paths && filter_func in subfilters;
- }
- }
-}