summaryrefslogtreecommitdiff
path: root/app/node_modules/okview/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/node_modules/okview/index.js')
-rw-r--r--app/node_modules/okview/index.js90
1 files changed, 75 insertions, 15 deletions
diff --git a/app/node_modules/okview/index.js b/app/node_modules/okview/index.js
index 1ceac03..c245b0c 100644
--- a/app/node_modules/okview/index.js
+++ b/app/node_modules/okview/index.js
@@ -1,4 +1,8 @@
-var fetchTemplateData = require('okutil').fetchTemplateData;
+var assign = require('object-assign');
+var pluralize = require('pluralize');
+var isarray = require('lodash.isarray');
+var Q = require('q');
+var OKQuery = require('okquery');
var OKResource = require('okresource');
// Routes for views over collections have a special pattern
@@ -15,11 +19,11 @@ function OKView(options) {
if (!(this instanceof OKView)) return new OKView(options);
options = options || {};
if (!options.template)
- throw new Error('No template provided to view.');
+ throw new Error('No template provided to OKView.');
if (!options.meta)
- throw new Error('No meta resource provided to view');
+ throw new Error('No meta resource provided to OKView');
if (!options.route)
- throw new Error('No route provided to view');
+ throw new Error('No route provided to OKView');
var route = options.route;
var mount = options.mount || 'get';
this._template = options.template;
@@ -29,28 +33,32 @@ function OKView(options) {
// resource will be resolved later
// TODO This bound / unbound thing can probably be expressed in a
// less convoluted way.
- var unbound = this.unbound = !!UNBOUND_ROUTE_PATTERN.exec(this.route);
+ var unbound = this.unbound = !!UNBOUND_ROUTE_PATTERN.exec(route);
+
Object.defineProperty(this, 'mount', {
value: mount,
writable: false,
enumerable: true
});
+
Object.defineProperty(this, 'route', {
value: route,
writable: false,
enumerable: true
});
+
this._middleware = createMiddleware(this);
- this._fetchTemplateData = unbound ?
- fetchResourceTemplateData : fetchCollectionTemplateData;
+ this._fetchTemplateData = unbound ? fetchUnbound : fetchBound;
- function fetchResourceTemplateData(id) {
- // Bound views only have a single query
- // TODO This is super convoluted
- return fetchTemplateData(meta, [queries[0].get(id)]);
+ function fetchUnbound(id) {
+ var resource = queries[0].resource;
+ return fetchTemplateData(meta, [OKQuery({
+ resource: resource,
+ query: id
+ })]);
}
- function fetchCollectionTemplateData() {
+ function fetchBound() {
return fetchTemplateData(meta, queries);
}
}
@@ -62,7 +70,7 @@ OKView.prototype.middleware = function() {
OKView.prototype.render = function(req, res, data) {
this._template.render(data).then(function(html) {
res.send(html);
- }, errorHandler(req, res, data));
+ }).fail(errorHandler(req, res, data));
};
OKView.prototype.fetchTemplateData = function() {
@@ -94,7 +102,7 @@ function unboundMiddleware(view) {
var id = req.params[paramName];
view.fetchTemplateData(id).then(function(data) {
view.render(req, res, data);
- }, errorHandler(req, res, next));
+ }).fail(errorHandler(req, res, next));
};
}
@@ -106,7 +114,7 @@ function boundMiddleware(view) {
return function(req, res, next) {
view.fetchTemplateData().then(function(data) {
view.render(req, res, data);
- }, errorHandler(req, res, next));
+ }).fail(errorHandler(req, res, next));
};
}
@@ -129,4 +137,56 @@ function getParamName(route) {
return matches[1];
}
+/**
+ * Takes a meta data query and an array of resource queries
+ * and returns a promise for an object merging all queried
+ * data, pluralizing keys where necessary.
+ *
+ * Lil bit convoluted, sorry.
+ */
+function fetchTemplateData(meta, queries) {
+ return Q.promise(function(resolve, reject) {
+ return Q.all(
+ [meta.get()].concat(queries.map(function(query) {
+ return query.get();
+ })))
+ .then(function(results) {
+ var metadata = results.shift();
+ var normalized = results.reduce(function(cache, result, i) {
+ // Could be just some rogue request
+ if (!result) {
+ return cache;
+ }
+ var resource = queries[i].resource;
+ var type = queries[i].type;
+ var manyResult = isarray(result);
+ // Inform template of ID in generic field
+ if (manyResult) {
+ result = result.map(function(data) {
+ return assign({}, data, {id: data[resource.idField]})
+ });
+ } else {
+ result = assign({}, result, {id: result[resource.idField]});
+ }
+ // If we have a lot of results for a certain type,
+ // we pluralize the key and yield an array of results
+ if (cache[type] || manyResult) {
+ var plural = pluralize(type);
+ delete cache[type];
+ cache[plural] = [];
+ if (manyResult) {
+ cache[plural] = cache[plural].concat(result);
+ } else {
+ cache[plural].push(result);
+ }
+ } else {
+ cache[type] = result;
+ }
+ return cache;
+ }, {meta: metadata});
+ resolve(normalized);
+ }).fail(reject);
+ });
+}
+
module.exports = OKView;