summaryrefslogtreecommitdiff
path: root/app/node_modules
diff options
context:
space:
mode:
Diffstat (limited to 'app/node_modules')
-rw-r--r--app/node_modules/okadminview/index.js100
-rw-r--r--app/node_modules/okquery/index.js1
-rw-r--r--app/node_modules/okresource/index.js66
-rw-r--r--app/node_modules/okschema/index.js4
4 files changed, 145 insertions, 26 deletions
diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js
index 273d541..06656dc 100644
--- a/app/node_modules/okadminview/index.js
+++ b/app/node_modules/okadminview/index.js
@@ -154,11 +154,12 @@ function OKAdminView(options) {
if (!resource) {
error(req, res, 404)(new Error('No such resource ' + type));
} else {
- var templateData = transformData(meta, resource, {});
- view.renderResourceNew(req, res, assign(templateData, {
- success: req.flash('success'),
- errors: req.flash('errors'),
- }));
+ fetchNewTemplateData(meta, resource, transformData).then(function(data) {
+ view.renderResourceNew(req, res, assign(data, {
+ success: req.flash('success'),
+ errors: req.flash('errors'),
+ }))
+ }).fail(error(req, res, 500))
}
});
@@ -280,11 +281,11 @@ function OKAdminView(options) {
/**
* Yields formatted template data for a single resource
*/
-function transformData(meta, resource, data) {
+function transformData(meta, spec, resource, data) {
meta = meta || {};
resource = resource || {};
data = data || {};
- var spec = Object.keys(resource.spec).reduce(function(cache, prop) {
+ var spec = Object.keys(spec).reduce(function(cache, prop) {
var value = data[prop];
var propSpec = cache[prop];
// Decorate spec with actual resource values
@@ -294,7 +295,7 @@ function transformData(meta, resource, data) {
propSpec.hidden = true;
}
return cache;
- }, resource.spec);
+ }, spec);
return {
meta: meta,
resource: {
@@ -340,47 +341,94 @@ function fetchIndexTemplateData(meta, queries, dashboardConfig) {
Q.all(queries.map(function(query) {
return query.get();
})).then(function(results) {
- var resources = results.reduce(function(cache, result, i) {
- if (!result)
- return cache;
+ var templateData = results.reduce(function(acc, result, i) {
var resource = queries[i].resource;
// We want the raw object spec
var spec = resource.spec;
var dashConf = resourceConfig[resource.type] || {}
var groupBy = dashConf.groupBy
var key = pluralize(resource.type)
- cache[key] = {
+ acc[key] = {
type: resource.type,
spec: spec,
data: result,
groupBy: groupBy
}
- return cache;
- }, {});
-
+ return acc
+ }, {})
resolve({
meta: meta,
- resources: resources
- });
- }).fail(reject);
+ resources: templateData
+ })
+ }).fail(reject)
});
}
+function fetchNewTemplateData(meta, resource, transformFn) {
+ return Q.promise(function(resolve, reject) {
+ if (!resource.hasForeignKey) {
+ done({spec: resource.spec, resource: resource})
+ } else {
+ fetchForeignKeyOptions(resource).then(done).fail(reject)
+ }
+
+ function done(results) {
+ resolve(transformFn(meta, results.spec, results.resource, {}))
+ }
+ })
+}
+
/**
* Annotate template data with schema info
*/
-function fetchResourceTemplateData(meta, query, fn) {
- fn = fn || function(m, r, d) { return {meta: m, resource: d}; };
+function fetchResourceTemplateData(meta, query, transformFn) {
return Q.promise(function(resolve, reject) {
query.get().then(function(data) {
- if (!data) {
- reject(new Error('No resource data'));
+ if (!data)
+ return reject(new Error('No resource data'))
+
+ var resource = query.resource
+
+ if (resource.hasForeignKey) {
+ fetchForeignKeyOptions(resource).then(done).fail(reject)
} else {
- var resource = query.resource;
- resolve(fn(meta, resource, data));
+ done({spec: resource.spec, resource: resource})
}
- }).fail(reject);
- });
+
+ function done(results) {
+ resolve(transformFn(meta, results.spec, results.resource, data))
+ }
+ }).fail(reject)
+ })
+}
+
+function fetchForeignKeyOptions(resource) {
+ var promises = Object.keys(resource.foreignKeys)
+ .map(fetchOptionsForKey)
+ var spec = resource.spec
+
+ return Q.all(promises).then(done)
+
+ function done() {
+ return Q.promise(function(resolve, reject) {
+ resolve({spec: spec, resource: resource})
+ })
+ }
+
+ function fetchOptionsForKey(field) {
+ var relatedResourceType = resource.foreignKeys[field]
+ return resource.related(relatedResourceType).then(fillOptions)
+
+ function fillOptions(results) {
+ return Q.promise(function(resolve, reject) {
+ spec[field].options = results.map(function(result) {
+ return result.id
+ })
+ resolve()
+ })
+ }
+ }
}
+
module.exports = OKAdminView;
diff --git a/app/node_modules/okquery/index.js b/app/node_modules/okquery/index.js
index 09d867d..d4cb905 100644
--- a/app/node_modules/okquery/index.js
+++ b/app/node_modules/okquery/index.js
@@ -23,6 +23,7 @@ function OKQuery(options) {
// Queries are ordered by index by default
var sortField = options.sortBy || '__index';
+ // TODO Make descending by default
var descending = options.descending || false;
Object.defineProperty(this, 'resource', {
diff --git a/app/node_modules/okresource/index.js b/app/node_modules/okresource/index.js
index c3f9adb..c1f2509 100644
--- a/app/node_modules/okresource/index.js
+++ b/app/node_modules/okresource/index.js
@@ -1,3 +1,4 @@
+var format = require('util').format
var assign = require('object-assign');
var cloneDeep = require('lodash.clonedeep');
var Q = require('q');
@@ -22,10 +23,36 @@ function OKResource(options) {
var spec = schema.spec;
var type = options.type;
+ var hasForeignKey = false
this._db = options.db;
this._schema = schema;
+ var foreignKeys = Object.keys(spec).reduce(function(acc, field) {
+ var fieldSpec = spec[field]
+ if (fieldSpec.type === 'foreign-key') {
+ hasForeignKey = true
+ acc[field] = fieldSpec.key
+ }
+ return acc
+ }, {})
+
+ // Will store references to other resources referenced via foreign keys
+ this._foreignKeyedResources = {}
+
// Define properties which are part of the API
+
+ // Should be treated as read-only
+ Object.defineProperty(this, 'foreignKeys', {
+ get: function() {
+ return foreignKeys
+ }
+ })
+
+ Object.defineProperty(this, 'hasForeignKey', {
+ get: function() {
+ return hasForeignKey
+ }
+ })
Object.defineProperty(this, 'spec', {
get: function() {
@@ -49,6 +76,30 @@ function OKResource(options) {
});
}
+OKResource.prototype._linkForeignKey = function(field, resource) {
+ this._foreignKeyedResources[field] = resource
+}
+
+/**
+ * Fetch all related resources for the given field
+ */
+OKResource.prototype.related = function(field) {
+ var resource = this._foreignKeyedResources[field]
+ return Q.promise(function(resolve, reject) {
+ if (!resource) {
+ return error(reject, new Error(format(
+ "No related resource for field '%s'", field)))
+ }
+ resource.all().then(resolve).fail(reject)
+ })
+
+ function error(reject, err) {
+ setTimeout(function() {
+ reject(err)
+ }, 0)
+ }
+}
+
/**
* Throws an error if data does not conform to schema
*/
@@ -180,6 +231,9 @@ OKResource.prototype.instance = function(options) {
});
};
+/**
+ * TODO This class is such bullshit. Refactor out
+ */
function OKResourceInstance(resource, options) {
if (!(this instanceof OKResourceInstance)) return new OKResourceInstance(options);
// Only support static data instances for now
@@ -279,6 +333,18 @@ function OKResourceInstance(resource, options) {
resource.assertValid(data);
};
+ Object.defineProperty(this, 'foreignKeys', {
+ get: function() {
+ return []
+ }
+ })
+
+ Object.defineProperty(this, 'hasForeignKey', {
+ get: function() {
+ return false
+ }
+ })
+
Object.defineProperty(this, 'parent', {
value: resource,
writable: false,
diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js
index 89b59cc..330ad6b 100644
--- a/app/node_modules/okschema/index.js
+++ b/app/node_modules/okschema/index.js
@@ -73,6 +73,10 @@ var types = {
'flag': {
parent: 'string',
assertValid: function(spec, value) {}
+ },
+ 'foreign-key': {
+ parent: 'enum',
+ assertValid: function(spec, value) {}
}
}