Page MenuHomeSealhub

No OneTemporary

diff --git a/.jscsrc b/.jscsrc
index 7ed03497..2d0d7625 100644
--- a/.jscsrc
+++ b/.jscsrc
@@ -1,36 +1,39 @@
{
"validateIndentation": "\t",
+ "requireSpaceAfterBinaryOperators": true,
+ "requireSpaceBeforeBinaryOperators": true,
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true,
"beforeOpeningCurlyBrace": true
},
+ "disallowNewlineBeforeBlockStatements" : true,
"requireSpacesInNamedFunctionExpression": {
"beforeOpeningRoundBrace": true,
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInCallExpression": true,
"requireSpacesInFunctionDeclaration": {
"beforeOpeningRoundBrace": true,
"beforeOpeningCurlyBrace": true
},
"requireSpacesInForStatement": true,
"requireSpaceBeforeKeywords": [
"else",
"while",
"catch"
],
"requireSpaceAfterKeywords": [
"do",
"for",
"if",
"else",
"switch",
"case",
"try",
"catch",
"while",
"with",
"return",
"typeof"
]
-}
\ No newline at end of file
+}
diff --git a/lib/base-chips/field_type.boolean.js b/lib/base-chips/field_type.boolean.js
index 614ddce1..0c4d3d6b 100644
--- a/lib/base-chips/field_type.boolean.js
+++ b/lib/base-chips/field_type.boolean.js
@@ -1,35 +1,35 @@
var Sealious = require("sealious");
var Promise = require("bluebird");
var field_type_boolean = new Sealious.ChipTypes.FieldType({
name: "boolean",
get_description: function(context, params){
return "Boolean value. True or false. Can be a string: \"true\" or \"false\".";
},
is_proper_value: function(accept, reject, context, params, value){
- if (typeof value == "boolean") {
+ if (typeof value === "boolean") {
accept();
- } else if (value == 1 || value == 0) {
+ } else if (value.toString() === "1" || value.toString() === "0") {
accept();
- } else if (typeof value == "string" && (value.toLowerCase() == "true" || value.toLowerCase() == "false")) {
+ } else if (typeof value === "string" && (value.toLowerCase() === "true" || value.toLowerCase() === "false")) {
accept();
} else {
- reject("Value `" + value + "`" + " is not boolean format.");
+ reject(`Value '${value}' is not boolean format.`);
}
},
encode: function(context, params, value){
- if (typeof value == "boolean") {
+ if (typeof value === "boolean") {
return value;
- } else if (value == 1) {
+ } else if (value.toString() === "1") {
return true;
- } else if (value == 0) {
+ } else if (value.toString() === "0") {
return false;
- } else if (typeof value == "string") {
- if (value.toLowerCase() == "true") {
+ } else if (typeof value === "string") {
+ if (value.toLowerCase() === "true") {
return true;
- } else if (value.toLowerCase() == "false") {
+ } else if (value.toLowerCase() === "false") {
return false
}
}
}
-});
\ No newline at end of file
+});
diff --git a/lib/base-chips/field_type.color.js b/lib/base-chips/field_type.color.js
index 011a1a4e..253aad64 100644
--- a/lib/base-chips/field_type.color.js
+++ b/lib/base-chips/field_type.color.js
@@ -1,22 +1,23 @@
var Sealious = require("sealious");
var Promise = require("bluebird");
var Color = require("color");
var field_type_color = new Sealious.ChipTypes.FieldType({
name: "color",
is_proper_value: function(accept, reject, context, params, new_value){
try {
- if (typeof (new_value) === "string")
+ if (typeof (new_value) === "string"){
Color(new_value.toLowerCase());
- else
+ } else {
Color(new_value);
+ }
} catch (e){
reject("Value `" + new_value + "` could not be parsed as a color.");
}
accept();
},
encode: function(context, params, value_in_code){
var color = Color(value_in_code);
return color.hexString();
}
});
diff --git a/lib/base-chips/field_type.date.js b/lib/base-chips/field_type.date.js
index 8b0f189a..5cfacb6c 100644
--- a/lib/base-chips/field_type.date.js
+++ b/lib/base-chips/field_type.date.js
@@ -1,20 +1,20 @@
var Sealious = require("sealious");
var Promise = require("bluebird");
var field_type_date = new Sealious.ChipTypes.FieldType({
name: "date",
get_description: function(context, params){
return "Date standard ISO 8601 (YYYY-MM-DD)";
},
is_proper_value: function(accept, reject, context, params, date){
var date_in_string = date.toString();
var regex = /^([0-9]{4})-(0?[1-9]|1[0-2])-([0-2]?[0-9]|30|31)$/; //granulation_per_day
- if (regex.test(date_in_string) === false || Date.parse(date_in_string) === NaN) {
+ if (regex.test(date_in_string) === false || isNaN(Date.parse(date_in_string))) {
reject("Value `" + date + "`" + " is not date calendar format. Expected value standard IS0 8601 (YYYY-MM-DD)");
} else {
accept();
}
}
-});
\ No newline at end of file
+});
diff --git a/lib/base-chips/field_type.float.js b/lib/base-chips/field_type.float.js
index 976b2afe..290fe933 100644
--- a/lib/base-chips/field_type.float.js
+++ b/lib/base-chips/field_type.float.js
@@ -1,21 +1,21 @@
var Sealious = require("sealious");
var Promise = require("bluebird");
var field_type_float = new Sealious.ChipTypes.FieldType({
name: "float",
get_description: function(context, params){
return "Float number."
},
is_proper_value: function(accept, reject, context, params, number){
var test = parseFloat(number);
- if (test === null || test === NaN || isNaN(number) === true) {
+ if (test === null || isNaN(test) || isNaN(number) === true) {
reject("Value `" + number + "` is not a float number format.");
} else {
accept();
}
},
encode: function(context, params, value_in_code){
var parsed_float = parseFloat(value_in_code);
return parsed_float;
}
-});
\ No newline at end of file
+});
diff --git a/lib/base-chips/field_type.hashed-text.js b/lib/base-chips/field_type.hashed-text.js
index 8e19050d..f3617031 100644
--- a/lib/base-chips/field_type.hashed-text.js
+++ b/lib/base-chips/field_type.hashed-text.js
@@ -1,67 +1,71 @@
var Sealious = require('sealious');
var Promise = require("bluebird");
var crypto = require("crypto");
var field_type_hashed_text = new Sealious.ChipTypes.FieldType({
name: "hashed-text",
extends: "text",
get_description: function(context, params){
var message = "Hash text with chosen algorithm (default md5)";
if (params && Object.keys(params).length > 0) {
message += " with ";
if (params.digits) {
message += "required digits: " + params.digits + " ";
}
if (params.capitals) {
message += "required capitals: " + params.capitals + " ";
}
}
return message;
},
is_proper_value: function(accept, reject, context, params, new_value){
var pattern_array = [];
if (params instanceof Object){
if (params.required_digits){
pattern_array.push(new RegExp("(.*[0-9]+.*){" + params.required_digits + "}"));
}
if (params.required_capitals){
pattern_array.push(new RegExp("(.*[A-Z]+.*){" + params.required_capitals + "}"));
}
- var isAccepted = pattern_array.map(n => n.test(new_value)).reduce( (a,b) => a&&b, true);
+ var isAccepted = pattern_array.map(n => n.test(new_value)).reduce( (a,b) => a && b, true);
if (isAccepted) {
accept();
}
else {
var digits = params.required_digits || "0";
var capitals = params.required_capitals || "0";
reject("It didn't fulfill the requirements: required digits - " + digits + ", required capitals " + capitals);
}
}
else {
accept();
}
},
encode: function(context, params, value_in_code){
var salt = "", algorithm = "md5";
if (params) {
if (params.salt){
salt = params.salt;
}
else if (params.algorithm){
algorithm = params.algorithm;
}
}
return new Promise(function(resolve, reject){
crypto.pbkdf2(value_in_code, salt, 4096, 64, algorithm, function(err, key){
- err ? reject(err) : resolve(key.toString('hex'));
+ if (err){
+ reject(err);
+ } else {
+ resolve(key.toString('hex'))
+ }
});
})
}
-})
\ No newline at end of file
+})
diff --git a/lib/base-chips/field_type.int.js b/lib/base-chips/field_type.int.js
index 94cf0949..b23f7bba 100644
--- a/lib/base-chips/field_type.int.js
+++ b/lib/base-chips/field_type.int.js
@@ -1,20 +1,20 @@
var Sealious = require("sealious");
var Promise = require("bluebird");
var field_type_int = new Sealious.ChipTypes.FieldType({
name: "int",
get_description: function(context, params){
return "An integer number."
},
is_proper_value: function(accept, reject, context, params, new_value){
- if (new_value === null || new_value === NaN || isNaN(new_value) === true || new_value % 1 !== 0) {
+ if (new_value === null || isNaN(new_value) === true || new_value % 1 !== 0) {
reject("Value `" + new_value + "` is not a int number format.");
} else {
accept();
}
},
encode: function(context, params, value_in_code){
var parsed_int = parseInt(value_in_code);
return parsed_int;
}
-});
\ No newline at end of file
+});
diff --git a/lib/chip-types/resource-type-field.js b/lib/chip-types/resource-type-field.js
index 9a29dea2..e768eeab 100644
--- a/lib/chip-types/resource-type-field.js
+++ b/lib/chip-types/resource-type-field.js
@@ -1,126 +1,126 @@
var Sealious = require("../main.js");
var Promise = require("bluebird");
/**
* !! resource_type is optional, needen only for nice errors
*
*/
function ResourceTypeField (declaration, resource_type) {
this.name = declaration.name;
this.type_name = declaration.type;
this.human_readable_name = declaration.human_readable_name || null;
if (!Sealious.ChipManager.chip_exists("field_type", this.type_name)) {
- throw new Sealious.Errors.DeveloperError("In declaration of resource type '" + resource_type.name +"': unknown field type '"+this.type_name+"' in field '"+this.name+"'.");
+ throw new Sealious.Errors.DeveloperError("In declaration of resource type '" + resource_type.name + "': unknown field type '" + this.type_name + "' in field '" + this.name + "'.");
}
this.params = declaration.params;
this.default_value = declaration.default_value;
this.type = Sealious.ChipManager.get_chip("field_type", declaration.type);
if (this.type.init) {
this.type.init();
}
this.required = declaration.required || false;
this.derived = declaration.derived || false;
}
ResourceTypeField.prototype = new function(){
/**
* Shorthand for ResourceTypeField.type.isProperValue
* @alias ResourceTypeField#isProperValue
* @param {object} value
* @return {Promise}
*/
this.check_value = function(context, value, old_value){
return this.type.is_proper_value(context, this.params, value, old_value);
}
/**
* Creates map object.name = value
* @param {String} name
* @param {String} value
* @return {Promise} resolving with object, where object.name = value
*/
function to_map (name, value) {
var obj = {};
obj[name] = value;
return Promise.resolve(obj);
}
/**
* Checks if field has previous value sensitive methods
* @params method_name:String - which field-type method to check
* @return {Boolean}
*/
this.is_old_value_sensitive = function(method_name){
return this.type.is_old_value_sensitive(method_name);
}
/**
* It's a wrapper, which checks if encode_value function uses context or previous value, and if it does adds it to arguments.
* @return {} encoded value
*/
this.encode_value = function(context, new_value, old_value){
return this.type.encode(context, this.params, new_value, old_value);
}
/**
* It's a wrapper, which checks if decode_value function uses context, and if it does adds it to arguments.
* @returns {} decoded value
*/
this.decode_value = function(context, value_in_database){
return this.type.decode(context, this.params, value_in_database);
}
/**
* Gets field signature: name, type, required, human redable name, params, validator function, default value
* @param {Boolean} with validator - - whether to include validator function in field description.
* Warning! If set to true, the output is not serializable in JSON.
* @returns {} field signature
*/
this.get_specification = function(with_validator){
//with_validator:boolean - whether to include validator function in field description. Warning! If set to true, the output is not serializable in JSON.
var field_specification = {};
field_specification.name = this.name;
field_specification.type = this.type_name;
field_specification.required = this.required;
field_specification.human_readable_name = (typeof this.human_readable_name === "string") ? this.human_readable_name : undefined;
field_specification.params = this.params;
field_specification.validate = this.check_value.bind(this);
field_specification.default_value = this.default_value;
return field_specification;
}
this.get_nice_name = function(){
return this.human_readable_name || this.name;
}
}
ResourceTypeField.test_start = function(){
describe("ResourceTypeField", function(){
describe("constructor", function(){
it("should throw a nice error when non-existent field type is provided in declaration", function(done){
try {
var test_field = new ResourceTypeField({
name: "test_field",
type: "truly_non_existent_field_type",
}, {
name: "fake_resource_type"
});
} catch (error) {
if (error.is_developer_fault === true) {
done();
} else {
done(new Error("But it threw a non-nice error."));
}
return;
}
done(new Error("But it didn't throw any error at all"));
});
})
})
}
module.exports = ResourceTypeField;
\ No newline at end of file
diff --git a/lib/chip-types/resource-type.js b/lib/chip-types/resource-type.js
index 7f635e77..f4b67b8f 100644
--- a/lib/chip-types/resource-type.js
+++ b/lib/chip-types/resource-type.js
@@ -1,313 +1,313 @@
var Sealious = require("../main.js");
var Promise = require("bluebird");
var merge = require("merge");
var Chip = require("./chip.js");
var ResourceTypeField = require("./resource-type-field.js");
/**
ResourceType constructor
@constructor
@params {object} declaration
Resource-type declaration syntax:
{
name: String,
fields: Array<FieldDescription>,
access_strategy?: AccessStrategyDescription
}
* name, required - the name of the resource-type. It becomes the name of the chip representing the resource type, as well. It has to be unique amongst all other resource-types.
* fields, required - an array of field descriptions. You can read about field description syntax below.
* access_strategy, optional. A hashmap or string compatible with access strategy description syntax, described below. Defaults to public.
*/
var ResourceType = function(declaration){
if (typeof declaration !== "object"){
throw new Sealious.Errors.DeveloperError("Tried to create a resource-type without a declaration");
}
Chip.call(this, true, "resource_type", declaration.name);
this.name = declaration.name;
this.human_readable_name = declaration.human_readable_name;
this.summary = declaration.summary;
this.fields = {};
this.references = {};
this.access_strategy = {
default: Sealious.ChipManager.get_chip("access_strategy", "public")
};
this._process_declaration(declaration);
}
ResourceType.prototype = new function(){
/*
Process declaration, creates fields and sets access strategy
@param {object} declaration - consistnent with resource type declaration syntax
@returns void
*/
this._process_declaration = function(declaration){
if (declaration){
if (declaration.fields){
for (var i = 0; i < declaration.fields.length; i++){
if (declaration.fields[i].params) {
if (typeof declaration.fields[i].params !== "object") {
throw new Sealious.Errors.ValidationError("In field `" + declaration.fields[i].name + "`: `params` is of wrong type, it should be an object")
}
}
}
this.add_fields(declaration.fields);
}
this.set_access_strategy(declaration.access_strategy);
}
}
/*
Adds field to resource type
@param {object} field_declaration - consistnent with field declaration syntax
{
name: String,
type: FieldTypeName,
human_readable_name?: String,
params?: Object
}
* name, required - a string representing the machine-readable name for the field. Should be short. No spaces allowed. All lower-case letters, the _ and - symbols are allowed.
* human_readable_name, optional - a string representing a human-readable version of the field’s name. No restrictions on what is and what is not allowed here. When not specified, the value of ‘name’ attribute is used instead.
* type, required - a string representing a resource-type name that is already registred in your Sealious application.
* params, optional - a hashmap of parameters that will be passed to the field-type. These parameters are also a part of the field’s signature. Defaults to {}.
@returns void
*/
this.add_field = function(field_declaration){
var field_object = new ResourceTypeField(field_declaration, this);
var field_name = field_object.name;
if (!this.fields[field_name]) {
this.fields[field_name] = field_object;
}
else {
- throw new Sealious.Errors.DeveloperError("Duplicate field names: '" + field_name + "' in resource: '" + this.name +"'" );
+ throw new Sealious.Errors.DeveloperError("Duplicate field names: '" + field_name + "' in resource: '" + this.name + "'" );
}
}
/*
Adds multiple fields to resource type
@param {array} field_declarations_array - array of declarations consistnent with field declaration syntax
@returns void
*/
this.add_fields = function(field_declarations_array){
for (var i in field_declarations_array){
var declaration = field_declarations_array[i];
this.add_field(declaration);
}
}
/*
Checks if resource type has_previous_value_sensitive_fields
@returns {boolean}
*/
this.has_previous_value_sensitive_fields = function(){
for (var field_name in this.fields){
if (this.fields[field_name].has_previous_value_sensitive_methods()){
return true;
}
}
return false;
}
/*
Checks if all values from given array are represented as fields resource type
@params {array} values - array of names of fields, which resource type should have
@returns {hashmap} validation_errors - hashmap of errors, if there was an unknown field there would be entry under key "missing_field_name" with value "unknown_field"
*/
function ensure_no_unknown_fields (values) {
var validation_errors = {};
for (var field_name in values){
if (this.fields[field_name] === undefined) {
validation_errors[field_name] = "unknown_field";
}
}
return validation_errors;
}
this.extend_with_missing_field_values_errors = function(current_validation_errors, values){
for (var i in this.fields) {
var field = this.fields[i];
if (field.required && values[field.name] === undefined){
current_validation_errors[field.name] = new Sealious.Errors.ValidationError("Missing value for field `" + field.get_nice_name() + "`");
}
}
}
this.validate_field_values = function(context, check_missing, values, old_values){
var self = this;
var existing_field_names = Object.keys(this.fields);
var validation_errors = {};
var validation_tasks = [];
for (var key in values){
var validation_promise;
if (values[key] === undefined){
//if this field is required, it will be detected by extend_with_missing_field_values_errors called below
continue;
}
var value = values[key];
if (existing_field_names.indexOf(key) === -1){
- validation_errors[key] = new Sealious.Errors.ValidationError("Wrong field name: '" + key +"'");
+ validation_errors[key] = new Sealious.Errors.ValidationError("Wrong field name: '" + key + "'");
} else {
var old_value = old_values ? old_values[key] : undefined;
validation_promise = self.fields[key].check_value(context, value, old_value).catch((function(key){
return function(error){
validation_errors[key] = error;
return Promise.resolve();
}
})(key));
}
validation_tasks.push(validation_promise);
}
return Promise.all(validation_tasks)
.then(function(){
if (check_missing){
self.extend_with_missing_field_values_errors(validation_errors, values);
}
var has_errors = false;
for (var key in validation_errors) {
//validation_errors is not an empty object
has_errors = true;
var error = validation_errors[key];
if (error.is_user_fault) {
validation_errors[key] = error.message;
} else {
return Promise.reject(error);
}
}
if (has_errors) {
return Promise.reject(new Sealious.Errors.ValidationError("There are problems with some of the provided values", validation_errors));
} else {
//validation_errors is empty, resolve
return Promise.resolve();
}
});
}
this.encode_field_values = function(context, body, old_body){
var promises = {};
for (var field_name in body){
var current_value = body[field_name];
- if (current_value===undefined){
+ if (current_value === undefined){
promises[field_name] = null;
} else {
var old_value = old_body && old_body[field_name];
promises[field_name] = this.fields[field_name].encode_value(context, current_value, old_value);
}
}
return Promise.props(promises);
}
/**
* Gets resource type specification
* @param {Boolean} with validator - - whether to include validator function in field description.
* Warning! If set to true, the output is not serializable in JSON.
* @returns {} resource type signature
*/
this.get_specification = function(with_validators){
//with_validators:boolean - whether to include validator functions in field descriptions. Warning! If set to true, the output is not serializable in JSON.
var resource_type_specification = {};
for (var field_name in this.fields){
var field_specification = this.fields[field_name].get_specification(with_validators);
resource_type_specification[field_name] = field_specification;
}
var specification = {
name: this.name,
human_readable_name: this.human_readable_name,
summary: this.summary,
fields: resource_type_specification
};
return specification;
}
this.get_specification_with_validators = function(){
return this.get_specification(true);
}
this.set_access_strategy = function(strategy_declaration){
var access_strategy_name;
if (typeof strategy_declaration === "string"){
access_strategy_name = strategy_declaration;
this.access_strategy = {
"default": Sealious.ChipManager.get_chip("access_strategy", access_strategy_name),
}
} else if (typeof strategy_declaration === "object"){
for (var action_name in strategy_declaration){
var access_strategy = Sealious.ChipManager.get_chip("access_strategy", strategy_declaration[action_name]);
this.access_strategy[action_name] = access_strategy;
}
}
}
this.get_access_strategy = function(action){
return this.access_strategy[action] || this.access_strategy["default"];
}
this.has_large_data_fields = function(){
for (var i in this.fields){
var field = this.fields[i];
if (field.type.handles_large_data){
return true;
}
}
return false;
}
this.is_old_value_sensitive = function(method_name){
for (var i in this.fields){
if (this.fields[i].type.is_old_value_sensitive(method_name)) {
return true;
}
}
return false;
}
/**
* Decodes multiple values, with proper decode value function
* @param {Context} context
* @param {Object} db_document - object representing encoded document from database
* @returns {Promise} resolving with object represeting decoded resource
*/
this.decode_values = function(context, values){
var decoded_values = {};
for (var key in this.fields) {
var value = values[key];
var field = this.fields[key];
if (field === undefined){
continue;
}
decoded_values[key] = field.decode_value(context, value);
}
return Promise.props(decoded_values);
}
/**
* Decodes an entry from datastorage
* @param {Context} context
* @param {Object} db_document - object representing encoded document from database
* @returns {Promise} resolving with object represeting decoded resource
*/
this.decode_db_entry = function(context, db_document){
var id = db_document.sealious_id;
var original_body = db_document.body;
return this.decode_values(context, original_body)
.then(function(decoded_body){
var ret = {
id: id,
type: db_document.type,
body: decoded_body,
created_context: db_document.created_context,
last_modified_context: db_document.last_modified_context,
}
return Promise.resolve(ret);
});
}
}
module.exports = ResourceType;
\ No newline at end of file
diff --git a/lib/core-services/resource-manager.js b/lib/core-services/resource-manager.js
index 6eabbede..94948540 100644
--- a/lib/core-services/resource-manager.js
+++ b/lib/core-services/resource-manager.js
@@ -1,288 +1,288 @@
var Sealious = require("../main.js");
var Promise = require("bluebird");
var ResourceRepresentation = require("../chip-types/resource-representation.js");
var assert = require("assert");
var UUIDGenerator = require("uid");
/**
* Manages resources in the database
* @class
*/
var ResourceManager = new function(){
this.name = "resources";
var self = this;
/**
* Creates a resource of given type
* @param {Context} context - context in which resource is being created
* @param {String} type_name - name of created resource's type, defined in resource type declaration
* @param {Object} body - data with which resource will be created wrapped in object, body.field_name should give us value of field "field_name"
* @returns {Promise} which resolves with created object
*/
this.create = function(context, type_name, body){
return Promise.try(function(){
var resource_type_object = Sealious.ChipManager.get_chip("resource_type", type_name);
var access_strategy = resource_type_object.get_access_strategy("create");
var old_values = {};
if (resource_type_object.is_old_value_sensitive("is_proper_value")) {
for (var i in resource_type_object.fields) {
var field = resource_type_object.fields[i];
old_values[field.name] = null;
}
}
var encoded_body = {};
var current_item;
if (access_strategy.item_sensitive){
current_item = null;
} else {
current_item = undefined;
}
return access_strategy.check(context, current_item)
.then(function(){
return resource_type_object.validate_field_values(context, true, body, old_values);
}).then(function(){
return resource_type_object.encode_field_values(context, body);
}).then(function(response){
encoded_body = response;
var newID = UUIDGenerator(10);
var resource_data = {
sealious_id: newID,
type: type_name,
body: encoded_body,
created_context: context.toObject(),
};
return Sealious.Datastore.insert("resources", resource_data, {});
}).then(function(inserted_document){
var database_entry = inserted_document;
return resource_type_object.decode_db_entry(context, database_entry);
})
})
}
/**
* Deletes resource of given id
* @param {Context} context - context
* @param {String} type_name - name of deleted resource's type, defined in resource type declaration
* @param {String} id - id of particular resource, which you want to delete
* @returns {Promise} witch resolves if resource had been successfully deleted
*/
this.delete = function(context, type_name, id){
return new Promise.try(function(){
var resource_type_object = Sealious.ChipManager.get_chip("resource_type", type_name);
var access_strategy = resource_type_object.get_access_strategy("delete");
return access_strategy.check(context)
.then(function(){
return Sealious.Datastore.find("resources", {
sealious_id: id
}, {})
.then(function(documents){
if (documents[0] === undefined) {
return Promise.reject(new Sealious.Errors.NotFound("resource of id " + id + " not found"));
} else {
return Sealious.Datastore.remove("resources", {sealious_id: id, type: type_name}, {});
}
})
})
.then(function(data){
return Promise.resolve();
});
})
}
/**
* Gets a resource of given id
* @param {Context} context - context
* @param {String} resource_id - id of particular resource
* @returns {Promise} which resolves with object representing resource, or rejects if resource with given id is not find
*/
this.get_by_id = function(context, resource_id){
return Promise.try(function(){
//var access_strategy = resource_type_object.get_access_strategy("get_by_id");
return Sealious.Datastore.find("resources", {
sealious_id: resource_id
}, {})
.then(function(documents){
if (documents[0] === undefined) {
return Promise.reject(new Sealious.Errors.NotFound("resource of id " + resource_id + " not found"));
} else {
var database_entry = documents[0];
var resource_type_name = database_entry.type;
var resource_type_object = Sealious.ChipManager.get_chip("resource_type", resource_type_name);
var ret = [];
ret[0] = resource_type_object;
ret[1] = resource_type_object.decode_db_entry(context, database_entry);
return Promise.all(ret);
}
})
.then(function(response){
var resource_type = response[0];
var resource_data = response[1];
var access_strategy = resource_type.get_access_strategy("retrieve");
return access_strategy.check(context, resource_data);
})
})
}
/**
* is used to filter in item sensitive access strategies. Returns a function that can be used with Promise.filter
* @param {Context} context - context in which resource is being created
* @param {} access_strategy -
*/
function filter_resource_list (context, access_strategy) {
return function(item){
return new Promise(function(resolve, reject){
access_strategy.check(context, item)
.then(function(){
resolve(true);
}).catch(function(){
resolve(false);
})
});
}
}
/**
* Returns list of resources of given type
* @param {Context} context - context in which resource is being created
* @param {String} type_name - name of resource type, defined in resource type declaration
* @returns {Promise} which resolves with array of objects, representing resources of given type
*/
this.list_by_type = function(context, type_name){
return Promise.try(function(){
var resource_type = Sealious.ChipManager.get_chip("resource_type", type_name);
var access_strategy = resource_type.get_access_strategy("retrieve");
var preliminary_access_strategy_check;
if (access_strategy.item_sensitive){
preliminary_access_strategy_check = Promise.resolve();
} else {
preliminary_access_strategy_check = access_strategy.check(context);
}
var get_items = preliminary_access_strategy_check.then(function(){
return Sealious.Datastore.find("resources", {
type: type_name
}, {}, {});
});
var decoded_items = get_items.map(resource_type.decode_db_entry.bind(resource_type, context));
var filtered_items;
if (access_strategy.item_sensitive){
filtered_items = decoded_items.then(function(items){
return Promise.filter(items, filter_resource_list(context, access_strategy));
});
} else {
filtered_items = decoded_items;
}
return filtered_items;
})
}
/**
* Returns list of resources, which match given restriction
* @param {Context} context - context in which resource is being created
* @param {Object} field_values - object representing our query ex. field_values.name = "cup" will find all resources, which field name has value "cup"
* @param {String} type - name of resource type, defined in resource type declaration
* @returns {Promise} which resolves with array of founded objects
*/
this.find = function(context, field_values, type){
var find_arguments = arguments;
return Promise.try(function(){
//throw new Error("ResourceManager.find not implemented.");
if (find_arguments.length === 2) {
type = null;
}
var query = {};
if (type){
query.type = type;
}
for (var field_name in field_values){
query["body." + field_name] = field_values[field_name];
}
return Sealious.Datastore.find("resources", query)
.then(function(documents){
var parsed_documents = documents.map(function(document){
return new ResourceRepresentation(document).getData()
});
return Promise.resolve(parsed_documents);
});
})
}
/**
* Replaces just the provided values. Equivalent of PATCH request
* @param {Context} context - context in which resource is being created
* @param {String} type_name - name of resource type, defined in resource type declaration
* @param {Object} field_values - object representing our query ex. field_values.name = "cup" will find all resources, which field name has value "cup"
* @param consider_empty_values - if set to true, values from values_to_patch will be deleted. Defaults to false.
*
* @returns {Promise} which resolves with array of founded objects
*/
this.patch_resource = function(context, type_name, resource_id, values_to_patch, consider_empty_values){
return Promise.try(function(){
var access_strategy;
var get_item;
- if (consider_empty_values===undefined){
+ if (consider_empty_values === undefined){
consider_empty_values = false;
}
//replaces just the provided values. Equivalent of PATCH request
var resource_type_object = Sealious.ChipManager.get_chip("resource_type", type_name);
access_strategy = resource_type_object.get_access_strategy();
if (access_strategy.item_sensitive || resource_type_object.is_old_value_sensitive()){
get_item = self.get_by_id(context, resource_id);
} else {
get_item = Promise.resolve({
body: {}
});
}
return get_item.then(function(item){
return access_strategy.check(context, item);
}).then(function(current_resource){
var old_values = current_resource.body;
return resource_type_object.validate_field_values(context, consider_empty_values, values_to_patch, old_values)
.then(function(){
return Promise.resolve(old_values);
})
}).then(function(old_values){
return resource_type_object.encode_field_values(context, values_to_patch, old_values && old_values.body);
}).then(function(encoded_values){
var query = {};
query.last_modified_context = context.toObject();
for (var field_name in encoded_values){
query["body." + field_name] = encoded_values[field_name];
}
if (Object.keys(query).length === 0){
return Promise.resolve();
} else {
return Sealious.Datastore.update("resources", {
sealious_id: resource_id
}, {
$set: query
})
}
}).then(function(){
return self.get_by_id(context, resource_id);
});
})
}
this.update_resource = function(context, type_name, resource_id, body){
return Promise.try(function(){
var type = Sealious.ChipManager.get_chip("resource_type", type_name);
for (var i in type.fields) {
var field = type.fields[i];
if (!body.hasOwnProperty(field.name)) {
body[field.name] = undefined;
}
}
return self.patch_resource(context, type_name, resource_id, body, true);
})
}
}
module.exports = ResourceManager;
diff --git a/lib/main.js b/lib/main.js
index a4c2279d..f2ec51d5 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -1,51 +1,51 @@
var path = require("path");
var Sealious = {};
module.exports = Sealious;
var Core = require("./core.js");
Sealious.Errors = require("./response/error.js");
Sealious.Response = require("./response/response.js");
Sealious.File = require("./data-structures/file.js");
Sealious.ChipManager = require("./chip-types/chip-manager.js");
Sealious.ConfigManager = require("./config/config-manager.js");
Sealious.PluginManager = require("./plugins/plugin-manager.js");
Sealious.Context = require("./context.js");
Sealious.Logger = require("./logger/logger.js");
Sealious.ResourceManager = require("./core-services/resource-manager.js");
Sealious.UserManager = require("./core-services/user_manager.js");
Sealious.FileManager = require("./core-services/file-manager.js");
Sealious.ChipTypes = {
"AccessStrategy": require("./chip-types/access-strategy.js"),
"Channel": require("./chip-types/channel.js"),
"Datastore": require("./chip-types/datastore.js"),
"FieldType": require("./chip-types/field-type.js"),
"ResourceType": require("./chip-types/resource-type.js"),
}
// prefix Sealious.ChipTypes[chip_type_name] to Sealious[chip_type_name]
for (var chip_type_name in Sealious.ChipTypes) {
if (chip_type_name === 'Datastore'){
chip_type_name += 'Creator';
}
Sealious[chip_type_name] = Sealious.ChipTypes[chip_type_name];
}
Sealious.init = function(){
require("./base-chips/_base-chips.js");
Sealious.PluginManager.load_plugins();
Sealious.Datastore = Sealious.ChipManager.get_datastore_chip();
}
Sealious.start = function(){
Core.check_version();
return Sealious.ChipManager.start_chips();
}
-module.exports = Sealious;
\ No newline at end of file
+module.exports = Sealious;
diff --git a/lib/plugins/plugin-manager.js b/lib/plugins/plugin-manager.js
index 7316790f..0ec16f19 100644
--- a/lib/plugins/plugin-manager.js
+++ b/lib/plugins/plugin-manager.js
@@ -1,63 +1,63 @@
var Sealious = require("../main.js");
var path = require("path");
var fs = require("fs");
var resolve = require("resolve");
var PluginManager = new function(){
function get_package_info_path (dir, package_name) {
var package_path = resolve.sync(package_name, { basedir: dir });
var package_info_path = null;
- while (package_info_path===null){
+ while (package_info_path === null){
var temp_path = path.resolve(package_path, "../package.json");
try {
fs.accessSync(temp_path, fs.F_OK);
package_info_path = temp_path;
} catch (e) {
package_path = path.resolve(package_path, "../");
}
}
return package_info_path;
}
function get_package_info (dir, package_name) {
return require(get_package_info_path(dir, package_name));
}
function is_sealious_plugin (dir, module_name) {
var plugin_package_info = get_package_info(dir, module_name);
- return plugin_package_info.keywords && plugin_package_info.keywords.indexOf("sealious-plugin")!==-1;
+ return plugin_package_info.keywords && plugin_package_info.keywords.indexOf("sealious-plugin") !== -1;
}
function load_plugins_from_dir (dir) {
var root = path.resolve(dir);
var pkgfile = path.join(root, 'package.json');
var pkg = require(pkgfile);
var dependencies = pkg.dependencies;
var required_sealious_plugins = Object.keys(dependencies).filter(is_sealious_plugin.bind({}, root));
if (required_sealious_plugins.length){
Sealious.Logger.debug(`${pkg.name} (${pkgfile}) requires: ${required_sealious_plugins.join(", ")}`)
for (var i in required_sealious_plugins){
var plugin_name = required_sealious_plugins[i];
var plugin_info_path = get_package_info_path(root, plugin_name);
var plugin_dir = path.resolve(plugin_info_path, "../");
load_plugins_from_dir(plugin_dir);
require(resolve.sync(plugin_name, {basedir: root}));
Sealious.Logger.info(`\t\u2713 ${plugin_name}`)
}
}
}
this.load_plugins = function(){
Sealious.Logger.info("Loading plugins...");
var sealious_dir = path.resolve(module.filename, "../../../");
- if (sealious_dir!=path.resolve("")){
+ if (sealious_dir !== path.resolve("")){
load_plugins_from_dir(sealious_dir);
}
load_plugins_from_dir("");
}
}
module.exports = PluginManager;
diff --git a/package.json b/package.json
index 52bea885..fe2d9887 100644
--- a/package.json
+++ b/package.json
@@ -1,64 +1,63 @@
{
"name": "sealious",
"homepage": "http://sealious.github.io/",
"version": "0.7.11",
"description": "A declarative framework for fast & easy app development.",
"main": "./lib/main.js",
"scripts": {
"prepublish": "require-self",
"test": "node ./tests/test.js",
"test-coverage": "istanbul cover ./tests/test.js",
"coveralls": "npm run test-coverage && cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
- "check-formatting": "jscs -c .jscsrc ./lib && echo \"\\n ✓ Code formatting O.K.!\\n\" || (echo \"\\nSome formatting errors found. Run 'npm run fix-formatting' to correct them.\\n\" && exit )",
+ "check-formatting": "jscs -c .jscsrc ./lib && echo \"\\n ✓ Code formatting O.K.!\\n\" || (echo \"\\nSome formatting errors found. Run 'npm run fix-formatting' to correct them.\\n\" && exit 1 )",
"fix-formatting": "jscs -c .jscsrc ./lib --fix",
- "check-hint": "jshint ./lib/chip-types/ ./lib/config/ ./lib/core-services/ ./lib/data-structures/ ./lib/logger/ ./lib/plugins/ ./lib/response/ ./lib/*.js",
- "hint": "jshint ./lib/chip-types/ ./lib/config/ ./lib/core-services/ ./lib/data-structures/ ./lib/logger/ ./lib/plugins/ ./lib/response/ ./lib/*.js && echo \"\\n ✓ Code guidelines O.K.!\\n\" || (echo \"\\nSome JSHint errors found. Fix errors and run 'npm run check-hint' to correct them.\\n\" && exit )"
+ "jshint": "jshint ./lib/*/*.js ./lib/*.js && echo \"\\n ✓ Code guidelines O.K.!\\n\" || (echo \"\\nSome JSHint errors found. Fix errors and run 'npm run check-hint' to correct them.\\n\" && exit 1)"
},
"repository": {
"type": "git",
"url": "https://github.com/Sealious/Sealious/"
},
"keywords": [
"sealious"
],
"author": "The Sealious team (http://github.com/Sealious)",
"license": "BSD-2-Clause",
"bugs": {
"url": "https://github.com/Sealious/Sealious/issues"
},
"dependencies": {
"Set": "~0.4.1",
"bluebird": "~2.9.9",
"clone": "^1.0.2",
"color": "latest",
"fs-extra": "^0.18.2",
"immutable": "^3.7.2",
"merge": "^1.2.0",
"require-dir": "^0.3.0",
"resolve": "^1.1.7",
"sanitize-html": "^1.6.1",
"sealious-datastore-tingo": "^0.1.5",
"sha1": "^1.1.0",
"uid": "0.0.2",
"winston": "^1.0.0"
},
"devDependencies": {
"coveralls": "^2.11.4",
"deep-equal": "^1.0.1",
"istanbul": "^0.4.1",
"jscs": "^2.1.1",
"jshint": "^2.9.1",
"mocha": "*",
"mocha-istanbul": "^0.2.0",
"pre-commit": "^1.1.1",
"require-self": "^0.1.0"
},
"pre-commit": {
"colors": true,
"run": [
"check-formatting",
- "hint"
+ "jshint"
],
"silent": false
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 11, 09:50 (17 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
984159
Default Alt Text
(42 KB)

Event Timeline