diff --git a/.gitignore b/.gitignore
index 73c490d..8c2830c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ fleet.json
*.log
.fseventsd
.TemporaryItems
+node_modules/
+doc/
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000..a920c65
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,102 @@
+{
+ // JSHint Default Configuration File (as on JSHint website)
+ // See http://jshint.com/docs/ for more details
+
+ "maxerr" : 10, // {int} Maximum error before stopping
+
+ // Enforcing
+ "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
+ "camelcase" : false, // true: Identifiers must be in camelCase
+ "curly" : true, // true: Require {} for every new block or scope
+ "eqeqeq" : true, // true: Require triple equals (===) for comparison
+ "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
+ "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
+ "indent" : 4, // {int} Number of spaces to use for indentation
+ "latedef" : true, // true: Require variables/functions to be defined before being used
+ "newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
+ "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
+ "noempty" : true, // true: Prohibit use of empty blocks
+ "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
+ "plusplus" : false, // true: Prohibit use of `++` & `--`
+ "quotmark" : true, // Quotation mark consistency:
+ // false : do nothing (default)
+ // true : ensure whatever is used is consistent
+ // "single" : require single quotes
+ // "double" : require double quotes
+ "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
+ "unused" : true, // true: Require all defined variables be used
+ "strict" : true, // true: Requires all functions run in ES5 Strict Mode
+ "trailing" : true, // true: Prohibit trailing whitespaces
+ "maxparams" : false, // {int} Max number of formal params allowed per function
+ "maxdepth" : false, // {int} Max depth of nested blocks (within functions)
+ "maxstatements" : false, // {int} Max number statements per function
+ "maxcomplexity" : false, // {int} Max cyclomatic complexity per function
+ "maxlen" : false, // {int} Max number of characters per line
+
+ // Relaxing
+ "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
+ "boss" : false, // true: Tolerate assignments where comparisons would be expected
+ "debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
+ "eqnull" : true, // true: Tolerate use of `== null`
+ "es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
+ "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
+ "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
+ // (ex: `for each`, multiple try/catch, function expression…)
+ "evil" : false, // true: Tolerate use of `eval` and `new Function()`
+ "expr" : true, // true: Tolerate `ExpressionStatement` as Programs
+ "funcscope" : false, // true: Tolerate defining variables inside control statements"
+ "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict')
+ "iterator" : false, // true: Tolerate using the `__iterator__` property
+ "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
+ "laxbreak" : false, // true: Tolerate possibly unsafe line breakings
+ "laxcomma" : false, // true: Tolerate comma-first style coding
+ "loopfunc" : false, // true: Tolerate functions being defined in loops
+ "multistr" : false, // true: Tolerate multi-line strings
+ "proto" : false, // true: Tolerate using the `__proto__` property
+ "scripturl" : false, // true: Tolerate script-targeted URLs
+ "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
+ "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
+ "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
+ "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
+ "validthis" : false, // true: Tolerate using this in a non-constructor function
+
+ // Environments
+ "browser" : true, // Web Browser (window, document, etc)
+ "couch" : false, // CouchDB
+ "devel" : true, // Development/debugging (alert, confirm, etc)
+ "dojo" : false, // Dojo Toolkit
+ "jquery" : false, // jQuery
+ "mootools" : false, // MooTools
+ "node" : true, // Node.js
+ "nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
+ "prototypejs" : false, // Prototype and Scriptaculous
+ "rhino" : false, // Rhino
+ "worker" : false, // Web Workers
+ "wsh" : false, // Windows Scripting Host
+ "yui" : false, // Yahoo User Interface
+
+ // Legacy
+ "nomen" : false, // true: Prohibit dangling `_` in variables
+ "onevar" : false, // true: Allow only one `var` statement per function
+ "passfail" : false, // true: Stop on first error
+ "white" : false, // true: Check against strict whitespace and indentation rules
+
+ // Custom Globals
+ "globals" : {
+
+ // RequireJS
+ "define": true,
+ "requirejs": true,
+
+ // mocha
+ "describe": true,
+ "beforeEach": true,
+ "afterEach": true,
+ "before": true,
+ "after": true,
+ "it": true,
+
+ //chai
+ "expect": true
+ }
+}
diff --git a/lib/handlers.js b/lib/handlers.js
index 371e522..301c075 100644
--- a/lib/handlers.js
+++ b/lib/handlers.js
@@ -1,26 +1,26 @@
+'use strict';
module.exports = function (mongoDataInstance, previewInstance, importerInstance) {
- "use strict";
function getAttribute(options, callback) {
- mongoDataInstance.getMongoAttribute(options, callback);
+ return mongoDataInstance.getMongoAttribute(options, callback);
}
function getContent(options, callback) {
- mongoDataInstance.getMongoContent(options, callback);
+ return mongoDataInstance.getMongoContent(options, callback);
}
function getPreviewHTML(html, options, callback) {
- previewInstance.getPreviewHTML(html, options, callback);
+ return previewInstance.getPreviewHTML(html, options, callback);
}
function importer(doc, options, callback) {
- importerInstance.importer(doc, options, callback);
+ return importerInstance.importer(doc, options, callback);
}
return {
- getAttribute: getAttribute,
- getContent: getContent,
+ getAttribute: getAttribute,
+ getContent: getContent,
getPreviewHTML: getPreviewHTML,
- importer: importer
+ importer: importer
};
};
diff --git a/lib/helpers.js b/lib/helpers.js
index 7e30362..a0d10f2 100644
--- a/lib/helpers.js
+++ b/lib/helpers.js
@@ -1,12 +1,12 @@
+'use strict';
var when = require('when');
-var _ = require('underscore');
+var _ = require('underscore');
module.exports = function (markers) {
- "use strict";
function replace(text, marker, getReplacement, once) {
var deferred = when.defer();
- var regExp = new RegExp(markers.prefix + marker + markers.postfix, 'gmi');
- var matches = text && text.match && text.match(regExp);
+ var regExp = new RegExp(markers.prefix + marker + markers.postfix, 'gmi');
+ var matches = text && text.match && text.match(regExp);
if (matches) {
if (once) {
matches = [matches[0]];
@@ -20,7 +20,7 @@ module.exports = function (markers) {
deferred2.reject(err);
} else {
var replace_result = {
- regExp: replacement.regExp || regExp,
+ regExp: replacement.regExp || regExp,
replacement: replacement.value
};
deferred2.resolve(replace_result);
@@ -51,18 +51,18 @@ module.exports = function (markers) {
});
});
} catch (e) {
- return callback(e);
+ return callback && callback(e);
}
- return callback(null, text);
+ return callback && callback(null, text);
},
function onFailure(err) {
- return callback(err);
+ return callback && callback(err);
}
);
}
return {
- replace: replace,
+ replace: replace,
handTextManipulation: handTextManipulation
};
};
diff --git a/lib/importer.js b/lib/importer.js
index f321938..c549689 100644
--- a/lib/importer.js
+++ b/lib/importer.js
@@ -1,12 +1,11 @@
+'use strict';
var when = require('when');
-var _ = require('underscore');
+var _ = require('underscore');
var path = require('path');
-var fs = require('fs');
+var fs = require('fs');
module.exports = function (config, mongoInstance, helpers, markers) {
- "use strict";
-
var replaceMarkers;
function handleImportMarkers(doc, options, callback) {
@@ -18,28 +17,28 @@ module.exports = function (config, mongoInstance, helpers, markers) {
return new_text;
}
- helpers.handTextManipulation(doc,
+ return helpers.handTextManipulation(doc,
promises,
handler,
callback
);
}
- var import_leftovers_tag = markers.import_leftovers_tag;
+ var import_leftovers_tag = markers.import_leftovers_tag;
var import_leftovers_regexp = markers.import_leftovers_regexp;
function importer(doc, options, cb) {
var promises = helpers.replace(doc, import_leftovers_tag,
function getReplacement(result, callback) {
- var parts = import_leftovers_regexp.exec(result);
+ var parts = import_leftovers_regexp.exec(result);
var context = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3]
+ name: parts[2],
+ attribute: parts[3]
};
return callback(null, {
regExp: new RegExp(result, 'gmi'),
- value: context
+ value: context
});
},
// there can be only one import_leftovers
@@ -50,33 +49,33 @@ module.exports = function (config, mongoInstance, helpers, markers) {
handleImportMarkers(doc, options, function handleLeftover(err, remainder) {
if (err) {
config.error && config.error('ERR importer.importer handleImportMarkers', err);
- return cb(err);
+ return cb && cb(err);
}
if (leftover) {
return mongoInstance.ensureContent(leftover.replacement, function parent(err, parent_result) {
if (err) {
config.error && config.error('ERR importer.importer ensureContent', err);
- return cb(err);
+ return cb && cb(err);
}
- leftover.replacement.query = { _id: parent_result._id };
+ leftover.replacement.query = {_id: parent_result._id};
- remainder = remainder.replace(leftover.regExp, "");
+ remainder = remainder.replace(leftover.regExp, '');
return mongoInstance.setMongoAttribute(remainder, leftover.replacement, function savedAttribute(err) {
if (err) {
config.error && config.error('ERR importer.importer setMongoAttribute', err);
- return cb(err);
+ return cb && cb(err);
}
- return cb(null, remainder);
+ return cb && cb(null, remainder);
});
});
}
config.debug && config.debug('no import_leftover tag found');
- return cb(null, remainder);
+ return cb && cb(null, remainder);
});
},
function onFailure(err) {
config.error && config.error('ERR importer.importer onFailure', err);
- return cb(err);
+ return cb && cb(err);
}
);
}
@@ -86,23 +85,23 @@ module.exports = function (config, mongoInstance, helpers, markers) {
return mongoInstance.ensureContent(context, function parent(err, parent_result) {
if (err) {
config.error && config.error('ERR importer.importer ensureContent', err);
- return callback(err);
+ return callback && callback(err);
}
function replaceWithEmptyContent(err) {
var replacement = {
regExp: result,
- value: ""
+ value: ''
};
- return callback(err, replacement);
+ return callback && callback(err, replacement);
}
- if (context.attribute === "json") {
- var data = null;
+ if (context.attribute === 'json') {
+ var data = null;
try {
data = JSON.parse(remainder);
} catch (error) {
config.error && config.error('ERR importer.replaceMarkers JSON.parse(remainder)', remainder, error);
- return callback(error);
+ return callback && callback(error);
}
if (data._id) {
delete data._id;
@@ -112,31 +111,31 @@ module.exports = function (config, mongoInstance, helpers, markers) {
return mongoInstance.setMongoContent(parent_result, context, function (err) {
if (err) {
config.error && config.error('ERR importer.importRemainder setMongoContent', err);
- return callback(err);
+ return callback && callback(err);
}
var documentId = 'json:' + context.collection + ':' + context.name;
- var keys = _.keys(parent_result); // reset all attributes;
+ var keys = _.keys(parent_result); // reset all attributes;
return mongoInstance.updateShareDocument(documentId, parent_result, keys, function () {
return replaceWithEmptyContent(null);
});
});
}
- context.query = { _id: parent_result._id };
+ context.query = {_id: parent_result._id};
return mongoInstance.setMongoAttribute(remainder, context, function savedAttribute(err) {
if (err) {
config.error && config.error('ERR2 importer.importer setMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
return replaceWithEmptyContent(null);
});
});
}
- var import_tag = markers.import_tag;
- var import_regexp = markers.import_regexp;
+ var import_tag = markers.import_tag;
+ var import_regexp = markers.import_regexp;
var import_strip_regexp = markers.import_strip_regexp;
- var import_file_tag = markers.import_file_tag;
+ var import_file_tag = markers.import_file_tag;
var import_file_regexp = markers.import_file_regexp;
replaceMarkers = function (doc, options) {
@@ -144,19 +143,19 @@ module.exports = function (config, mongoInstance, helpers, markers) {
promises.push(
helpers.replace(doc, import_tag, function handleImportMarker(result, callback) {
- var parts = import_regexp.exec(result);
- var context = {
+ var parts = import_regexp.exec(result);
+ var context = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3]
+ name: parts[2],
+ attribute: parts[3]
};
var striped_parts = import_strip_regexp.exec(parts[4]);
- var sub_doc = striped_parts[1];
+ var sub_doc = striped_parts[1];
handleImportMarkers(sub_doc, options, function handleLeftover(err, remainder) {
if (err) {
config.error && config.error('ERR importer.replaceMarkers import_content_marker', err);
- return callback(err);
+ return callback && callback(err);
}
return importRemainder(context, result, remainder, callback);
});
@@ -166,23 +165,23 @@ module.exports = function (config, mongoInstance, helpers, markers) {
promises.push(
helpers.replace(doc, import_file_tag, function handleImportFileMarker(result, callback) {
- var parts = import_file_regexp.exec(result);
+ var parts = import_file_regexp.exec(result);
var filename = path.resolve(config.statics.importer_path, parts[1]);
- var context = {
+ var context = {
collection: parts[2],
- name: parts[3],
- attribute: parts[4]
+ name: parts[3],
+ attribute: parts[4]
};
fs.readFile(filename, 'utf-8', function handleFileContent(err, sub_doc) {
if (err) {
config.error && config.error('ERR importer.replaceMarkers readFile', err);
- return callback(err);
+ return callback && callback(err);
}
// process with leftover marker support
return importer(sub_doc, context, function handleLeftover(err, remainder) {
if (err) {
config.error && config.error('ERR importer.replaceMarkers importer', err);
- return callback(err);
+ return callback && callback(err);
}
return importRemainder(context, result, remainder, callback);
});
diff --git a/lib/markers.js b/lib/markers.js
index 269a6a7..45bcc24 100644
--- a/lib/markers.js
+++ b/lib/markers.js
@@ -1,23 +1,23 @@
+'use strict';
module.exports = function markers(config) {
- "use strict";
- var marker_prefix = '';
// Preview markers
- var script_tag = 'script__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var script_tag = 'script__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var script_regexp = new RegExp(marker_prefix + script_tag + marker_postfix);
- var style_tag = 'style__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var style_tag = 'style__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var style_regexp = new RegExp(marker_prefix + style_tag + marker_postfix);
- var less_tag = 'less__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var less_tag = 'less__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var less_regexp = new RegExp(marker_prefix + less_tag + marker_postfix);
- var template_tag = 'template__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)__context__([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var template_tag = 'template__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)__context__([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var template_regexp = new RegExp(marker_prefix + template_tag + marker_postfix);
- var markdown_tag = 'markdown__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var markdown_tag = 'markdown__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var markdown_regexp = new RegExp(marker_prefix + markdown_tag + marker_postfix);
// remove_tag is greedy, so we can do multiple removes on one page.
@@ -25,16 +25,16 @@ module.exports = function markers(config) {
//var remove_regexp = new RegExp(remove_tag);
// Importer markers
- var import_leftovers_tag = 'import_leftovers__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var import_leftovers_tag = 'import_leftovers__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var import_leftovers_regexp = new RegExp(marker_prefix + import_leftovers_tag + marker_postfix);
// import tag is non greedy on purpose, you can only import content into 1 object,
// repeating the same tag will result in content overwriting each other.
- var import_tag = 'import__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([\\w\\W]*)_end_import__\\1_\\2_\\3';
- var import_regexp = new RegExp(marker_prefix + import_tag + marker_postfix);
+ var import_tag = 'import__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)_([\\w\\W]*)_end_import__\\1_\\2_\\3';
+ var import_regexp = new RegExp(marker_prefix + import_tag + marker_postfix);
var import_strip_regexp = new RegExp(marker_postfix + '([\\w\\W]*)' + marker_prefix);
- var import_file_tag = 'import_file__([A-Za-z0-9.\/]+)__into__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
+ var import_file_tag = 'import_file__([A-Za-z0-9.\/]+)__into__([A-Za-z0-9]+)_([A-Za-z0-9]+)_([A-Za-z0-9]+)';
var import_file_regexp = new RegExp(marker_prefix + import_file_tag + marker_postfix);
@@ -45,27 +45,27 @@ module.exports = function markers(config) {
}
return {
- prefix: marker_prefix,
- postfix: marker_postfix,
- createTag: createTag,
- script_tag: script_tag,
- script_regexp: script_regexp,
- style_tag: style_tag,
- style_regexp: style_regexp,
- less_tag: less_tag,
- less_regexp: less_regexp,
- template_tag: template_tag,
- template_regexp: template_regexp,
- markdown_tag: markdown_tag,
- markdown_regexp: markdown_regexp,
- remove_tag: remove_tag,
+ prefix: marker_prefix,
+ postfix: marker_postfix,
+ createTag: createTag,
+ script_tag: script_tag,
+ script_regexp: script_regexp,
+ style_tag: style_tag,
+ style_regexp: style_regexp,
+ less_tag: less_tag,
+ less_regexp: less_regexp,
+ template_tag: template_tag,
+ template_regexp: template_regexp,
+ markdown_tag: markdown_tag,
+ markdown_regexp: markdown_regexp,
+ remove_tag: remove_tag,
// remove_regexp:remove_regexp,
- import_leftovers_tag: import_leftovers_tag,
+ import_leftovers_tag: import_leftovers_tag,
import_leftovers_regexp: import_leftovers_regexp,
- import_tag: import_tag,
- import_regexp: import_regexp,
- import_strip_regexp: import_strip_regexp,
- import_file_tag: import_file_tag,
- import_file_regexp: import_file_regexp
+ import_tag: import_tag,
+ import_regexp: import_regexp,
+ import_strip_regexp: import_strip_regexp,
+ import_file_tag: import_file_tag,
+ import_file_regexp: import_file_regexp
};
};
diff --git a/lib/mongoData.js b/lib/mongoData.js
index 5ef3631..3149365 100644
--- a/lib/mongoData.js
+++ b/lib/mongoData.js
@@ -1,51 +1,51 @@
+'use strict';
var ObjectID = require('mongodb').ObjectID;
-var _ = require('underscore');
+var _ = require('underscore');
module.exports = function (config, db, shareModel) {
- "use strict";
/*
- options:
+ * options:
* collection (mandatory)
* query (mandatory)
*/
function getMongoContent(options, callback) {
config.debug && config.debug('getMongoContent options', options);
- if ( !options.collection) {
+ if (!options.collection) {
return callback(new Error('Data not found / missing collection'));
}
return db.collection(options.collection, function collection(err, col) {
if (err) {
config.error && config.error('ERR2 getMongoContent', err);
- return callback(err);
+ return callback && callback(err);
}
if (!options.query) {
- return callback(new Error('Data not found ' + options.collection + '/ missing query'), null, col);
+ return callback && callback(new Error('Data not found ' + options.collection + '/ missing query'), null, col);
}
if (options.query._id && !(options.query._id instanceof Object)) {
try {
options.query._id = new ObjectID.createFromHexString(options.query._id);
} catch (error) {
config.error && config.error('ERR3 getMongoContent', error);
- return callback(error);
+ return callback && callback(error);
}
}
return col.findOne(options.query, function foundOne(err, result) {
if (err) {
config.error && config.error('ERR4 getMongoContent', err);
- return callback(err);
+ return callback && callback(err);
}
if (!result) {
- return callback(new Error('Data not found ' + options.collection + '/' + JSON.stringify(options.query)), null, col);
+ return callback && callback(new Error('Data not found ' + options.collection + '/' + JSON.stringify(options.query)), null, col);
}
- return callback(null, result, col);
+ return callback && callback(null, result, col);
});
});
}
/*
- options:
+ * options:
* collection (mandatory)
* query (mandatory)
* attribute (mandatory)
@@ -55,7 +55,7 @@ module.exports = function (config, db, shareModel) {
return getMongoContent(options, function document(err, result) {
if (err) {
config.error && config.error('ERR1 getMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
var attribute_options = null;
config.debug && config.debug('getMongoAttribute result', result);
@@ -64,25 +64,25 @@ module.exports = function (config, db, shareModel) {
result[options.attribute].guid) {
attribute_options = {
collection: options.collection,
- query: {_id: result[options.attribute].guid}
+ query: {_id: result[options.attribute].guid}
};
config.debug && config.debug('getMongoAttribute attribute_options', attribute_options);
getMongoContent(attribute_options, function attribute(err, attribute_result) {
if (err) {
config.error && config.error('ERR2 getMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
config.debug && config.debug('getMongoAttribute attribute_result', attribute_result);
- return callback(err, attribute_result);
+ return callback && callback(err, attribute_result);
});
} else {
config.debug && config.debug('getMongoAttribute try direct lookup');
attribute_options = {
collection: options.collection,
- query: {
+ query: {
parent: result._id,
- name: result.name + '.' + options.attribute
+ name: result.name + '.' + options.attribute
}
};
config.debug && config.debug('getMongoAttribute attribute_options', attribute_options);
@@ -90,10 +90,10 @@ module.exports = function (config, db, shareModel) {
return getMongoContent(attribute_options, function attribute(err, attribute_result) {
if (err) {
config.error && config.error('ERR getMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
config.debug && config.debug('getMongoAttribute direct attribute_result', attribute_result);
- return callback(err, attribute_result);
+ return callback && callback(err, attribute_result);
});
}
});
@@ -107,11 +107,11 @@ module.exports = function (config, db, shareModel) {
collection.save(data, {safe: true}, function (err, result2, result3) {
if (err) {
config.error && config.error('ERR saveData', err);
- return callback(err);
+ return callback && callback(err);
}
config.debug && config.debug('saveData saved', data._id, result2, result3);
- return callback(null, data, collection);
+ return callback && callback(null, data, collection);
});
}
@@ -125,20 +125,20 @@ module.exports = function (config, db, shareModel) {
return updateData(collection, data, callback);
});
} else {
- updating = true;
+ updating = true;
var stopUpdating = function (err, result, col) {
config.debug && config.debug('Stop updating');
updating = false;
if (err) {
- return callback(err);
+ return callback && callback(err);
}
- return callback(null, result, col);
+ return callback && callback(null, result, col);
};
- return collection.findOne({ _id: data._id}, function foundOne(err, result) {
+ return collection.findOne({_id: data._id}, function foundOne(err, result) {
if (err) {
config.error && config.error('ERR updateData', err);
- return callback(err);
+ return callback && callback(err);
}
_.extend(result, data);
return saveData(collection, result, stopUpdating);
@@ -148,7 +148,7 @@ module.exports = function (config, db, shareModel) {
/*
- options:
+ * options:
* collection (mandatory)
* query (mandatory)
* update (optional) : extends existing content
@@ -158,7 +158,7 @@ module.exports = function (config, db, shareModel) {
return db.collection(options.collection, function handleCollection(err, collection) {
if (err) {
config.error && config.error('ERR2 setMongoContent', err);
- return callback(err);
+ return callback && callback(err);
}
if (options.operation) {
data.version = options.operation.v;
@@ -172,7 +172,7 @@ module.exports = function (config, db, shareModel) {
collection.findOne(options.query, function foundOne(err, result) {
if (err) {
config.error && config.error('ERR3 setMongoContent', err);
- return callback(err);
+ return callback && callback(err);
}
if (result) {
data._id = result._id;
@@ -191,16 +191,17 @@ module.exports = function (config, db, shareModel) {
config.warn && config.warn('WARN setMongoAttribute updateShareDocumentPath shareModel.getSnapshot', documentId, err);
return callback && callback();
}
- var sub_data = data;
+ var sub_data = data;
var sub_snapshot_data = doc.snapshot;
- var equal_path = [];
- var found = false;
+ var equal_path = [];
+ var found = false;
var x;
for (x = 0; !found && x < path.length; x += 1) {
var key = path[x];
- if (sub_data && sub_data.hasOwnProperty(key)
- && sub_snapshot_data && sub_snapshot_data.hasOwnProperty(key)) {
- sub_data = sub_data[key];
+ if (sub_data && sub_data.hasOwnProperty(key) &&
+ sub_snapshot_data &&
+ sub_snapshot_data.hasOwnProperty(key)) {
+ sub_data = sub_data[key];
sub_snapshot_data = sub_snapshot_data[key];
equal_path.push(key);
} else if (!sub_snapshot_data || !sub_snapshot_data.hasOwnProperty(key)) {
@@ -219,7 +220,10 @@ module.exports = function (config, db, shareModel) {
if (sub_snapshot_data) {
op.od = sub_snapshot_data;
}
- return shareModel.applyOp(documentId, { op: [op], v: doc.v }, function (err, result) {
+ return shareModel.applyOp(documentId, {
+ op: [op],
+ v: doc.v
+ }, function (err, result) {
if (err) {
config.error && config.error('ERR updateShareDocumentPath shareModel.applyOp', documentId, err);
return callback && callback();
@@ -244,10 +248,12 @@ module.exports = function (config, db, shareModel) {
}
if (doc.type.name === 'text') {
ops.push({
- d: doc.snapshot, p: 0
+ d: doc.snapshot,
+ p: 0
});
ops.push({
- i: data, p: 0
+ i: data,
+ p: 0
});
} else if (doc.type.name === 'json') {
_.forEach(keys, function (key) {
@@ -265,7 +271,10 @@ module.exports = function (config, db, shareModel) {
}
});
}
- return shareModel.applyOp(documentId, { op: ops, v: doc.v }, function (err, result) {
+ return shareModel.applyOp(documentId, {
+ op: ops,
+ v: doc.v
+ }, function (err, result) {
if (err) {
config.warn && config.warn('WARN updateShareDocument shareModel.applyOp', documentId, err);
return callback && callback();
@@ -297,16 +306,16 @@ module.exports = function (config, db, shareModel) {
config.debug && config.debug('Stop ensuring', options);
ensuring = false;
if (err) {
- return callback(err);
+ return callback && callback(err);
}
- return callback(null, result, col);
+ return callback && callback(null, result, col);
};
getMongoContent(options, function document(err, result, col) {
if (err) {
if (/Data not found*/.test(err.message)) {
var documentId = 'json:' + options.collection + ':' + options.name;
- var data = {name: options.name};
+ var data = {name: options.name};
setMongoContent(data, options, function (err, content_result, col) {
var keys = _.keys(data); // reset all attributes;
return updateShareDocument(documentId, data, keys, function updatedShareDocument() {
@@ -332,21 +341,21 @@ module.exports = function (config, db, shareModel) {
ensureContent(options, function document(err, result, col) {
if (err) {
config.error && config.error('ERR1 setMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
var attribute_options = {
collection: options.collection,
- name: result.name + '.' + options.attribute
+ name: result.name + '.' + options.attribute
};
- if (result.hasOwnProperty(options.attribute)
- && result[options.attribute].guid) {
+ if (result.hasOwnProperty(options.attribute) &&
+ result[options.attribute].guid) {
attribute_options.query = {
_id: result[options.attribute].guid
};
} else {
attribute_options.query = {
parent: result._id,
- name: result.name + '.' + options.attribute
+ name: result.name + '.' + options.attribute
};
}
@@ -355,7 +364,7 @@ module.exports = function (config, db, shareModel) {
return ensureContent(attribute_options, function attribute(err, attribute_result) {
if (err) {
config.error && config.error('ERR2 setMongoAttribute ensureContent', err);
- return callback(err);
+ return callback && callback(err);
}
var updateContent = true;
if (result[options.attribute]) {
@@ -365,11 +374,11 @@ module.exports = function (config, db, shareModel) {
result[options.attribute].guid = attribute_result._id;
}
} else {
- result[options.attribute] = { guid: attribute_result._id };
+ result[options.attribute] = {guid: attribute_result._id};
}
- attribute_result.parent = result._id;
- attribute_result.name = result.name + '.' + options.attribute;
+ attribute_result.parent = result._id;
+ attribute_result.name = result.name + '.' + options.attribute;
attribute_result[options.attribute] = data;
if (options.operation) {
attribute_result.version = options.operation.v;
@@ -377,18 +386,18 @@ module.exports = function (config, db, shareModel) {
return saveData(col, attribute_result, function saved(err) {
if (err) {
config.error && config.error('ERR3 setMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
- var documentId = 'json:' + options.collection + ':' + result.name;
- var type = options.type || 'text';
+ var documentId = 'json:' + options.collection + ':' + result.name;
+ var type = options.type || 'text';
var attributeDocumentId = type + ':' + options.collection + ':' + result.name + ':' + options.attribute;
- var keys = null;
- var share_data = null;
+ var keys = null;
+ var share_data = null;
if (type === 'json') {
keys = _.keys(attribute_result); // reset all attributes;
share_data = attribute_result;
} else {
- keys = [attribute_result.name];
+ keys = [attribute_result.name];
share_data = data;
}
if (options.no_share) {
@@ -399,15 +408,15 @@ module.exports = function (config, db, shareModel) {
updateData(col, result, function saved(err) {
if (err) {
config.error && config.error('ERR3 setMongoAttribute', err);
- return callback(err);
+ return callback && callback(err);
}
var path = [options.attribute, 'guid']; // reset just guid attribute;
return updateShareDocumentPath(documentId, result, path, function updatedShareContent() {
- return callback(null, attribute_result, col);
+ return callback && callback(null, attribute_result, col);
});
});
} else {
- callback(null, attribute_result, col);
+ return callback && callback(null, attribute_result, col);
}
});
});
@@ -416,11 +425,11 @@ module.exports = function (config, db, shareModel) {
}
return {
- getMongoAttribute: getMongoAttribute,
- getMongoContent: getMongoContent,
- setMongoAttribute: setMongoAttribute,
- setMongoContent: setMongoContent,
- ensureContent: ensureContent,
+ getMongoAttribute: getMongoAttribute,
+ getMongoContent: getMongoContent,
+ setMongoAttribute: setMongoAttribute,
+ setMongoContent: setMongoContent,
+ ensureContent: ensureContent,
updateShareDocument: updateShareDocument
};
};
diff --git a/lib/preview.js b/lib/preview.js
index 82dd841..fef68bd 100644
--- a/lib/preview.js
+++ b/lib/preview.js
@@ -1,26 +1,26 @@
+'use strict';
var Handlebars = require('handlebars');
-var markdown = require('markdown').markdown;
-var _ = require('underscore');
-var less = require('less');
-var when = require('when');
+var markdown = require('markdown').markdown;
+var _ = require('underscore');
+var less = require('less');
+var when = require('when');
module.exports = function (config, mongoDataInstance, helpers, markers) {
- "use strict";
var getPreviewHTML;
- var script_tag = markers.script_tag;
+ var script_tag = markers.script_tag;
var script_regexp = markers.script_regexp;
- var style_tag = markers.style_tag;
+ var style_tag = markers.style_tag;
var style_regexp = markers.style_regexp;
- var less_tag = markers.less_tag;
+ var less_tag = markers.less_tag;
var less_regexp = markers.less_regexp;
- var template_tag = markers.template_tag;
+ var template_tag = markers.template_tag;
var template_regexp = markers.template_regexp;
- var markdown_tag = markers.markdown_tag;
+ var markdown_tag = markers.markdown_tag;
var markdown_regexp = markers.markdown_regexp;
var remove_tag = markers.remove_tag;
@@ -33,76 +33,76 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
// Script tag handling
promises.push(
helpers.replace(html, script_tag, function handleScriptMarker(result, callback) {
- var parts = script_regexp.exec(result);
+ var parts = script_regexp.exec(result);
var context = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3]
+ name: parts[2],
+ attribute: parts[3]
};
- return callback(null, {
- regExp: new RegExp(result, 'gmi'),
- value: ''
- });
+ return callback && callback(null, {
+ regExp: new RegExp(result, 'gmi'),
+ value: ''
+ });
}));
// Style tag handling
promises.push(
helpers.replace(html, style_tag, function handleStyleMarker(result, callback) {
- var parts = style_regexp.exec(result);
+ var parts = style_regexp.exec(result);
var context = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3]
+ name: parts[2],
+ attribute: parts[3]
};
- return callback(null, {
- regExp: new RegExp(result, 'gmi'),
- value: ''
- });
+ return callback && callback(null, {
+ regExp: new RegExp(result, 'gmi'),
+ value: ''
+ });
}));
// Less tag handling
promises.push(
helpers.replace(html, less_tag, function handleStyleMarker(result, callback) {
- var parts = less_regexp.exec(result);
+ var parts = less_regexp.exec(result);
var context = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3]
+ name: parts[2],
+ attribute: parts[3]
};
- return callback(null, {
- regExp: new RegExp(result, 'gmi'),
- value: ''
- });
+ return callback && callback(null, {
+ regExp: new RegExp(result, 'gmi'),
+ value: ''
+ });
}));
// Template tag handling
promises.push(
helpers.replace(html, template_tag, function handleTemplateMarker(result, callback) {
- var parts = template_regexp.exec(result);
+ var parts = template_regexp.exec(result);
var template = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3],
- query: { name: parts[2]}
+ name: parts[2],
+ attribute: parts[3],
+ query: {name: parts[2]}
};
- var context = {
+ var context = {
collection: parts[4],
- name: parts[5],
- query: { name: parts[5]},
- req: options.req
+ name: parts[5],
+ query: {name: parts[5]},
+ req: options.req
};
return mongoDataInstance.getMongoContent(context, function handleContext(err, context_result) {
if (err) {
config.error && config.error('ERR template_tag getMongoContent', context);
- return callback(err);
+ return callback && callback(err);
}
return mongoDataInstance.getMongoAttribute(template, function handleTemplate(err, template_result) {
if (err) {
config.error && config.error('ERR template_tag getMongoAttribute', template, err);
- return callback(err);
+ return callback && callback(err);
}
var compiled_template = null;
- var keys_to_collect = {};
+ var keys_to_collect = {};
function collectKey(key) {
return function () {
@@ -110,7 +110,7 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
return keys_to_collect[key];
}
keys_to_collect[key] = null;
- return "waiting for content";
+ return 'waiting for content';
};
}
@@ -128,7 +128,7 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
compiled_template = handlebars.compile(template_result[template.attribute]);
} catch (error1) {
config.error && config.error('ERR template_tag Handlebars.compile', template, error1);
- return callback(error1);
+ return callback && callback(error1);
}
var extendHandlebars_context = function (result) {
var handlebars = {};
@@ -141,41 +141,43 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
});
return handlebars;
};
- var handlebars_context = extendHandlebars_context(context_result);
+ var handlebars_context = extendHandlebars_context(context_result);
try {
compiled_template(handlebars_context);
} catch (error2) {
config.error && config.error('ERR template_tag Handlebars.render', template, context, error2);
- return callback(error2);
+ return callback && callback(error2);
}
var promises = [];
_.forEach(_.keys(keys_to_collect), function gatherKeyValues(key) {
- var deferred = when.defer();
- var promise = deferred.promise;
+ //noinspection JSUnresolvedFunction
+ var deferred = when.defer();
+ var promise = deferred.promise;
promises.push(promise);
var attribute_context = {
collection: context.collection,
- attribute: key,
- query: { _id: context_result._id}
+ attribute: key,
+ query: {_id: context_result._id}
};
return mongoDataInstance.getMongoAttribute(attribute_context, function cacheTemplateKey(err, template_key_result) {
if (err) {
config.error && config.error('ERR handlebar.registerHelper getMongoAttribute', err);
deferred.reject(err);
}
- var value = template_key_result[key];
+ var value = template_key_result[key];
keys_to_collect[key] = value;
deferred.resolve(value);
});
});
+ //noinspection JSUnresolvedFunction
return when.all(promises).then(
function onSuccess() {
- var rendered = null;
+ var rendered = null;
try {
rendered = compiled_template(handlebars_context);
} catch (err) {
config.error && config.error('ERR template_tag Handlebars.render', template, context, err);
- return callback(err);
+ return callback && callback(err);
}
config.debug && config.debug('// handle markers on rendered template');
context.query = {_id: context_result._id};
@@ -186,13 +188,13 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
}
return callback(null, {
regExp: new RegExp(result, 'gmi'),
- value: preview_html
+ value: preview_html
});
});
},
function onFailure(err) {
config.error && config.error('ERR template_tag resolving promises', err);
- return callback(err);
+ return callback && callback(err);
}
);
});
@@ -202,32 +204,32 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
// Markdown tag handling
promises.push(
helpers.replace(html, markdown_tag, function handleMarkDownMarker(result, callback) {
- var parts = markdown_regexp.exec(result);
+ var parts = markdown_regexp.exec(result);
var attribute = {
collection: parts[1],
- name: parts[2],
- attribute: parts[3],
- query: { name: parts[2] }
+ name: parts[2],
+ attribute: parts[3],
+ query: {name: parts[2]}
};
return mongoDataInstance.getMongoAttribute(attribute, function handleMarkdownContent(err, markdown_result) {
if (err) {
- return callback(err);
+ return callback && callback(err);
}
var html = markdown.toHTML(markdown_result[attribute.attribute]);
- return callback(null, {
- regExp: new RegExp(result, 'gmi'),
- value: html
- });
+ return callback && callback(null, {
+ regExp: new RegExp(result, 'gmi'),
+ value: html
+ });
});
}));
// Remove tag handling
promises.push(
helpers.replace(html, remove_tag, function handleRemoveMarker(result, callback) {
- return callback(null, {
- regExp: null,
- value: ""
- });
+ return callback && callback(null, {
+ regExp: null,
+ value: ''
+ });
}, true));
return promises;
@@ -241,7 +243,7 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
return text.replace(result.regExp, result.replacement);
}
- helpers.handTextManipulation(content,
+ return helpers.handTextManipulation(content,
promises,
handler,
callback
@@ -249,7 +251,7 @@ module.exports = function (config, mongoDataInstance, helpers, markers) {
};
return {
- getPreviewHTML: getPreviewHTML,
+ getPreviewHTML: getPreviewHTML,
_replaceMarkers: replaceMarkers
};
};
diff --git a/lib/responder.js b/lib/responder.js
index 7a2bc9e..687a78f 100644
--- a/lib/responder.js
+++ b/lib/responder.js
@@ -1,10 +1,9 @@
-
+'use strict';
/*
* options.ext: determines content-type
* options.attribute: sends result[options.attribute] in stead of result
*/
module.exports = function (config, options, res, next) {
- "use strict";
return function responder(err, result) {
if (err) {
config.error && config.error('ERR responder', options, err);
diff --git a/lib/routes.js b/lib/routes.js
index 58695c3..a933fe3 100644
--- a/lib/routes.js
+++ b/lib/routes.js
@@ -1,20 +1,20 @@
+'use strict';
var responder = require('./responder.js');
var path = require('path');
-var fs = require('fs');
+var fs = require('fs');
module.exports = function (app, handlers, markers, config) {
- "use strict";
var route;
route = config.api.data + '/:collection/:guid/:attribute.:ext(css|less|js|html)';
app.get(route,
function getAttributeByGUID(req, res, next) {
- config.debug && config.debug('/data/:collection/:guid/:attribute.:ext(less|js|html)');
+ config.debug && config.debug(config.api.data + '/:collection/:guid/:attribute.:ext(less|js|html)');
var options = {
collection: req.params.collection,
- attribute: req.params.attribute,
- ext: req.params.ext,
- query: {_id: req.params.guid}
+ attribute: req.params.attribute,
+ ext: req.params.ext,
+ query: {_id: req.params.guid}
};
handlers.getAttribute(options,
responder(config, options, res, next)
@@ -25,11 +25,11 @@ module.exports = function (app, handlers, markers, config) {
route = config.api.data + '/:collection/:guid.:ext(json)';
app.get(route,
function getContentByGUID(req, res, next) {
- config.debug && config.debug('/data/:collection/:guid.:ext(json)');
+ config.debug && config.debug(config.api.data + '/:collection/:guid.:ext(json)');
var options = {
collection: req.params.collection,
- ext: req.params.ext,
- query: {_id: req.params.guid}
+ ext: req.params.ext,
+ query: {_id: req.params.guid}
};
handlers.getContent(options,
responder(config, options, res, next)
@@ -40,12 +40,12 @@ module.exports = function (app, handlers, markers, config) {
route = config.api.content + '/:collection/:name/:attribute.:ext(css|less|js|html)';
app.get(route,
function getAttributeByName(req, res, next) {
- config.debug && config.debug('/content/:collection/:name/:attribute.:ext(less|js|html)');
+ config.debug && config.debug(config.api.content + '/:collection/:name/:attribute.:ext(less|js|html)');
var options = {
collection: req.params.collection,
- attribute: req.params.attribute,
- ext: req.params.ext,
- query: {name: req.params.name}
+ attribute: req.params.attribute,
+ ext: req.params.ext,
+ query: {name: req.params.name}
};
handlers.getAttribute(options,
responder(config, options, res, next)
@@ -53,14 +53,14 @@ module.exports = function (app, handlers, markers, config) {
}
);
- route = config.api.content + '/content/:collection/:name.:ext(json)';
+ route = config.api.content + '/:collection/:name.:ext(json)';
app.get(route,
function getContentByName(req, res, next) {
- config.debug && config.debug('/content/:collection/:name.:ext(json)');
+ config.debug && config.debug(config.api.content + '/:collection/:name.:ext(json)');
var options = {
collection: req.params.collection,
- ext: req.params.ext,
- query: {name: req.params.name}
+ ext: req.params.ext,
+ query: {name: req.params.name}
};
handlers.getContent(options,
responder(config, options, res, next)
@@ -72,19 +72,20 @@ module.exports = function (app, handlers, markers, config) {
route = config.api.preview + '/:collection/:name.:ext(html|md)';
app.get(route,
function getPreviewContent(req, res, next) {
- config.debug && config.debug('/page/:collection/:name.:ext(html|md)');
+ config.debug && config.debug(config.api.preview + '/:collection/:name.:ext(html|md)');
var options = {
collection: req.params.collection,
- ext: req.params.ext,
- query: {name: req.params.name},
- req: { query: req.query || {},
+ ext: req.params.ext,
+ query: {name: req.params.name},
+ req: {
+ query: req.query || {},
headers: req.headers
}
};
if (options.ext === 'md') {
- var attribute_parts = options.query.name.split('.');
+ var attribute_parts = options.query.name.split('.');
var markdownDocument = markers.createTag('markdown', options.collection, attribute_parts[0], attribute_parts[1]);
- return handlers.getPreviewHTML(markdownDocument, { req: options.req },
+ return handlers.getPreviewHTML(markdownDocument, {req: options.req},
responder(config, options, res, next)
);
}
@@ -94,20 +95,21 @@ module.exports = function (app, handlers, markers, config) {
}
if (result) {
var attribute_parts = options.query.name.split('.');
- var attribute = attribute_parts[attribute_parts.length - 1];
+ var attribute = attribute_parts[attribute_parts.length - 1];
var attribute_value = result[attribute];
if (attribute_value) {
- options.name = attribute_parts[0];
+ options.name = attribute_parts[0];
var preview_options = {
collection: options.collection,
- name: options.name,
- attribute: attribute,
- query: {_id: result._id},
- req: options.req
+ name: options.name,
+ attribute: attribute,
+ query: {_id: result._id},
+ req: options.req
};
config.debug && config.debug('getPreviewContent content', attribute_value);
- handlers.getPreviewHTML(attribute_value, preview_options,
+ handlers.getPreviewHTML(attribute_value,
+ preview_options,
responder(config, options, res, next)
);
} else {
@@ -124,7 +126,7 @@ module.exports = function (app, handlers, markers, config) {
route = config.api.importer + '/:filename';
app.get(route, function importFile(req, res, next) {
var filename = path.resolve(config.statics.importer_path, req.params.filename);
- config.debug && config.debug('/importer/:filename', filename);
+ config.debug && config.debug(config.api.importer + '/:filename', filename);
fs.readFile(filename, 'utf-8', function handleFileContent(err, sub_doc) {
if (err) {
config.error && config.error('ERR readFile', filename, err);
diff --git a/lib/share.js b/lib/share.js
index 32be6ae..9023fff 100644
--- a/lib/share.js
+++ b/lib/share.js
@@ -1,19 +1,19 @@
+'use strict';
var ShareJS = require('share');
module.exports = function (config, app, db) {
- "use strict";
// share wraps express app with http.Server
- if (config
- && config.share
- && config.share.db
- && config.share.db.type === 'mongo') {
+ if (config &&
+ config.share &&
+ config.share.db &&
+ config.share.db.type === 'mongo') {
config.share.db.client = db;
}
var server = ShareJS.server.attach(app, config.share);
- var model = app.model;
+ var model = app.model;
return {
server: server,
- model: model
+ model: model
};
};
diff --git a/lib/shareHandlers.js b/lib/shareHandlers.js
index 422e29a..6de2c1a 100644
--- a/lib/shareHandlers.js
+++ b/lib/shareHandlers.js
@@ -1,5 +1,5 @@
+'use strict';
module.exports = function (config, model, mongoDataInstance) {
- "use strict";
var timers = {};
function handleMongoGetResult(options) {
@@ -13,18 +13,18 @@ module.exports = function (config, model, mongoDataInstance) {
if (options.type === 'json') {
result[options.attribute] = {};
} else {
- result[options.attribute] = "";
+ result[options.attribute] = '';
}
}
notFound = true;
} else {
- config.error && config.error('ERR1 handleMongoGetResult.handleResult Error retrieving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err);
+ config.error && config.error('ERR1 handleMongoGetResult.handleResult Error retrieving document ', options.collection, JSON.stringify(options.query), options.attribute || '', err);
}
}
if (result || notFound) {
var operation = null;
config.debug && config.debug('handleMongoGetResult options', options, result);
- var data = result;
+ var data = result;
if (options.attribute) {
data = result[options.attribute];
}
@@ -33,13 +33,19 @@ module.exports = function (config, model, mongoDataInstance) {
if (data instanceof String) {
data = JSON.parse(data);
}
- operation = { op: [
- { p: [], oi: data, od: null }
- ], v: version };
+ operation = {
+ op: [
+ {p: [], oi: data, od: null}
+ ],
+ v: version
+ };
} else if (options.type === 'text') {
- operation = { op: [
- {i: data, p: 0}
- ], v: version };
+ operation = {
+ op: [
+ {i: data, p: 0}
+ ],
+ v: version
+ };
}
if (operation) {
model.applyOp(options.documentId, operation, function appliedOp(error, version) {
@@ -60,13 +66,13 @@ module.exports = function (config, model, mongoDataInstance) {
var splitId = documentId.split(':');
var options = {
documentId: documentId,
- type: splitId[0],
+ type: splitId[0],
collection: splitId[1],
- attribute: null
+ attribute: null
};
if (splitId.length === 4) {
// options.query = {_id: splitId[2]};
- options.query = {name: splitId[2]};
+ options.query = {name: splitId[2]};
options.attribute = splitId[3];
mongoDataInstance.getMongoAttribute(options, handleMongoGetResult(options));
} else {
@@ -79,15 +85,18 @@ module.exports = function (config, model, mongoDataInstance) {
function handleMongoSetResult(options, current, callback) {
function handleResult(err, result) {
if (err) {
- config.error && config.error('ERR1 handleMongoSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err);
+ config.error && config.error('ERR1 handleMongoSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || '', err);
return callback && callback(err);
}
config.debug && config.debug('current', current, 'result', result, 'options', options);
if ((!current || !current.name) && (result.name || options.name)) {
- var name = result.name || options.name;
- var operation = { op: [
- { p: ['name'], oi: name, od: null }
- ], v: options.operation.v };
+ var name = result.name || options.name;
+ var operation = {
+ op: [
+ {p: ['name'], oi: name, od: null}
+ ],
+ v: options.operation.v
+ };
model.applyOp(options.documentId, operation, function appliedOp(error, version) {
config.debug && config.debug('setResult applyOp version', version);
if (error) {
@@ -97,7 +106,7 @@ module.exports = function (config, model, mongoDataInstance) {
return callback && callback(null, version);
});
} else {
- return callback(null, null);
+ return callback && callback(null, null);
}
}
@@ -107,11 +116,11 @@ module.exports = function (config, model, mongoDataInstance) {
function handleMongoAttributeSetResult(options, current, callback) {
function handleResult(err, result) {
if (err) {
- config.error && config.error('ERR1 handleMongoAttributeSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err);
- return callback(err);
+ config.error && config.error('ERR1 handleMongoAttributeSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || '', err);
+ return callback && callback(err);
}
config.debug && config.debug('current', current, 'result', result);
- return callback(null, null);
+ return callback && callback(null, null);
}
return handleResult;
@@ -160,31 +169,31 @@ module.exports = function (config, model, mongoDataInstance) {
return;
}
- var splitId = documentId.split(':');
- var options = {
+ var splitId = documentId.split(':');
+ var options = {
documentId: documentId,
- type: splitId[0],
+ type: splitId[0],
collection: splitId[1],
- name: splitId[2],
- attribute: null,
- operation: operation,
- no_share: true // prevent circular updates.
+ name: splitId[2],
+ attribute: null,
+ operation: operation,
+ no_share: true // prevent circular updates.
};
- var timer = {
+ var timer = {
current: current,
options: options
};
var attribute = false;
if (splitId.length === 4) {
// options.query = {_id: splitId[2]};
- options.query = {name: splitId[2]};
+ options.query = {name: splitId[2]};
options.attribute = splitId[3];
- attribute = true;
+ attribute = true;
} else {
options.query = {name: splitId[2]};
}
if (timers[documentId]) {
- timer.timer_id = timers[documentId].timer_id;
+ timer.timer_id = timers[documentId].timer_id;
timers[documentId] = timer;
config.debug && config.debug('resetting timer', documentId);
} else {
diff --git a/package.json b/package.json
index 6ea0393..1bb58f2 100644
--- a/package.json
+++ b/package.json
@@ -1,45 +1,45 @@
{
- "name": "Prototyper",
- "version": "0.0.1",
- "main": "server.js",
- "config" : {
- "port" : "8000"
+ "name": "Prototyper",
+ "version": "0.0.1",
+ "main": "server.js",
+ "config": {
+ "port": "8000"
},
- "engine": "node 0.10.4",
- "private": "true",
- "dependencies": {
- "share": "~0.6.0",
- "connect": "~2.7.9",
- "express": "~3.2.4",
- "bson": "~0.1.8",
- "mongodb": "~1.2.14",
+ "engine": "node 0.10.38",
+ "private": "true",
+ "dependencies": {
+ "share": "~0.6.0",
+ "connect": "~2.7.9",
+ "express": "~3.2.4",
+ "bson": "~0.1.8",
+ "mongodb": "~1.2.14",
"handlebars": "~1.0.10",
"underscore": "~1.4.4",
- "less": "~1.3.3",
- "when": "~2.1.0",
- "markdown": "~0.4.0",
- "async": "~0.2.8"
+ "less": "~1.3.3",
+ "when": "~2.1.0",
+ "markdown": "~0.4.0",
+ "async": "~0.2.8"
},
"devDependencies": {
"sockjs": "~0.3.7",
- "chai": "*",
- "mocha": "*",
- "sinon": "*",
- "groc": "*"
+ "chai": "*",
+ "mocha": "*",
+ "sinon": "*",
+ "groc": "*"
},
- "repository": "git://github.com/aikomastboom/Prototyper.git",
- "author": "Aiko Mastboom",
- "license": "Unknown",
- "readmeFilename": "README.md",
- "directories": {
+ "repository": "git://github.com/aikomastboom/Prototyper.git",
+ "author": "Aiko Mastboom",
+ "license": "Unknown",
+ "readmeFilename": "README.md",
+ "directories": {
"test": "test"
},
- "description": "README.md",
- "scripts": {
- "test": "./node_modules/.bin/mocha",
+ "description": "README.md",
+ "scripts": {
+ "test": "./node_modules/.bin/mocha",
"install": "./bin/installit",
- "deploy": "./bin/deployit",
- "doc":"./bin/docit",
- "cov": "./bin/coverit"
+ "deploy": "./bin/deployit",
+ "doc": "./bin/docit",
+ "cov": "./bin/coverit"
}
}
diff --git a/server.js b/server.js
index 5b96366..1886ff4 100644
--- a/server.js
+++ b/server.js
@@ -1,81 +1,101 @@
-"use strict";
-process.title = "Prototyper";
+'use strict';
+process.title = 'Prototyper';
-var connect = require('connect');
-var express = require('express');
-var MongoClient = require('mongodb').MongoClient;
-var addRoutes = require('./lib/routes.js');
-var shareServer = require('./lib/share.js');
+var connect = require('connect');
+var express = require('express');
+var MongoClient = require('mongodb').MongoClient;
+var addRoutes = require('./lib/routes.js');
+var shareServer = require('./lib/share.js');
var shareHandlers = require('./lib/shareHandlers.js');
-var mongoData = require('./lib/mongoData.js');
-var preview = require('./lib/preview.js');
-var importer = require('./lib/importer.js');
-var handlers = require('./lib/handlers.js');
-var markers = require('./lib/markers.js');
-var helpers = require('./lib/helpers.js');
+var mongoData = require('./lib/mongoData.js');
+var preview = require('./lib/preview.js');
+var importer = require('./lib/importer.js');
+var handlers = require('./lib/handlers.js');
+var markers = require('./lib/markers.js');
+var helpers = require('./lib/helpers.js');
var config = {
- debug: function () {
+ debug: function () {
if (process.env.DEBUG) {
var error = arguments[0] && arguments[0].message ||
arguments[1] && arguments[1].message ||
arguments[2] && arguments[2].message;
- var args = Array.prototype.slice.call(arguments);
- var log = { level: 'debug', message: args, timestamp: Date.now(), error: error};
+ var args = Array.prototype.slice.call(arguments);
+ var log = {
+ level: 'debug',
+ message: args,
+ timestamp: Date.now(),
+ error: error
+ };
console.log(JSON.stringify(log));
}
},
- info: function () {
- var error = arguments[0] && arguments[0].message ||
- arguments[1] && arguments[1].message ||
- arguments[2] && arguments[2].message;
- var args = Array.prototype.slice.call(arguments);
- var log = { level: 'info', message: args, timestamp: Date.now(), error: error};
- console.log(JSON.stringify(log));
- },
- warn: function () {
- var error = arguments[0] && arguments[0].message ||
- arguments[1] && arguments[1].message ||
- arguments[2] && arguments[2].message;
- var args = Array.prototype.slice.call(arguments);
- var log = { level: 'warn', message: args, timestamp: Date.now(), error: error};
- console.warn(JSON.stringify(log));
- },
- error: function () {
+ info: function () {
var error = arguments[0] && arguments[0].message ||
arguments[1] && arguments[1].message ||
arguments[2] && arguments[2].message;
- var args = Array.prototype.slice.call(arguments);
- var log = { level: 'error', message: args, timestamp: Date.now(), error: error};
+ var args = Array.prototype.slice.call(arguments);
+ var log = {
+ level: 'info',
+ message: args,
+ timestamp: Date.now(),
+ error: error
+ };
+ console.log(JSON.stringify(log));
+ },
+ warn: function () {
+ var error = arguments[0] && arguments[0].message ||
+ arguments[1] && arguments[1].message ||
+ arguments[2] && arguments[2].message;
+ var args = Array.prototype.slice.call(arguments);
+ var log = {
+ level: 'warn',
+ message: args,
+ timestamp: Date.now(),
+ error: error
+ };
+ console.warn(JSON.stringify(log));
+ },
+ error: function () {
+ var error = arguments[0] && arguments[0].message ||
+ arguments[1] && arguments[1].message ||
+ arguments[2] && arguments[2].message;
+ var args = Array.prototype.slice.call(arguments);
+ var log = {
+ level: 'error',
+ message: args,
+ timestamp: Date.now(),
+ error: error
+ };
console.error(JSON.stringify(log));
},
- port: process.env.npm_package_config_port || 8000,
- mongo: {
- server: "mongodb://localhost:27017/Prototyper",
- options: {
- db: {
+ port: process.env.npm_package_config_port || 8000,
+ mongo: {
+ server: 'mongodb://localhost:27017/Prototyper',
+ options: {
+ db: {
native_parser: true,
- fsync: true
+ fsync: true
},
server: {
- maxPoolSize: 10,
+ maxPoolSize: 10,
auto_reconnect: true
}
},
savedelay: 200
},
- share: {
- sockjs: {
- prefix: '',
- response_limit: 128 * 1024,
- websocket: true,
- jsessionid: false,
- heartbeat_delay: 25000,
+ share: {
+ sockjs: {
+ prefix: '',
+ response_limit: 128 * 1024,
+ websocket: true,
+ jsessionid: false,
+ heartbeat_delay: 25000,
disconnect_delay: 5000,
- log: function(severity, line) {
+ log: function (severity, line) {
if (process.env.DEBUG) {
if (severity === 'info') {
- config.info && config.info(severity,line);
+ config.info && config.info(severity, line);
} else if (severity === 'error') {
config.error && config.error(severity, line);
} else {
@@ -83,29 +103,29 @@ var config = {
}
}
},
- sockjs_url: 'https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js'
+ sockjs_url: 'https://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js'
},
staticpath: '/lib/share',
- db: {type: 'none'}
+ db: {type: 'none'}
// db: {
// type: 'mongo',
// opsCollectionPerDoc: false
// }
},
- api: {
- content: '/content',
- data: '/data',
- preview: '/page',
+ api: {
+ content: '/content',
+ data: '/data',
+ preview: '/page',
importer: '/importer'
},
statics: {
dev_favicon_path: __dirname + '/public/favicon_dev.ico',
- importer_path: __dirname + '/public',
- public_path: __dirname + '/public',
- doc_path: __dirname + '/doc',
- markdown_client: __dirname + '/node_modules/markdown/lib',
- ace_client: __dirname + '/node_modules/share/examples/lib/ace',
- async_client: __dirname + '/node_modules/async/lib'
+ importer_path: __dirname + '/public',
+ public_path: __dirname + '/public',
+ doc_path: __dirname + '/doc',
+ markdown_client: __dirname + '/node_modules/markdown/lib',
+ ace_client: __dirname + '/node_modules/share/examples/lib/ace',
+ async_client: __dirname + '/node_modules/async/lib'
}
};
@@ -119,10 +139,12 @@ express.static.mime.define({
if (process.env.DEBUG) {
//app.use(connect.logger());
- var stream = { write: function(str) {
- config.debug && config.debug(str);
- }};
- app.use(connect.logger({ immediate: false, format: 'dev', stream: stream }));
+ var stream = {
+ write: function (str) {
+ config.debug && config.debug(str);
+ }
+ };
+ app.use(connect.logger({immediate: false, format: 'dev', stream: stream}));
}
//noinspection JSUnresolvedFunction
app.use(express.compress());
@@ -155,8 +177,8 @@ MongoClient.connect(config.mongo.server, config.mongo.options, function connecti
}
config.debug && config.debug('database connected');
- var share = shareServer(config, app, db);
- var model = share.model;
+ var share = shareServer(config, app, db);
+ var model = share.model;
var server = share.server;
config.debug && config.debug('share attached');
@@ -187,13 +209,24 @@ MongoClient.connect(config.mongo.server, config.mongo.options, function connecti
function exit(code) {
db.close();
- process.exit(code);
+ // Probably there are also some other listeners for uncaughtException,
+ // so we postpone process.exit
+ process.nextTick(function () {
+ process.exit(code);
+ });
}
+ process.on('uncaughtException', function (err) {
+ config.error && config.error('HALTING ON UNCAUGHT EXCEPTION:' + err.message, err);
+ config.error && config.error(err.stack);
+ config.error && config.error('EXIT 1');
+ return exit(1);
+ });
+
server.on('error', function (err) {
config.error && config.error('Server error', err);
if (err.code && err.code === 'EADDRINUSE') {
- exit(2);
+ return exit(2);
}
});
diff --git a/test/test.helpers.js b/test/test.helpers.js
index cec80d9..90811ce 100644
--- a/test/test.helpers.js
+++ b/test/test.helpers.js
@@ -1,17 +1,18 @@
+'use strict';
+//noinspection JSUnresolvedVariable
var libpath = process.env.PROTOTYPER_COV ? '../lib-cov' : '../lib';
-var helpers = require(libpath + '/helpers.js');
-var markers = require(libpath + '/markers.js');
-var chai = require('chai');
+var helpers = require(libpath + '/helpers.js');
+var markers = require(libpath + '/markers.js');
+var chai = require('chai');
chai.config.includeStack = true; // defaults to false
chai.config.showDiff = false; // defaults to false
var expect = chai.expect;
-var when = require('when');
+var when = require('when');
describe('Helpers', function () {
- "use strict";
- var config = {
+ var config = {
debug: function () {
//console.log(arguments);
},
@@ -20,10 +21,10 @@ describe('Helpers', function () {
}
};
var markersInstance = markers(config);
- var marker_prefix = '';
- var helper = helpers({
- prefix: marker_prefix,
+ var marker_prefix = '';
+ var helper = helpers({
+ prefix: marker_prefix,
postfix: marker_postfix
});
@@ -52,7 +53,7 @@ describe('Helpers', function () {
};
}
- var i, values = [ null, undefined, '', 'hello', {}, []];
+ var i, values = [null, undefined, '', 'hello', {}, []];
for (i = 0; i < values.length; i += 1) {
it('should ignore non text input ' + values[i], testText(values[i]));
}
@@ -62,7 +63,7 @@ describe('Helpers', function () {
it('should call getReplacement fail on error', function (done) {
var marker = '';
- var text = 'hello' + marker + 'world';
+ var text = 'hello' + marker + 'world';
function getReplacement(result, callback) {
expect(result).to.be.equal(marker);
@@ -84,7 +85,7 @@ describe('Helpers', function () {
it('should call getReplacement (once)', function (done) {
var marker = '';
- var text = 'Hello' + marker + 'World' + marker + '!!';
+ var text = 'Hello' + marker + 'World' + marker + '!!';
function getReplacement(result, callback) {
expect(result).to.be.equal(marker);
@@ -92,7 +93,7 @@ describe('Helpers', function () {
callback(null, {});
}
- var once = true;
+ var once = true;
var promise = helper.replace(text, null, getReplacement, once);
expect(when.isPromise(promise)).to.be.ok;
promise.then(
@@ -117,18 +118,19 @@ describe('Helpers', function () {
it('should call getReplacement', function (done) {
var marker = '';
- var text = 'Hello' + marker + 'World' + marker + '!!';
+ var text = 'Hello' + marker + 'World' + marker + '!!';
function getReplacement(result, callback) {
expect(result).to.be.equal(marker);
expect(callback).to.be.a('function');
callback(null, {
regExp: new RegExp('What?'),
- value: '#'});
+ value: '#'
+ });
}
- var once = false;
+ var once = false;
var promise = helper.replace(text, null, getReplacement, once);
expect(when.isPromise(promise)).to.be.ok;
promise.then(
@@ -161,10 +163,10 @@ describe('Helpers', function () {
it('should handle variable tags', function (done) {
var marker_tag = 'test__([A-Za-z0-9]+)';
- var marker1 = '';
- var marker2 = '';
- var text = 'Hello' + marker1 + 'World' + marker2 + '!!';
- var called = 0;
+ var marker1 = '';
+ var marker2 = '';
+ var text = 'Hello' + marker1 + 'World' + marker2 + '!!';
+ var called = 0;
function getReplacement(result, callback) {
if (called) {
@@ -176,11 +178,12 @@ describe('Helpers', function () {
expect(callback).to.be.a('function');
callback(null, {
regExp: new RegExp('What?'),
- value: '#'});
+ value: '#'
+ });
}
- var once = false;
+ var once = false;
var promise = helper.replace(text, marker_tag, getReplacement, once);
expect(when.isPromise(promise)).to.be.ok;
promise.then(
@@ -209,12 +212,12 @@ describe('Helpers', function () {
it('should handle tags in tags', function (done) {
var marker_tag = 'test_([A-Za-z0-9]+)__([\\w\\W]*?)__\\1_test';
- var marker1 = '';
- var marker2 = '';
- var marker3 = '';
- var text = 'Hello' + marker1 + 'World' + marker2 + '!!' + marker3 +
+ var marker1 = '';
+ var marker2 = '';
+ var marker3 = '';
+ var text = 'Hello' + marker1 + 'World' + marker2 + '!!' + marker3 +
'Greetings' + marker1 + 'Earthlings' + marker3 + '!!' + marker2;
- var called = 0;
+ var called = 0;
function getReplacement(result, callback) {
//console.log('result',called,result);
@@ -229,11 +232,12 @@ describe('Helpers', function () {
expect(callback).to.be.a('function');
callback(null, {
regExp: new RegExp('What?'),
- value: '#'});
+ value: '#'
+ });
}
- var once = false;
+ var once = false;
var promise = helper.replace(text, marker_tag, getReplacement, once);
expect(when.isPromise(promise)).to.be.ok;
promise.then(
@@ -278,7 +282,7 @@ describe('Helpers', function () {
};
}
- var i, values = [ null, undefined, '', 'hello', {}, []];
+ var i, values = [null, undefined, '', 'hello', {}, []];
for (i = 0; i < values.length; i += 1) {
it('should return input when there are no promisses ' + values[i], testText(values[i]));
}
diff --git a/test/test.mongoData.js b/test/test.mongoData.js
index c286505..27469e3 100644
--- a/test/test.mongoData.js
+++ b/test/test.mongoData.js
@@ -1,12 +1,13 @@
-"use strict";
-var libPath = process.env.PROTOTYPER_COV ? '../lib-cov' : '../lib';
-var chai = require('chai');
+'use strict';
+//noinspection JSUnresolvedVariable
+var libPath = process.env.PROTOTYPER_COV ? '../lib-cov' : '../lib';
+var chai = require('chai');
chai.config.includeStack = true; // defaults to false
chai.config.showDiff = false; // defaults to false
var expect = chai.expect;
var mongoData = require(libPath + '/mongoData.js');
-var config = {
+var config = {
debug: function () {
//console.log(arguments);
},
@@ -35,34 +36,41 @@ describe('mongoData', function () {
throw new Error('fail:' + JSON.stringify(arguments));
}
- var col = {findOne: findOne};
- var db = { collection: function (c, cb) {
- //console.log('collection arguments', arguments);
- if (c === 'test_error') {
- return cb(new Error(c));
+ var col = {findOne: findOne};
+ var db = {
+ collection: function (c, cb) {
+ //console.log('collection arguments', arguments);
+ if (c === 'test_error') {
+ return cb(new Error(c));
+ }
+ return cb(null, col);
}
- return cb(null, col);
- }};
- var shareModel = {};
- var option_list = [
+ };
+ var shareModel = {};
+ var option_list = [
{}, // no collection
{query: 'q'}, // no collection
{collection: 'test_error'}, // bad collection
{collection: 'col'}, // no query
- {collection: 'no_hex',
- query: {_id: 'id'} // not a hexString
+ {
+ collection: 'no_hex',
+ query: {_id: 'id'} // not a hexString
},
- {collection: 'no_col', // trigger findOne error
- query: {_id: '123456789012345678901234'}
+ {
+ collection: 'no_col', // trigger findOne error
+ query: {_id: '123456789012345678901234'}
},
- {collection: 'col', // trigger null result
- query: {_id: '234567890123456789012345'}
+ {
+ collection: 'col', // trigger null result
+ query: {_id: '234567890123456789012345'}
},
- {collection: 'col', // trigger '' result
- query: {_id: '345678901234567890123456'}
+ {
+ collection: 'col', // trigger '' result
+ query: {_id: '345678901234567890123456'}
},
- {collection: 'ok', // trigger 'ok' result
- query: {_id: '456789012345678901234567'}
+ {
+ collection: 'ok', // trigger 'ok' result
+ query: {_id: '456789012345678901234567'}
}
];
var mongoDataInstance = mongoData(config, db, shareModel);
@@ -91,7 +99,9 @@ describe('mongoData', function () {
}
for (i = 0; i < option_list.length; i += 1) {
- it('should handle arguments correctly', testArguments(option_list[i]));
+ it('should handle arguments correctly ' + JSON.stringify(option_list[i]),
+ testArguments(option_list[i])
+ );
}
});
});