Page MenuHomeSealhub

No OneTemporary

diff --git a/lib/base-chips/access_strategy.just_owner.js b/lib/base-chips/access_strategy.just_owner.js
index 94f9c77f..3ec8be95 100644
--- a/lib/base-chips/access_strategy.just_owner.js
+++ b/lib/base-chips/access_strategy.just_owner.js
@@ -1,14 +1,14 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var JustOwner = new Sealious.ChipTypes.AccessStrategy({
name: "just_owner",
checker_function: function(context, item){
if (context.get("user_id") === item.created_context.user_id) {
return Promise.resolve();
} else {
return Promise.reject("Only the owner of this resource can perform this operation on this item.");
};
},
item_sensitive: true
});
\ No newline at end of file
diff --git a/lib/base-chips/access_strategy.noone.js b/lib/base-chips/access_strategy.noone.js
index db0d4069..9825beb1 100644
--- a/lib/base-chips/access_strategy.noone.js
+++ b/lib/base-chips/access_strategy.noone.js
@@ -1,10 +1,10 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var Public = new Sealious.ChipTypes.AccessStrategy({
name: "noone",
checker_function: function(context){
return Promise.reject("Noone gets in!");
},
item_sensitive: false,
});
\ No newline at end of file
diff --git a/lib/base-chips/access_strategy.public.js b/lib/base-chips/access_strategy.public.js
index 07be2674..4c745fd5 100644
--- a/lib/base-chips/access_strategy.public.js
+++ b/lib/base-chips/access_strategy.public.js
@@ -1,10 +1,10 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var Public = new Sealious.ChipTypes.AccessStrategy({
name: "public",
checker_function: function(context){
return Promise.resolve("Everybody is a winner!");
},
item_sensitive: false,
});
\ 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 9201e56b..614ddce1 100644
--- a/lib/base-chips/field_type.boolean.js
+++ b/lib/base-chips/field_type.boolean.js
@@ -1,35 +1,35 @@
-var Sealious = require("../main.js");
+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") {
accept();
} else if (value == 1 || value == 0) {
accept();
} else if (typeof value == "string" && (value.toLowerCase() == "true" || value.toLowerCase() == "false")) {
accept();
} else {
reject("Value `" + value + "`" + " is not boolean format.");
}
},
encode: function(context, params, value){
if (typeof value == "boolean") {
return value;
} else if (value == 1) {
return true;
} else if (value == 0) {
return false;
} else if (typeof value == "string") {
if (value.toLowerCase() == "true") {
return true;
} else if (value.toLowerCase() == "false") {
return false
}
}
}
});
\ No newline at end of file
diff --git a/lib/base-chips/field_type.date.js b/lib/base-chips/field_type.date.js
index 16ed6603..36acc700 100644
--- a/lib/base-chips/field_type.date.js
+++ b/lib/base-chips/field_type.date.js
@@ -1,24 +1,24 @@
-var Sealious = require("../main.js");
+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) {
reject("Value `" + date + "`" + " is not date calendar format. Expected value standard IS0 8601 (YYYY-MM-DD)");
} else {
accept();
}
},
encode: function(context, params, value_in_code){
var date_in_string = value_in_code.toString();
return Date.parse(date_in_string);
}
});
\ No newline at end of file
diff --git a/lib/base-chips/field_type.datetime.js b/lib/base-chips/field_type.datetime.js
index dda729e9..d33ad85b 100644
--- a/lib/base-chips/field_type.datetime.js
+++ b/lib/base-chips/field_type.datetime.js
@@ -1,20 +1,20 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var field_type_datetime = new Sealious.ChipTypes.FieldType({
name: "datetime",
get_description: function(context, params){
return "Timestamp - amount of miliseconds since epoch."
},
is_proper_value: function(accept, reject, context, params, datetime){
if (isNaN(datetime) === true || datetime % 1 !== 0) {
reject("Value `" + datetime + "`" + " is not datetime format. Only timestamps are accepted.");
} else {
accept();
}
},
encode: function(context, params, value_in_code){
var parsed_datetime = parseInt(value_in_code);
return parsed_datetime;
}
});
\ No newline at end of file
diff --git a/lib/base-chips/field_type.email.js b/lib/base-chips/field_type.email.js
index 927b16c9..e31767af 100644
--- a/lib/base-chips/field_type.email.js
+++ b/lib/base-chips/field_type.email.js
@@ -1,20 +1,20 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var field_type_email = new Sealious.ChipTypes.FieldType({
name: "email",
get_description: function(context, params){
return "Email address, like something@something.sth"
},
is_proper_value: function(accept, reject, context, params, value){
var address = value;
var regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!regex.test(address)) {
reject(address + " is not valid e-mail address.");
} else {
accept();
}
}
});
\ No newline at end of file
diff --git a/lib/base-chips/field_type.file.js b/lib/base-chips/field_type.file.js
index 6715f511..5bfdf076 100644
--- a/lib/base-chips/field_type.file.js
+++ b/lib/base-chips/field_type.file.js
@@ -1,41 +1,41 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var FieldFileType = new Sealious.ChipTypes.FieldType({
name: "file",
handles_large_data: true,
is_proper_value: function(accept, reject, context, params, value){
if (value === undefined) {
return undefined;
}
if ((value instanceof Sealious.File) || (value.filename !== undefined && value.data instanceof Buffer)) {
accept();
} else {
var type;
if (value instanceof Array) {
type = "<Array>. If you want to upload multiple files, use array field types.";
} else {
type = typeof data;
}
reject("Wrong file data format. Should be <Buffer>, but received " + type);
}
},
encode: function(context, params, value_in_code){
if (value_in_code) {
return Sealious.Dispatcher.files.save_file(value_in_code);
} else {
return null;
}
},
decode: function(context, params, value_in_database){
if (value_in_database) {
return Promise.resolve(new Sealious.File.Reference(value_in_database.id, value_in_database.filename));
} else {
if (params.no_file_value) {
return params.no_file_value;
} else {
return undefined;
}
}
}
});
\ 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 19c7ef2c..976b2afe 100644
--- a/lib/base-chips/field_type.float.js
+++ b/lib/base-chips/field_type.float.js
@@ -1,21 +1,21 @@
-var Sealious = require("../main.js");
+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) {
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.int.js b/lib/base-chips/field_type.int.js
index e75e670c..94cf0949 100644
--- a/lib/base-chips/field_type.int.js
+++ b/lib/base-chips/field_type.int.js
@@ -1,20 +1,20 @@
-var Sealious = require("../main.js");
+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) {
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/base-chips/field_type.reference.js b/lib/base-chips/field_type.reference.js
index 7cb49b93..e58ea036 100644
--- a/lib/base-chips/field_type.reference.js
+++ b/lib/base-chips/field_type.reference.js
@@ -1,90 +1,90 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var clone = require("clone");
var field_type_reference = new Sealious.ChipTypes.FieldType({
name: "reference",
is_proper_declaration: function(declaration){
var required_declaration_fields = {
"name": "string",
"allowed_types": "array"
};
for (var attribute_name in required_declaration_fields) {
if (declaration[attribute_name] === undefined) {
throw new Sealious.Errors.DeveloperError("Missing `" + attribute_name + "` attribute in reference declaration.");
}
}
for (var i in declaration.allowed_types) {
var type_name = declaration.allowed_types[i];
if (!Sealious.ChipManager.chip_exists("resource_type", type_name)) {
throw new Sealious.Errors.DeveloperError("Unknown allowed type in declaration of reference: " + type_name);
}
}
},
is_proper_value: function(accept, reject, context, params, value){
if (typeof value == "object") {
//validate object's values as values for new resource
var type = value.type;
if (type === undefined) {
reject("Reference resource type undefined. `type` attribute should be set to one of these values: " + this.params.allowed_types.join(", ") + ".");
} else if (this.params.allowed_types.indexOf(type) == -1) {
reject("Incorrect reference resource type: `" + type + "`. Allowed resource types for this reference are:" + this.params.allowed_types.join(", ") + ".");
} else {
var resource_type_object = Sealious.ChipManager.get_chip("resource_type", type);
var access_strategy = resource_type_object.get_access_strategy();
return access_strategy.check(context, value.type, value.data)
.then(function(){
return resource_type_object.validate_field_values(context, true, value.data);
})
}
} else {
//value is uid. Check if it is proper
var supposed_resource_id = value;
return Sealious.Dispatcher.resources.get_by_id(context, supposed_resource_id)
.then(function(resource){
if (this.params.allowed_types.indexOf(resource.type) >= 0) {
accept(resource);
} else {
reject("Resource of id `" + supposed_resource_id + "` is not of allowed type. Allowed types are: [" + this.params.allowed_types.join(", ") + "]");
}
}.bind(this))
.catch(function(error){
if (error.type == "not_found") {
reject(error.status_message);
} else {
reject(error);
}
}.bind(this));
}
},
encode: function(context, params, value_in_code){
//decide whether to create a new resource (if so, do create it). Resolve with id of referenced resource.
if (value_in_code instanceof Object) {
return Sealious.Dispatcher.resources.create(context, value_in_code.type, value_in_code.data).then(function(resource){
return Promise.resolve(resource.id);
})
} else {
//assuming the provided id already exists
return Promise.resolve(value_in_code);
}
},
get_description: function(context, params){
var params_copy = clone(params, false);
params_copy.allowed_types = {};
for (var i in params.allowed_types) {
var type_name = params.allowed_types[i];
var type_object = Sealious.ChipManager.get_chip("resource_type", type_name);
var type_schema = Sealious.ChipManager.get_chip("resource_type", type_name).get_specification();
params_copy.allowed_types[type_name] = type_schema;
}
return params_copy;
},
decode: function(context, params, value_in_db){
if (value_in_db == undefined) {
return Promise.resolve(undefined);
} else {
return Sealious.Dispatcher.resources.get_by_id(context, value_in_db);
}
}
});
\ No newline at end of file
diff --git a/lib/base-chips/field_type.text.js b/lib/base-chips/field_type.text.js
index f6fc53d6..ef432941 100644
--- a/lib/base-chips/field_type.text.js
+++ b/lib/base-chips/field_type.text.js
@@ -1,37 +1,37 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var sanitizeHtml = require("sanitize-html");
var field_type_text = new Sealious.ChipTypes.FieldType({
name: "text",
get_description: function(context, params){
return "Text with a maximum length " + params.max_length
},
is_proper_value: function(accept, reject, context, params, new_value){
if (params === undefined || params.max_length === undefined) {
accept()
} else {
if (new_value.length <= params.max_length) {
accept()
} else {
reject("Text '" + new_value + "' has exceeded max length of " + params.max_length + " chars.");
}
}
},
encode: function(context, params, value_in_code){
if (params && params.strip_html === true) {
var stripped = sanitizeHtml(value_in_code.toString(), {
allowedTags: []
})
return Promise.resolve(stripped);
} else {
if (value_in_code instanceof Object) {
return Promise.resolve(JSON.stringify(value_in_code));
} else if (value_in_code === null) {
return Promise.resolve(null);
} else {
return Promise.resolve(value_in_code.toString());
}
}
}
});
\ No newline at end of file
diff --git a/lib/base-chips/resource_type.user.js b/lib/base-chips/resource_type.user.js
index 906d471e..0768b148 100644
--- a/lib/base-chips/resource_type.user.js
+++ b/lib/base-chips/resource_type.user.js
@@ -1,19 +1,19 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var user = new Sealious.ChipTypes.ResourceType({
name: "user",
fields: [{
name: "username",
type: "text",
required: true
}, {
name: "email",
type: "email"
}, {
name: "password",
type: "text",
required: true
}, {
name: "status",
type: "text"
}, ]
});
diff --git a/lib/chip-types/access-strategy.js b/lib/chip-types/access-strategy.js
index 83f62862..5b5178b1 100644
--- a/lib/chip-types/access-strategy.js
+++ b/lib/chip-types/access-strategy.js
@@ -1,93 +1,93 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var Chip = require("./chip.js");
function AccessStrategy (declaration) {
if (typeof declaration.name != "string") {
throw new Sealious.Errors.DeveloperError("Access strategy declaration has an invalid or missing `name` attribute");
}
Chip.call(this, true, "access_strategy", declaration.name);
this.checker_function = null;
this.item_sensitive = false;
if (declaration) this._process_declaration(declaration);
}
AccessStrategy.prototype = new function(){
/*
Process declaration of access strategy. Gives new access strategy checker_function and item_sensitive from declaration.
@param {object} delcaration - is an object with attributes:
name - string, required. The name of the access strategy - it has to be a string unique amongst any other access strategies in your application.
checker_function - function, required. It’s a function that takes a context instance as an argument and implements the logic of the access strategy. Its return values can be:
* boolean - true for granting the access and false for denying.
* a Promise - that resolves when the access is granted and rejects otherwise. Use promises only when the decision depends on a result of an asynchronous function.
item_sensitive - boolean, defaults to false. If set to true, the checker_function is provided with a second argument, which contains an object representing the resource being requested.
*/
this._process_declaration = function(declaration){
this.checker_function = declaration.checker_function === undefined ? null : declaration.checker_function;
if (declaration.item_sensitive !== undefined) {
this.item_sensitive = declaration.item_sensitive;
}
}
/*
Setter of checker function.
@param {function} checker_function - function to be set as checker function of this access strategy.
return void
*/
this.set_checker_function = function(checker_function){
this.checker_function = checker_function;
}
this.load_item_if_neccesary = function(item_or_getter){
if (this.item_sensitive){
if (typeof item_or_getter=="function"){
return Promise.method(item_or_getter)();
} else {
return Promise.resolve(item_or_getter);
}
} else {
return Promise.resolve(undefined);
}
}
this.check = function(context, item_or_getter){
//item_or_getter can be either the item to use for checking, a function that returns the item, or null
var self = this;
return self.load_item_if_neccesary(item_or_getter)
.then(function(item){
if (self.item_sensitive && item == undefined){
return Promise.resolve(undefined);
} else {
return self.checker_function.call(self, context, item);
}
})
.catch(function(error){
if (typeof error == "string") {
throw new Sealious.Errors.BadContext(error);
} else {
throw error;
}
});
}
}
// odrzucanie i przyjmowanie wartości za pomocą checker_function, która zwraca Promisa
// odrzucanie i przyjmowanie wartości za pomocą checker_function, która zwraca Booleana
AccessStrategy.type_name = "access_strategy";
AccessStrategy.test_start = function(){
describe("AccessStrategy", function(){
describe(".check", function(){
describe("with checker_function that returns a Promise", function(){
})
})
});
}
module.exports = AccessStrategy;
\ No newline at end of file
diff --git a/lib/chip-types/channel.js b/lib/chip-types/channel.js
index e77084e2..21cb3ffc 100644
--- a/lib/chip-types/channel.js
+++ b/lib/chip-types/channel.js
@@ -1,19 +1,19 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var chip = require("./chip.js");
/*
Represents channel.
@constructor
@param {string} name - name of channel
return void
*/
function channel (name) {
this.name = name;
this.longid = "channel." + name;
this.default_configuration = {};
Sealious.ChipManager.add_chip("channel", this.name, this);
}
channel.prototype = new chip();
module.exports = channel;
\ No newline at end of file
diff --git a/lib/chip-types/chip-manager.js b/lib/chip-types/chip-manager.js
index 84e671d4..f20a4cc9 100644
--- a/lib/chip-types/chip-manager.js
+++ b/lib/chip-types/chip-manager.js
@@ -1,178 +1,178 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var fs = require("fs");
var path = require('path')
var Set = require('Set');
var Promise = require("bluebird");
var ConfigurationManager = require("../config/config-manager.js");
var chip_type_functions = {
channel: require("./channel.js"),
resource_type: require("./resource-type.js"),
field_type: require("./field-type.js"),
datastore: require("./datastore.js")
}
chips_by_module = {};
var started_chips_longids = new Set();
var chips = {};
var chip_type_start_order = ["datastore", "access_strategy", "field_type", "resource_type", "channel"];
var registred_chips_longids = new Set();
var ChipManager = new function(){
/**
* Starts chips in proper order.
* @param {array} chip_types_to_start - array of names of chips we want to start
* @returns {Promise} - Promise, which will resolve with starting chips or reject with error
*/
this.start_chips = function(){
Sealious.Logger.info("Starting all chips:");
var promises = [];
for (var i in chip_type_start_order){
var type = chip_type_start_order[i];
Sealious.Logger.info(" " + type + ":");
for (var name in chips[type]){
var chip = chips[type][name];
Sealious.Logger.info("\t \u2713 " + name);
try {
if (chip.start){
var promise = chip.start();
promises.push(promise);
}
} catch (error){
Sealious.Logger.error("\t " + "couldn't start `" + name + "`");
return Promise.reject(error);
}
}
}
return Promise.all(promises);
}
/**
* Adds chip to chips array and chips_by_module array
* @param {string} type - chip type ex. access-strategy, channel
* @param {string} name - chip name
* @param {object} chip - chip itselfs
* @returns void
*/
this.add_chip = function(type, name, chip){
if (chips[type]==undefined){
chips[type]=[];
}
chips[type][name]=chip;
}
/**
* Gets all resource types
* @returns {array} Array of names of resource types.
*/
this.get_all_resource_types = function(){
var names = [];
for (resource_type in chips.resource_type) {
names.push(resource_type);
}
return names;
}
/**
* Checks if chip exists
* @param {string} type - chip type
* @param {string} name - chip name
* @returns {boolean} true if exists, otherwise false
*/
this.chip_exists = function(type, name){
if (chips[type] && chips[type][name]){
return true;
} else {
return false;
}
}
/**
* Gets chip
* @param {string} type - chip type
* @param {string} name - chip name
* @returns {object} requested chip or throws error
*/
this.get_chip = function(type, name){
try {
var ret = chips[type][name];
if (ret == undefined){
throw new Error("Chip of type " + type + " and name " + name + " has not yet been registered.");
}
return ret;
} catch (e){
throw new Sealious.Errors.ValidationError("ChipManager was asked to return a chip of type `" + type + "` and name `" + name + "`, but it was not found", {}, {short_message: "chip_not_found"});
}
}
/*
* Gets chip by long id
* @param {string} longid - longid is chip_type.chip_name ex. chanell.cli
* @returns {object} requested chip or throws error
*/
this.get_chip_by_longid = function(longid){
var type = longid.split(".")[0];
var name = longid.split(".")[1];
return this.get_chip(type, name);
}
/*
* Checks if chip is registered
* @param {string} longid - longid is chip_type.chip_name ex. chanell.cli
* @returns {boolean} true if chip is registered, otherwise false
*/
this.chip_is_registred = function(longid){
return this.get_chip_by_longid(longid) != undefined;
}
/*
Gets amount of chips in given type
* @param {string} type - type name ex. chanell, access_strategy
* @returns {integer} amount of chips of this type
*/
this.get_chip_amount_by_type = function(type){
if (chips[type]){
return Object.keys(chips[type]).length;
} else {
return 0;
}
}
/**
* Gets proper datastore chip
* @returns {object} datastore chip for application or throws error if no datastore chip is defined
*/
this.get_datastore_chip = function(){
var datastore_chip_amount = this.get_chip_amount_by_type("datastore");
if (datastore_chip_amount===0){
throw new Sealious.Errors.Error("Chip manager was requested to return the datastore chip, but no chips of type `datastore` have been registered.")
} else if (datastore_chip_amount===1){
return chips["datastore"][Object.keys(chips["datastore"])[0]]
} else {
var datastore_chip_name = ConfigurationManager.get_config().datastore_chip_name;
if (datastore_chip_name===undefined){
throw new Sealious.Errors.Error("Chip manager was requested to return a datastore chip. Multiple chips of type `datastore` have been registered, and no default provided in configuration.")
} else {
return this.get_chip("datastore", datastore_chip_name);
}
}
}
/**
* Gets all chips of given type
* @param {string} chip type name ex. channel, access_strategy
* @returns {array} Array of chips of given type.
*/
this.get_chips_by_type = function(chip_type){
return chips[chip_type];
}
}
module.exports = ChipManager;
diff --git a/lib/chip-types/datastore.js b/lib/chip-types/datastore.js
index 818014d8..106eabb0 100644
--- a/lib/chip-types/datastore.js
+++ b/lib/chip-types/datastore.js
@@ -1,251 +1,251 @@
var assert = require("assert");
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Chip = require("./chip.js");
/*
Represents datastore.
@constructor
@param {string} name - name of datastore
*/
var Datastore = function(name){
this.name = name;
this.longid = "datastore." + name;
this.default_configuration = {};
Sealious.ChipManager.add_chip("datastore", this.name, this);
}
Datastore.prototype = new Chip();
/**
* Defines functions datastore need to implement,
* then ensures that if one of these function will not be implemented Selious will throw an informative error.
*/
var needs_to_implement = ["find", "insert", "update", "remove"]
Datastore.prototype.return_not_implemented = function(fn_name){
return function(){
throw new Sealious.Errors.DeveloperError("Function ", fn_name, "not implemented in ", this.longid, ", aborting.");
}
}
for (var i in needs_to_implement) {
var fn_name = needs_to_implement[i];
Datastore.prototype[fn_name] = Datastore.prototype.return_not_implemented(fn_name)
}
/*
Tests datastore compatibility with Sealious. It is a cascade of Promises, which result will be logged in console.
*/
Datastore.prototype.test_compatibility = function(){
var self = this;
this.start();
var rand = Math.random();
var test_collection_name = "_test";
return Promise.resolve()
.then(function(){
//.insert method should respond with the created document
var to_insert = {
value: 1,
random: rand
};
return self.insert(test_collection_name, to_insert)
.then(function(response){
assert.deepEqual(to_insert, response, ".insert method should respond with the created document");
return Promise.resolve();
});
}).then(function(){
//check if find resolves with an array
return self.find(test_collection_name, {}, {})
.then(function(documents){
assert(documents instanceof Array, "datastore." + self.name + ".find should resolve with an array");
return Promise.resolve();
});
}).then(function(){
//check if amount of created documents checks out
var creates = [
self.insert(test_collection_name, {
value: 2,
random: rand
}),
self.insert(test_collection_name, {
value: 3,
random: rand
}),
self.insert(test_collection_name, {
value: 4,
random: -rand
}),
]
var created_so_far = 4;
return Promise.all(creates)
.then(function(){
return self.find(test_collection_name, {}, {});
}).then(function(documents){
assert(documents.length == created_so_far, "Inserted " + created_so_far + " documents so far, but " + documents.length + " were returned on .find()");
return Promise.resolve(created_so_far);
});
}).then(function(created_so_far){
//check if there is a proper amount of documents with random value set to rand
var documents_with_rand = created_so_far - 1;
return self.find(test_collection_name, {
random: rand
}, {})
.then(function(documents){
assert(documents.length == documents_with_rand, "Inserted " + documents_with_rand + " documents with `random` set to `" + rand + "` so far, but " + documents.length + " were returned on .find({random: " + rand + "})");
return Promise.resolve();
});
}).then(function(){
//Should store a complex object
var complex_object = {
id: "aseoifaoeina",
body: {
name: "Anna",
surname: "Fontanna"
}
};
return self.insert(test_collection_name, complex_object)
.then(function(response){
assert.deepEqual(complex_object, response, ".insert with complex object should resolve with that complex object.");
return self.find(test_collection_name, {
id: complex_object.id
})
}).then(function(response){
assert.deepEqual(complex_object, response[0], ".insert with complex object should store that complex object.");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
//Should handle dot-notation nested queries
return self.find(test_collection_name, {
"body.name": complex_object.body.name
})
.then(function(response){
assert.deepEqual(complex_object, response[0], ".find method should handle dot notation queries");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
return self.find(test_collection_name, {
body: {
name: complex_object.body.name
}
})
.then(function(response){
assert.deepEqual(complex_object, response[0], ".find method should handle nested object queries");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
//.update should modify document values with dot notation
complex_object.body.name = "Hanna";
return self.update(test_collection_name, {
id: complex_object.id
}, {
"body.name": complex_object.body.name
})
.then(function(){
return self.find(test_collection_name, {
id: complex_object.id
});
}).then(function(results){
assert.deepEqual(complex_object, results[0], ".update should modify document values with dot notation");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
//.update should modify document values using nested object as a query
complex_object.body.name = "Marzanna";
return self.update(test_collection_name, {
id: complex_object.id
}, {
body: {
name: complex_object.body.name
}
})
.then(function(){
return self.find(test_collection_name, {
id: complex_object.id
});
}).then(function(results){
assert.deepEqual(complex_object, results[0], ".update should modify document values using nested object as a query ");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
//.update should insert new value to a field that previously had no value (undefined)
complex_object.body.other = "Focca";
return self.update(test_collection_name, {
id: complex_object.id
}, {
body: {
other: complex_object.body.other
}
})
.then(function(){
return self.find(test_collection_name, {
id: complex_object.id
});
}).then(function(results){
assert.deepEqual(complex_object, results[0], ".update should insert new value to a field that previously had no value (undefined)");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
//.remove should remove only one document when "just_one" is set to true
return Promise.all([
self.insert(test_collection_name, complex_object),
self.insert(test_collection_name, complex_object),
self.insert(test_collection_name, complex_object),
]).then(function(){
//all the "complex_object" documents have the same id
return self.remove(test_collection_name, {
id: complex_object.id
}, true);
}).then(function(){
return self.find(test_collection_name, {
id: complex_object.id
});
}).then(function(results){
assert(results.length == 3, ".remove should remove only *one* document when `just_one` argument is set to true");
return Promise.resolve(complex_object);
});
}).then(function(complex_object){
//.remove should remove all matching documents when "just_one" is falsy
return Promise.all([
self.insert(test_collection_name, complex_object),
self.insert(test_collection_name, complex_object),
self.insert(test_collection_name, complex_object),
]).then(function(){
//all the "complex_object" documents have the same id
return self.remove(test_collection_name, {
id: complex_object.id
}, false);
}).then(function(){
return self.find(test_collection_name, {
id: complex_object.id
});
}).then(function(results){
assert(results.length == 0, ".remove should remove all matching documents when 'just_one' is falsy");
return Promise.resolve(complex_object);
});
}).then(function(){
self.clear_collection(test_collection_name);
}).catch(function(err){
self.clear_collection(test_collection_name);
console.log(err.stack);
return Promise.reject("Compatibility test unsuccesfull")
});
};
module.exports = Datastore;
\ No newline at end of file
diff --git a/lib/chip-types/field-type.js b/lib/chip-types/field-type.js
index 68edbe88..bb6bbd09 100644
--- a/lib/chip-types/field-type.js
+++ b/lib/chip-types/field-type.js
@@ -1,189 +1,189 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var merge = require("merge");
var Chip = require("./chip.js");
var FieldTypeDescription = require("../data-structures/field-type-description.js");
/**
* Stores field type metadata, as well as validation methods
* @class
*/
function FieldType (declaration) {
Chip.call(this, true, "field_type", declaration.name);
this.old_value_sensitive_methods = declaration.old_value_sensitive_methods || false;
this.process_declaration(declaration);
}
FieldType.prototype = new function(){
this.process_declaration = function(declaration){
this.declaration = declaration;
this.name = declaration.name;
this.handles_large_data = declaration.handles_large_data==undefined? false : true;
if (declaration.extends) {
this.parent_field_type = Sealious.ChipManager.get_chip("field_type", declaration.extends);
} else {
this.parent_field_type = null;
}
}
this.is_old_value_sensitive = function(method_name){
if (method_name == undefined) {
if (typeof this.old_value_sensitive_methods == "boolean") {
return this.old_value_sensitive_methods;
} else {
for (var i in this.old_value_sensitive_methods) {
if (this.old_value_sensitive_methods[i]) {
return true;
}
}
return false;
}
} else {
if (typeof this.old_value_sensitive_methods == "boolean") {
return this.old_value_sensitive_methods;
} else {
return this.old_value_sensitive_methods[method_name];
}
}
}
this.get_method = function(method_name){
var ret;
if (this.declaration[method_name]) {
ret = this.declaration[method_name];
} else {
ret = this["_" + method_name].bind(this);
}
return Promise.method(ret);
}
/**
* Whether a given value can be stored in this field type instance
* @memberOf FieldType
* @abstract
* @param {any} value - value of this variable will be tested for compatibility with this field
* @return {Promise}
*/
//to be decorated
this._is_proper_value = function(accept){
accept();
}
/**
* Whether a given declariation is proper
* @memberOf FieldType
* @abstract
* @param {object} declaration - value of this variable will be tested for compatibility with this field
* @returns {Promise|Boolean}
*
*/
//to be decorated
this.is_proper_declaration = function(declaration){
return true;
}
/**
* Encodes value given by user
* @memberOf FieldType
* @abstract
* @param {any} value_in_code - value to be encoded in proper format
* @returns {Promise|Boolean}
*/
//to be decorated
this._encode = function(context, params, value_in_code){
return value_in_code;
}
//to be decorated
this._get_description = function(){
return new FieldTypeDescription(this.name);
}
this._encode.uses_context = false;
/**
* Decodes value from database
* @memberOf FieldType
* @abstract
* @param {Context} context
* @param {object} param - field params
* @param {any} value_in_database - value to be decoded to proper format
* @return {Promise}
*/
//to be decorated
this._decode = function(context, param, value_in_database){
return value_in_database;
}
this._decode.uses_context = false;
this.is_proper_value = function(context, params, new_value, old_value){
var self = this;
var validate_in_parent;
if (this.declaration.extends) {
validate_in_parent = this.parent_field_type.is_proper_value(context, params, new_value, old_value);
} else {
validate_in_parent = Promise.resolve();
}
return validate_in_parent.then(function(){
return new Promise(function(resolve, reject){
var new_reject = function(error_message){
reject(new Sealious.Errors.ValidationError(error_message));
}
self.get_method("is_proper_value")(resolve, new_reject, context, params, new_value, old_value);
});
});
}
/**
* If a field-type has defined .decode method, use it. Otherwise use it's parent's or the default one
**/
this.decode = function(context, params, value_in_database){
if (this.declaration.extends && this.declaration.decode == undefined) {
return this.parent_field_type.decode(context, params, value_in_database);
} else {
return this.get_method("decode")(context, params, value_in_database);
}
}
/**
* If a field-type has defined .decode method, use it. Otherwise use it's parent's or the default one
**/
this.encode = function(context, params, value_in_code){
if (this.declaration.extends && this.declaration.encode == undefined) {
return this.parent_field_type.encode(context, params, value_in_code);
} else {
return this.get_method("encode")(context, params, value_in_code);
}
}
this.get_description = function(params){
if (this.declaration.extends && this.declaration.get_description == undefined) {
return this.parent_field_type.get_description(params)
} else {
return this.get_method("get_description")(params)
.then(function(description){
if (typeof description == "string") {
return Promise.resolve(new FieldTypeDescription(description));
} else {
return Promise.resolve(description);
}
});
}
}
}
FieldType.type_name = "field_type";
module.exports = FieldType;
\ 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 3d8fff21..c6934d3e 100644
--- a/lib/chip-types/resource-type-field.js
+++ b/lib/chip-types/resource-type-field.js
@@ -1,131 +1,131 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
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+"'.");
}
this.params = declaration.params;
this.default_value = declaration.default_value;
this.type = Sealious.ChipManager.get_chip("field_type", declaration.type);
structure_name = declaration.structure || "single";
if (Sealious.FieldStructures[structure_name]){
this.structure = Sealious.FieldStructures[structure_name];
} else {
throw new Sealious.Errors.DeveloperError("In declaration of resource type '" + resource_type.name +"': unknown field structure '"+structure_name+"' in field '"+this.name+"'.");
}
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 173bc527..abfe2bf7 100644
--- a/lib/chip-types/resource-type.js
+++ b/lib/chip-types/resource-type.js
@@ -1,286 +1,286 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
var merge = require("merge");
var Chip = require("./chip.js");
var ResourceTypeField = require("./resource-type-field.js");
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(){
this._process_declaration = function(declaration){
if (declaration){
if (declaration.fields){
this.add_fields(declaration.fields);
}
this.set_access_strategy(declaration.access_strategy);
}
}
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;
this.fields[field_name] = field_object;
}
}
this.add_fields = function(field_declarations_array){
for (var i in field_declarations_array){
var declaration = field_declarations_array[i];
this.add_field(declaration);
}
}
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;
}
this.get_unknown_field_errors = function(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.get_missing_values_checker = function(values, assume_delete_value_on_missing_key, old_values_or_getter){
var self = this;
if (assume_delete_value_on_missing_key){
return this.load_item_from_cached_getter(old_values_or_getter)
.then(function(old_values){
return function(field_name){
return self.fields[field_name].required && values[field_name]==undefined && old_values[field_name]==undefined
}
})
} else {
return function(field_name){
return self.fields[field_name].required && values[field.name]==undefined
}
}
}
this.get_missing_field_values_errors = function(values, assume_delete_value_on_missing_key, old_values_or_getter){
var self = this;
var errors = {};
return this.get_missing_values_checker(values, assume_delete_value_on_missing_key, old_values_or_getter)
.then(function(checker_fn){
return Promise.filter(Object.keys(self.fields), checker_fn.bind(self));
}).each(function(field_name){
errors[field_name] = new Sealious.Errors.ValidationError("Missing value for field `" + self.fields[field_name].get_nice_name() + "`");
}).then(function(){
return errors;
})
}
this.get_invalid_field_values_errors = function(context, values, old_values){
var errors = {};
var promises = [];
for (var field_name in values){
if (this.fields[field_name]){
var value = values[field_name];
var old_value = old_values? old_values[field_name] : undefined;
var promise = this.fields[field_name].check_value(context, value, old_value)
.catch((function(field_name){
return function(error){
if (error.type=="validation"){
errors[field_name] = error;
} else {
throw error;
}
}
})(field_name)
);
promises.push(promise);
}
}
return Promise.all(promises)
.then(function(){
return errors;
})
}
this.load_item_from_cached_getter = function(item_or_getter){
if (typeof item_or_getter == "function"){
return Promise.method(item_or_getter)();
} else if (item_or_getter==undefined){
return Promise.resolve({});
} else {
return Promise.resolve(item_or_getter);
}
}
this.load_item_if_necessary = function(item_or_getter){
if (this.is_old_value_sensitive()){
return this.load_item_from_cached_getter(item_or_getter);
} else {
return Promise.resolve(undefined);
}
}
this.validate_field_values = function(context, assume_delete_value_on_missing_key, new_values, old_values_or_getter){
var self = this;
var validation_errors = {};
return this.load_item_if_necessary(old_values_or_getter)
.then(function(old_values){
var errors_array = [
self.get_unknown_field_errors(new_values),
self.get_missing_field_values_errors(new_values, assume_delete_value_on_missing_key, old_values_or_getter),
self.get_invalid_field_values_errors(context, new_values, old_values)
];
return Promise.all(errors_array);
})
.reduce(merge)
.then(function(errors){
var user_errors = {};
var non_user_errors = {};
for (var field_name in errors){
var error = errors[field_name];
if (error.is_user_fault){
user_errors[field_name] = error;
} else {
non_user_errors[field_name] = error;
}
}
var non_user_errors_amount = Object.keys(non_user_errors).length;
if (non_user_errors_amount>0){
throw non_user_errors[Object.keys(non_user_errors)[0]];
}
var user_errors_amount = Object.keys(user_errors).length;
if (user_errors_amount>0){
throw new Sealious.Errors.ValidationError("There are problems with some of the provided values.", user_errors);
}
})
}
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){
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);
}
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){
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_name){
return this.access_strategy[action_name] || 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;
}
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);
}
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);
});
}
this.check_if_action_is_allowed = function(context, action_name, item_or_getter){
var access_strategy = this.get_access_strategy(action_name)
return access_strategy.check(context, item_or_getter);
}
}
module.exports = ResourceType;
\ No newline at end of file
diff --git a/lib/config/config-manager.js b/lib/config/config-manager.js
index 76e8a179..b4b3dbe6 100644
--- a/lib/config/config-manager.js
+++ b/lib/config/config-manager.js
@@ -1,68 +1,68 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var fs = require("fs");
var path = require("path");
var merge = require("merge");
var ConfigManager = new function(){
default_config = {};
config = {};
function modify_config (is_default_config, key, value) {
var key_elements = key.split('.');
var new_values = {};
var current_position = new_values;
for (var i = 0; i < key_elements.length - 1; i++) {
var current_key = key_elements[i];
current_position[current_key] = {};
current_position = current_position[current_key];
}
current_position[key_elements[key_elements.length - 1]] = value;
if (is_default_config) {
default_config = merge.recursive(true, default_config, new_values);
} else {
config = merge.recursive(true, config, new_values);
}
}
this.set_config = function(key, new_config){
if (arguments.length == 1) {
config = config;
} else {
modify_config(false, key, new_config);
}
}
this.set_default_config = function(key, value){
if (arguments.length == 1) {
default_config = default_config;
} else {
modify_config(true, key, value);
}
}
this.get_configuration = function(key){
var to_merge_left = default_config;
var to_merge_right = config;
var key_elements = key == undefined ? [] : key.split(".");
while (key_elements.length) {
var current_key = key_elements.splice(0, 1);
to_merge_left = to_merge_left[current_key] == undefined ? {} : to_merge_left[current_key];
to_merge_right = to_merge_right[current_key] == undefined ? {} : to_merge_right[current_key];
}
return merge.recursive(true, to_merge_left, to_merge_right);
}
this.get_config = this.get_configuration;
this.get_chip_config = function(longid){
return config.chip_config && config.chip_config[longid];
}
this.get_dispatcher_config = function(){
return config.dispatcher_config || {};
}
}
module.exports = ConfigManager;
\ No newline at end of file
diff --git a/lib/core-services/file-manager.js b/lib/core-services/file-manager.js
index 18fc7541..9538912c 100644
--- a/lib/core-services/file-manager.js
+++ b/lib/core-services/file-manager.js
@@ -1,112 +1,112 @@
var Promise = require("bluebird");
var UUIDGenerator = require("uid");
var path = require('path');
var fse = require("fs-extra");
var fs = require("fs");
var ResourceRepresentation = require("../chip-types/resource-representation.js");
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
/**
* Manages files
* @class
*/
var root_path = function(){
var parent_tmp = module.parent;
var parent = null;
while (parent_tmp) {
parent = parent_tmp;
parent_tmp = parent_tmp.parent;
}
return parent.filename;
}
var FileManager = new function(upload_path){
this.name = "files";
if (!upload_path) {
upload_path = "./uploaded_files/";
}
var upload_path_abs = path.resolve(root_path(), "../" + upload_path);
this.save_file = function(file, upload_path){
if (!fs.existsSync(upload_path_abs)) {
fse.mkdirs(upload_path_abs, function(err){});
}
var newID = UUIDGenerator(10);
var upload_path_with_sealious_name = upload_path_abs + "/" + newID;
fs.writeFile(upload_path_with_sealious_name, file.data, function(err, data){
if (err) {
throw (err);
}
});
var file_database_entry = {
original_name: file.filename,
creation_context: file.context,
id: newID,
mime_type: file.mime,
}
return Sealious.Dispatcher.datastore.insert("files", file_database_entry, {})
.then(function(){
return Promise.resolve({
id: newID,
filename: file.filename
});
})
}
this.diff = function(dispatcher, file){
}
this.get_list = function(dispatcher, owner){
var query = {
"body.owner": owner
};
Sealious.Logger.info("List for owner '" + owner + "' has been created");
return this.find(dispatcher, query);
}
this.find = function(context, query){
return Sealious.Dispatcher.datastore.find("files", query)
.then(function(documents){
var parsed_documents = documents.map(function(document){
var ret = Sealious.File.from_db_entry(document);
ret.path_on_hdd = upload_path + ret.id;
return ret;
});
return Promise.resolve(parsed_documents);
})
}
this.change_name = function(dispatcher, sealious_name, new_name){
return dispatcher.datastore.update("files", {
sealious_id: sealious_name
}, {
$set: {
"body.original_name": new_name
}
});
}
this.delete = function(dispatcher, query){
}
}
//wersjonowanie, historia dostępu, przetrzymywanie poprzednich wersji
module.exports = FileManager;
\ No newline at end of file
diff --git a/lib/core-services/resource-manager.js b/lib/core-services/resource-manager.js
index 0c2d7d7c..d324ca35 100644
--- a/lib/core-services/resource-manager.js
+++ b/lib/core-services/resource-manager.js
@@ -1,145 +1,145 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
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;
/**
* 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.Dispatcher.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.Dispatcher.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, 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.Dispatcher.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.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/core-services/user_manager.js b/lib/core-services/user_manager.js
index e1def61c..d0fbbab9 100644
--- a/lib/core-services/user_manager.js
+++ b/lib/core-services/user_manager.js
@@ -1,97 +1,97 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var Promise = require("bluebird");
module.exports = new function(){
this.name = "users";
this.create_user = function(context, username, password){
var user_data;
return Sealious.Dispatcher.users.user_exists(context, username)
.then(function(user_exists){
if (!user_exists) {
Sealious.Logger.info("User " + username + " has been created");
return Sealious.Dispatcher.resources.create(context, "user", {
username: username,
password: password
});
} else {
throw new Sealious.Errors.ValueExists("Username `" + username + "` is already taken.");
}
})
}
this.user_exists = function(context, username){
return new Promise(function(resolve, reject){
Sealious.Dispatcher.resources.find({
username: username
}, "user")
.then(function(matched_documents){
resolve(matched_documents.length === 1);
});
})
}
this.password_match = function(context, username, password){
return new Promise(function(resolve, reject){
if (!username && !password) {
var err = new Sealious.Errors.InvalidCredentials("Missing username and password!");
reject(err);
} else if (!password) {
var err = new Sealious.Errors.InvalidCredentials("Missing password!");
reject(err);
} else if (!username) {
var err = new Sealious.Errors.InvalidCredentials("Missing username!");
reject(err);
} else {
var query = {
type: "user",
body: {
username: username,
password: password
}
};
Sealious.Dispatcher.datastore.find("resources", query)
.then(function(result){
if (result[0]) {
resolve(result[0].sealious_id);
} else {
var err = new Sealious.Errors.InvalidCredentials("Wrong username or password!");
reject(err);
}
})
}
})
}
this.get_all_users = function(context){
return Sealious.Dispatcher.datastore.find("resources", {
type: "user"
});
}
this.get_user_data = function(context, user_resource_id){
try {
var ret = Sealious.Dispatcher.resources.get_by_id(context, user_resource_id);
} catch (err) {
throw err;
}
return ret;
}
this.update_user_data = function(context, user_id, new_user_data){
return Sealious.Dispatcher.resources.update_resource(user_id, new_user_data);
}
this.delete_user = function(context, user_id){
return new Promise(function(resolve, reject){
Sealious.Dispatcher.datastore.delete("resources", {
sealious_id: user_id
})
.then(function(data){
resolve(data);
}).catch(function(e){
reject(e);
});
});
}
}
\ No newline at end of file
diff --git a/lib/data-structures/file.js b/lib/data-structures/file.js
index 8a516018..033aeaae 100644
--- a/lib/data-structures/file.js
+++ b/lib/data-structures/file.js
@@ -1,32 +1,32 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
function File (creation_context, filename, data, id, mime) {
this.filename = filename;
this.data = data;
this.id = id || null;
this.mime = mime || false;
}
File.from_id = function(context, file_id){
return Sealious.Dispatcher.files.find(context, {
id: file_id
})
.then(function(file_array){
return Promise.resolve(file_array[0]);
});
}
File.from_db_entry = function(db_document, upload_path){
return new File(db_document.creation_context, db_document.original_name, db_document.data, db_document.id, db_document.mime_type);
}
File.prototype = new function(){
this.data_structure = "file";
}
File.Reference = function(id, filename){
this.id = id;
this.filename = filename;
}
module.exports = File;
\ No newline at end of file
diff --git a/lib/logger/logger.js b/lib/logger/logger.js
index 39efad70..06d2d7ab 100644
--- a/lib/logger/logger.js
+++ b/lib/logger/logger.js
@@ -1,136 +1,136 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var winston = require('winston');
var ConfigManager = Sealious.ConfigManager;
/*
This is the default configration of Sealious logger.
To retrieve a specifig setting, use "get_config()" function, ex. "ConfigManager.get_config().logger_config.logger_level".
@logger_level - specifies from which log level (displayed below) onward should be displayed,
@logger_color - specifies if the log should be colorized, values "true" or "false"
@logger_file - defines a filename to save the logs, if a falsy value is given the logs will not be saved,
@logger_dirname - defines a default path to save the logs,
@logger_to_json - specifies the format of the saved logs,
@logger_rotation - defines the log rotation format, set to daily by default
*/
ConfigManager.set_default_config(
"logger_config", {
logger_level: "info",
logger_color: true,
logger_file: null,
logger_dirname: ".",
logger_to_json: false,
logger_rotation: '.yyyy-MM-Tdd'
});
/*
This is the custom logger level and color configuration.
@levels - default logger levels, 0 being the lowest importance, 4 being the highest:
* lazyseal - an Easter, or should we say: Sealious egg. Used only for humorous reasons, the lowest level of importance, default color: white,
* info - used for stating the current status or general information such as starting the server, default color: green,
* debug - used for debugging, default color: blue,
* warning - used to display warnings, default color: yellow,
* error - used to display errors, default color: red
*/
var custom = {
levels: {
lazyseal: 0,
info: 1,
debug: 2,
warning: 3,
error: 4,
no_output: 5
},
colors: {
lazyseal: "white",
info: "green",
debug: 'blue',
warning: 'yellow',
error: 'red'
}
};
/*
Returns the current date and time, default format: "yyyy-mm-dd hh:mm:ss.mmm", ex. "2000-01-01 20:00:00.000"
*/
function getDateTime (with_date) {
var date = new Date();
var hour = date.getHours();
hour = (hour < 10 ? "0" : "") + hour;
var min = date.getMinutes();
min = (min < 10 ? "0" : "") + min;
var sec = date.getSeconds();
sec = (sec < 10 ? "0" : "") + sec;
var milli = date.getMilliseconds();
milli = (milli < 10 ? "00" : "") + milli;
milli = (milli < 100 && milli >= 10 ? "0" : "") + milli;
var year = date.getFullYear();
var month = date.getMonth() + 1;
month = (month < 10 ? "0" : "") + month;
var day = date.getDate();
day = (day < 10 ? "0" : "") + day;
if (!with_date) {
return hour + ":" + min + ":" + sec + "." + milli;
} else {
return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + "." + milli;
}
}
var transports_array = new Array();
var logger_level = ConfigManager.get_config().logger_config.logger_level;
var logger_color = ConfigManager.get_config().logger_config.logger_color;
var logger_file = ConfigManager.get_config().logger_config.logger_file;
var logger_dirname = ConfigManager.get_config().logger_config.logger_dirname;
var logger_to_json = ConfigManager.get_config().logger_config.logger_to_json;
var logger_rotation = ConfigManager.get_config().logger_config.logger_rotation;
var winston_level = new(winston.transports.Console)({
level: logger_level,
colorize: logger_color,
timestamp: function(){
return getDateTime(false);
}
});
transports_array.push(winston_level);
if (logger_file) {
var winston_save_to_file = new(winston.transports.File)({
filename: logger_file,
colorize: logger_color,
timestamp: function(){
return getDateTime(true);
},
dirname: logger_dirname,
json: logger_to_json
});
var winston_daily_rotate = new(winston.transports.DailyRotateFile)({
filename: logger_file,
datePattern: logger_rotation
});
transports_array.push(winston_save_to_file);
transports_array.push(winston_daily_rotate);
}
var logger = new winston.Logger({
levels: custom.levels,
colors: custom.colors,
transports: transports_array
});
module.exports = logger;
\ No newline at end of file
diff --git a/lib/plugins/plugin-manager.js b/lib/plugins/plugin-manager.js
index 00b536e8..0dc3a090 100644
--- a/lib/plugins/plugin-manager.js
+++ b/lib/plugins/plugin-manager.js
@@ -1,39 +1,39 @@
-var Sealious = require("../main.js");
+var Sealious = require("sealious");
var path = require("path");
var PluginManager = new function(){
function load_plugins_from_dir (dir) {
dir = dir || "";
var root = path.resolve(dir);
var pkgfile = path.join(root, 'package.json');
var pkg = require(pkgfile);
for (var dependency_name in pkg.dependencies){
var plugin_package_info_file = path.resolve(root, "node_modules", dependency_name, "package.json");
try {
var plugin_package_info = require(plugin_package_info_file);
} catch (error){
continue;
}
if (plugin_package_info.keywords && plugin_package_info.keywords.indexOf("sealious-plugin")!==-1){
Sealious.Logger.info("Detected plugin " + plugin_package_info.name);
var plugin_dir = path.resolve(root, "node_modules", dependency_name);
var plugin = require(path.resolve(root, "node_modules", dependency_name));
load_plugins_from_dir(plugin_dir);
}
}
}
this.load_plugins = function(){
load_plugins_from_dir("");
var sealious_dir = path.resolve(module.filename, "../../../");
if (sealious_dir!=path.resolve("")){
load_plugins_from_dir(sealious_dir);
}
}
}
module.exports = PluginManager;
diff --git a/lib/subject-type/root-subject.js b/lib/subject-type/root-subject.js
index bed37195..e261cc29 100644
--- a/lib/subject-type/root-subject.js
+++ b/lib/subject-type/root-subject.js
@@ -1,27 +1,28 @@
var Sealious = require("sealious");
+
var ResourceCollection = require("./resource-collection-subject.js");
var RootSubject = function(){
this.resource_collections = null;
this._initialize_resource_collections = function(){
this.resource_collections = {};
var resource_types = Sealious.ChipManager.get_chips_by_type("resource_type");
for (var resource_type_name in resource_types){
resource_type = resource_types[resource_type_name];
this.resource_collections[resource_type_name] = new ResourceCollection(resource_type);
}
}
this.getChildSubject = function(key){
if (this.resource_collections===null){
this._initialize_resource_collections();
}
return this.resource_collections[key];
}
}
RootSubject.prototype = Object.create(Sealious.Subject.prototype)
module.exports = new RootSubject();
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 8, 08:40 (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034373
Default Alt Text
(74 KB)

Event Timeline