summaryrefslogtreecommitdiff
path: root/app/index.js
diff options
context:
space:
mode:
authorSean Fridman <fridman@mail.sfsu.edu>2015-04-01 18:27:51 -0400
committerSean Fridman <fridman@mail.sfsu.edu>2015-04-01 18:27:51 -0400
commit2e041ff6cd1b40c26bf16d37777c2c1c5153a669 (patch)
tree1e427659faf343bf42795beae8980000436617b8 /app/index.js
parentae24790e8122296b06f88fa883b8e272c6454d46 (diff)
Bootstrappin young lad
Diffstat (limited to 'app/index.js')
-rw-r--r--app/index.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/app/index.js b/app/index.js
new file mode 100644
index 0000000..641a468
--- /dev/null
+++ b/app/index.js
@@ -0,0 +1,141 @@
+var path = require('path');
+var OKQuery = require('okquery');
+var OKView = require('okview');
+var OKDB = require('okdb');
+var OKResource = require('okresource')
+var OKTemplate = require('oktemplate');
+var OKServer = require('okserver');
+var OKRestEndpoint = require('okrest');
+
+/**
+ * OKCMS!
+ * Basically takes configuration and gives you a server.
+ */
+function OKCMS(options) {
+ options = options || {};
+ var root = this._root = options.root || 'www';
+ // Reduce resource config into unique set
+ this._resourceConfig = options.resources || [];
+ this._views = options.views || {
+ '/': { template: 'index' }
+ };
+ this._resourceRoot = options.resourceRoot || '/api';
+ this._server = new OKServer({root: root});
+ this._templates = new OKTemplate({root: root});
+ var db = this._db = options.db || new OKDB();
+ // Special query for getting meta info
+ this._meta = options.meta || {
+ name: 'meta',
+ get: function() {
+ return db.getMeta();
+ }
+ };
+ this._init();
+}
+
+OKCMS.prototype.listen = function listen(port, options) {
+ options = options || {};
+ this._server.listen(port);
+};
+
+OKCMS.prototype._init = function _init() {
+ var self = this;
+
+ // Create resources instances from config and add CRUD views on them
+ // NOTE Does not support subresources
+ this._resources = this._resourceConfig.map(function (config) {
+ var resource = self._createResource(config);
+ var route = path.join(self._resourceRoot, resource.name);
+ self._server.addView(route, resource.view());
+ return resource;
+ });
+
+ // Add HTML views
+ Object.keys(this._views)
+ // Make sure more specific routes are processed first
+ // TODO This is not semantically correct (bro)
+ .sort(function(a, b) {
+ return a.length < b.length;
+ })
+ // For each route / viewOptions pair, add a view
+ .forEach(function eachRoute(route) {
+ var options = self._views[route];
+ // View should know what its route is.
+ options.route = route;
+ var view = self._createView(options);
+ // Add view at route
+ self._server.addView(route, view);
+ });
+};
+
+/**
+ * Takes a resource configuration object and returns a resource instance
+ */
+OKCMS.prototype._createResource = function(options) {
+ options = options || {};
+ var resourceClass = options.resource;
+ // No resource? Bail!
+ if (!resourceClass) throw new Error('OKCMS: No resource class given');
+ // Default to 'select all' id
+ options.id = options.id || '*';
+ // Some dependency injection
+ options.db = this._db;
+ // Clean unpassed options
+ delete options.resource;
+ // Return resource instance
+ return resourceClass(options);
+};
+
+/**
+ * Takes a view configuration object and returns a view instance
+ */
+OKCMS.prototype._createView = function _createView(options) {
+ options = options || {};
+ var self = this;
+ var viewClass = options.view || OKView;
+ var template = this._templates.getTemplate(options.template);
+ var queryConfig = options.data || [];
+ // No template? Bail!
+ if (!template) throw new Error('OKCMS: No template "' + options.template + '"');
+ // Inject them dependencies
+ options.template = template;
+ options.meta = this._meta;
+ options.queries = this._createQueries(queryConfig);
+ // Clean options not passed to view
+ delete options.view;
+ // Return view instance
+ return viewClass(options);
+};
+
+/**
+ * Takes a query configuration and returns a list of queries
+ */
+OKCMS.prototype._createQueries = function(options) {
+ options = options || [];
+ var db = this._db;
+ if (!options.length)
+ options = [options];
+ return options.map(function(option) {
+ if (!option.name)
+ throw new Error('No document name provided to query');
+ option.id = option.id || '*';
+ return new OKQuery(db, {
+ name: option.name,
+ id: option.id
+ });
+ });
+};
+
+module.exports = {
+
+ createApp: function(options) {
+ return new OKCMS(options);
+ },
+
+ OKResource: OKResource,
+
+ OKView: OKView,
+
+ OKRestEndpoint: OKRestEndpoint
+
+};