Comparing version 0.10.15 to 0.11.1
30
deep.js
@@ -12,2 +12,3 @@ /** | ||
"./lib/utils", | ||
"./lib/nodes", | ||
"./lib/query", | ||
@@ -24,8 +25,6 @@ "./lib/compose", | ||
"./lib/flatten", | ||
//"./lib/selector", | ||
"./lib/compiler", | ||
"./lib/emitter", | ||
"./lib/rql", | ||
"./lib/stores/chain", | ||
//"./lib/schema" | ||
"./lib/stores/chain" | ||
], function (require, utils) { | ||
@@ -58,9 +57,9 @@ | ||
else | ||
h._nodes = [deep.utils.createRootNode(obj, schema, options)]; | ||
h._nodes = [deep.nodes.root(obj, schema, options)]; | ||
if (obj && obj._deep_store_) | ||
{ | ||
h.store(obj); | ||
deep.Store.extendsChain(h); | ||
} | ||
if (r && r._deep_store_) | ||
h.store(r) | ||
.done(function(s){ | ||
this._nodes = [deep.nodes.root(s)]; | ||
}); | ||
@@ -84,3 +83,3 @@ h._root = h._nodes[0]; | ||
console.log("internal chain start error : ", error); | ||
h._nodes = [deep.utils.createRootNode({}, schema, options)]; | ||
h._nodes = [deep.nodes.root({}, schema, options)]; | ||
h._start(null, error); | ||
@@ -138,3 +137,8 @@ } | ||
deep.nodes = require("./lib/nodes"); | ||
deep.deepLoad = function(entry, context, destructive, excludeFunctions){ | ||
if(!entry._deep_query_node_) | ||
entry = deep.nodes.root(entry); | ||
return deep.nodes.deepLoad([entry]) | ||
}; | ||
/** | ||
@@ -190,2 +194,3 @@ * final namespace for deepjs/query | ||
deep.roles = ocm.roles; | ||
deep.getModes = ocm.getModes; | ||
@@ -214,5 +219,4 @@ var event = require("./lib/emitter"); | ||
require("./lib/stores/chain"); | ||
require("./lib/stores/chain")(deep); | ||
//_________________________________________________________________________________ | ||
@@ -219,0 +223,0 @@ |
@@ -14,3 +14,2 @@ [Back to tutorials](../tutorials.md) | ||
// our basical object/API | ||
var farmManager = { | ||
@@ -36,32 +35,30 @@ animals : [ | ||
// now we add an aspect on water() that will | ||
// clean the place before watering the animals (asynchronous) | ||
// Add aspects | ||
deep.utils.up({ | ||
water : deep.compose.before(function(){ | ||
var def = deep.Deferred(); | ||
setTimeout(function(){ | ||
console.log("cleaning before watering"); | ||
def.resolve("cleaning done"); | ||
},1500*Math.random()); | ||
return def.promise(); | ||
}) | ||
// now we add an aspect on water() that will | ||
// clean the place before watering the animals (asynchronous) | ||
water : deep.compose.before(function(){ | ||
return deep(1).delay(1500*Math.random()) | ||
.done(function(){ | ||
console.log("cleaning before watering"); | ||
//... | ||
return "cleaning done"; | ||
}); | ||
}), | ||
// this function added to our farmManager will run 3 cycles of | ||
// watering and feeding the animals. | ||
// All the asynchronous is managed by the deep chain | ||
cycle : function(){ | ||
var d = deep(farmManager); | ||
for(var i = 0;i<3;i++) | ||
d.run("water").run("feed",["flour"]).delay(200); | ||
return d; | ||
} | ||
},farmManager); | ||
// this function added to our farmManager will run 3 cycles of | ||
// watering and feeding the animals. | ||
// All the asynchronous is managed by the deep chain | ||
farmManager.doCycle = function(){ | ||
var d = deep(farmManager); | ||
for(var i = 0;i<3;i++) | ||
{ | ||
d.run("water").run("feed",["flour"]).delay(200); | ||
} | ||
return d; | ||
}; | ||
// run the example | ||
deep(farmManager) | ||
.run("doCycle") | ||
.run("cycle") | ||
.done(function(s){ | ||
console.log(" 3 cycles finished : ",s); | ||
console.log(" 3 cycles finished : ",s); | ||
}) | ||
@@ -68,0 +65,0 @@ .fail(function(error){ |
@@ -7,3 +7,3 @@ # Object validation | ||
deep-schema.js is json-schema v4 compliant. | ||
deepjs/lib/schema.js is json-schema v4 compliant. | ||
@@ -10,0 +10,0 @@ ## Direct API |
@@ -459,3 +459,3 @@ [Back to tutorials](./tutorials.md) | ||
## Sheets in OCM | ||
## Sheets and OCM | ||
@@ -489,3 +489,2 @@ You could, by default, obviously define a deep.sheet through OCM. | ||
But you could also use them at compilation time (apply sheets while your ocmanager compiles). | ||
For this : simply add an applySheets:true in ocm options | ||
@@ -508,3 +507,3 @@ ```javascript | ||
} | ||
},{ applySheets:true }); | ||
}); | ||
@@ -523,4 +522,5 @@ myObject.flatten(); | ||
``` | ||
Remarque : | ||
If you have real asynch call in your sheets that you want to be applyied at compilation, be careful : Read below (OCM and Asynch) | ||
## Classes composition with OCM | ||
@@ -625,13 +625,8 @@ | ||
var manager = deep.ocm({ | ||
mode1:{ | ||
name:"John", | ||
familly:"Doe" | ||
}, | ||
mode2:{ | ||
name:"Herbert", | ||
familly:"Laevus" | ||
} | ||
mode1:{ ... }, | ||
mode2:{ ... }, | ||
... | ||
}, { | ||
afterCompilation:function(result){ | ||
console.log("compiled : ", result.name, result.familly); | ||
... | ||
return deep.when(result) | ||
@@ -649,2 +644,32 @@ .done(function(res){ | ||
Remarque : read below | ||
## OCM and Asynch modelisation | ||
So... Be aware that, if you want to use OCM transparently in actual deepjs tools and modules, all call on a ocmanager (i.e. myManager("myMode")) should always return the compilation result directly, and should not return any promise. | ||
The reason of that is mainly for the simplicity of the ocm pattern injection : | ||
```javascript | ||
... | ||
var myObj = myObject; | ||
if(myObj && myObj._deep_ocm_) | ||
myObj = myObj(); | ||
myObj...; // myObj is now the ocm result and should be the final object (i.e. not a promise) | ||
... | ||
``` | ||
This pattern is heavily used at many places in deepjs tools and modules, and could be added anywhere in your own modules. | ||
For the moment, deepjs tools and modules do not manage promises from OCM calls automagically. | ||
Maybe in the future... ;) | ||
Meanwhile, be careful to provide non-asynch sheets or 'afterCompilation' callback, and to flatten you ocm (or the layer where it sits) BEFORE calling related ocmanager. | ||
And everyting will be ok... ;) | ||
Sub-remarque : | ||
do not be confused with an OCM store and its init sequence. Each store is lazzily initialised on first (own) API call (store.get, .post, .put, ...) and so you don't need to manage store initialisation before OCM call... | ||
[Back to tutorials](./tutorials.md) | ||
@@ -654,6 +679,6 @@ | ||
* [Additive vs restrictive](./ocm/ocm-synthesis.md) | ||
* [ocm and protocols](./ocm/ocm-protocols.md) | ||
* [ocm and stores](./ocm/ocm-stores.md) | ||
* [Additive vs restrictive](./ocm/ocm-synthesis.md) | ||
* [Delegation](./ocm/ocm-delegate.md) | ||
@@ -1,6 +0,9 @@ | ||
## manage soustractive modelisation | ||
When you want to modelise, by example, a store with different 'roles' (could be any other 'flag'), that have different restrictions between roles, you have two ways to achieve this. | ||
the idea is to have a stack that goes from less to more restrictive API. | ||
We remove capabilities. | ||
## Soustractive modelisation | ||
The idea, often more suited and practical, is to have a stack that goes from less to more restrictive API. | ||
So we define the less restrictive API (here 'full'), and we remove capabilities depending on roles. | ||
```javascript | ||
@@ -14,5 +17,2 @@ var myStore = deep.ocm({ | ||
middle:{ | ||
schema:{ | ||
ownerRestriction:"userID" | ||
}, | ||
backgrounds:["../full"], | ||
@@ -22,4 +22,3 @@ post:deep.compose.before(function(object){ | ||
return deep.errors.PreconditionFailed(); | ||
}), | ||
del:deep.Store.forbidden() | ||
}) | ||
}, | ||
@@ -34,17 +33,25 @@ less:{ | ||
none:{ | ||
post:deep.Store.forbidden | ||
} | ||
}); | ||
myStore.flatten() | ||
.modes({roles:"full"}) | ||
.done(function(myStore){ | ||
return myStore.post({ title:"hello", userID:12 }); | ||
}) | ||
.logError(); | ||
deep | ||
.roles("full") | ||
.store(myStore) | ||
.post({ title:"hello", userID:"e12" }) | ||
.log() // log success | ||
.roles("middle") | ||
.post({ title:"world", userID:"e12" }) | ||
.log() // log error 412 (precondition) | ||
.roles("less") | ||
.post({ title:"hello", userID:"e13" }) | ||
.log() // log error 403 (Owner) | ||
.roles("none") | ||
.post({ title:"hello", userID:12 }) | ||
.log() // error 405 (Method not allowed) | ||
``` | ||
## manage additive modelisation | ||
## Additive modelisation | ||
... todo |
1057
lib/chain.js
@@ -8,3 +8,3 @@ /** | ||
} | ||
define(["require", "./utils", "./errors", "./promise", "./compose", "./protocol", "./query"], function (require, utils, errors, prom, compose, protoc, querier) { | ||
define(["require", "./utils", "./errors", "./promise", "./compose", "./protocol", "./query", "./nodes"], function(require, utils, errors, prom, compose, protoc, querier, nodes) { | ||
@@ -17,173 +17,171 @@ var addInChain = utils.addInChain; | ||
chains.BaseChain = compose.Classes(prom.Promise, | ||
function BaseChainConstructor(options) { | ||
options = options || {}; | ||
delete this._deep_promise_; | ||
this._deep_chain_ = true; | ||
this._queried = options._queried; | ||
this._nodes = options._nodes; // || [utils.createRootNode(this._value, options.schema, options)]; | ||
this.positions = []; | ||
this.deferred = null;//prom.Deferred(); | ||
}, | ||
{ | ||
_nodes: null, | ||
promise: function () { | ||
if(!this.deferred) | ||
this.deferred = prom.Deferred(); | ||
if (this._initialised && this._queue.length === 0 && (!this.oldQueue || this.oldQueue.length === 0) && !this._running && !this._executing) | ||
if (!this._error) | ||
this.deferred.resolve(this._success); | ||
else | ||
this.deferred.reject(this._error); | ||
return this.deferred.promise(); | ||
}, | ||
_forceHandle: function chainForce() { | ||
var self = this; | ||
if (self.deferred && (self.deferred.rejected || self.deferred.resolved || self.deferred.canceled)) | ||
throw errors.ChainEnded("chain has already been ended ! could'nt execute it further."); | ||
forceHandle.apply(this); | ||
if(!self.deferred) | ||
return; | ||
if (self._queue.length === 0 && !self._running) | ||
if (self._error) | ||
self.deferred.reject(self._error); | ||
else | ||
self.deferred.resolve(self._success); | ||
}, | ||
clone:function(cloneValues) { | ||
//console.log("chains.Chain.clone : ", handler, cloneValues); | ||
var handler = this; | ||
var newRes = []; | ||
if (cloneValues) | ||
newRes = newRes.concat(handler._nodes); | ||
var newHandler = new chains.Chain({ | ||
_root: handler._root, | ||
_rethrow: handler.rethrow, | ||
_nodes: newRes, | ||
_queried: handler._queried, | ||
_error: handler._error, | ||
_context: handler._context, | ||
_success: handler._success, | ||
_store:handler._store | ||
}); | ||
newHandler._initialised = true; | ||
return newHandler; | ||
}, | ||
//_____________________________________________________________ BRANCHES | ||
/** | ||
* asynch handler for chain branches creation | ||
* | ||
* if you return the branches function (the branch creator) : the chain will wait until all the branches are done before continuing | ||
* | ||
* Inject function result in chain as success or error. | ||
* | ||
* @example | ||
* deep().branches( function(branches) | ||
* { | ||
* branches.branch().query(...).load().log() | ||
* branches.branch().query(...).post().log(); | ||
* //... | ||
* return branches; | ||
* }); | ||
* | ||
* // if you want to return a subset of branches promises : | ||
* // you could use prom.all([array_of_promises]) : | ||
* | ||
* var branch = branches.branch().myChain()...; | ||
* //... | ||
* return prom.all([prom.when(branch), ...]); | ||
* | ||
* @method branches | ||
* @async | ||
* @chainable | ||
* @param {Function} func the callback that will receive the brancher (see above) | ||
* @return {chains.Chain} this | ||
*/ | ||
branches: function chainBranches(func) { | ||
var self = this; | ||
var create = function (s, e) { | ||
self.oldQueue = self.callQueue; | ||
self._queue = []; | ||
var a = func.call(self, brancher(self)); | ||
if (a === self) | ||
function BaseChainConstructor(options) { | ||
options = options || {}; | ||
delete this._deep_promise_; | ||
this._deep_chain_ = true; | ||
this._queried = options._queried; | ||
this._nodes = options._nodes; // || [nodes.root(this._value, options.schema, options)]; | ||
this.positions = []; | ||
this.deferred = null; //prom.Deferred(); | ||
}, { | ||
_nodes: null, | ||
promise: function() { | ||
if (!this.deferred) | ||
this.deferred = prom.Deferred(); | ||
if (this._initialised && this._queue.length === 0 && (!this.oldQueue || this.oldQueue.length === 0) && !this._running && !this._executing) | ||
if (!this._error) | ||
this.deferred.resolve(this._success); | ||
else | ||
this.deferred.reject(this._error); | ||
return this.deferred.promise(); | ||
}, | ||
_forceHandle: function chainForce() { | ||
var self = this; | ||
if (self.deferred && (self.deferred.rejected || self.deferred.resolved || self.deferred.canceled)) | ||
throw errors.ChainEnded("chain has already been ended ! could'nt execute it further."); | ||
forceHandle.apply(this); | ||
if (!self.deferred) | ||
return; | ||
return a; | ||
}; | ||
create._isDone_ = true; | ||
return addInChain.call(this, create); | ||
}, | ||
/** | ||
* save current chain position. it means that it will save | ||
* - current entries | ||
* - current success and errors | ||
* - current store (if any) in private queue before continuing. | ||
* | ||
* asynch | ||
* transparent true | ||
* | ||
* @method position | ||
* @param name the name of position (its id/label) | ||
* @param options optional object (no options for the moment) | ||
* @return {chains.Chain} this | ||
*/ | ||
position: function chainPosition(name, options) { | ||
var self = this; | ||
var func = function (s, e) { | ||
chains.chain.position(self, name, options); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
return this; | ||
}, | ||
/** | ||
* go back to a previously saved position (see .position). | ||
* If no name is provided : go back to last position (if any) | ||
* | ||
* throw an error if no position founded. | ||
* | ||
* inject chain values as chain success | ||
* | ||
* @method back | ||
* @chainable | ||
* @param {String} name the name of the last position asked | ||
* @param {Object} options (optional - no options for the moment) | ||
* @return {chains.Chain} | ||
*/ | ||
back: function chainBack(name, options) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var position = null; | ||
if (name) { | ||
var pos = self.positions.concat([]), | ||
ok = false; | ||
while (true && pos.length > 0) | ||
{ | ||
position = pos.pop(); | ||
if (position.name == name) { | ||
ok = true; | ||
break; | ||
if (self._queue.length === 0 && !self._running) | ||
if (self._error) | ||
self.deferred.reject(self._error); | ||
else | ||
self.deferred.resolve(self._success); | ||
}, | ||
clone: function(cloneValues) { | ||
//console.log("chains.Chain.clone : ", handler, cloneValues); | ||
var handler = this; | ||
var newRes = []; | ||
if (cloneValues) | ||
newRes = newRes.concat(handler._nodes); | ||
var newHandler = new chains.Chain({ | ||
_root: handler._root, | ||
_rethrow: handler.rethrow, | ||
_nodes: newRes, | ||
_queried: handler._queried, | ||
_error: handler._error, | ||
_context: handler._context, | ||
_success: handler._success, | ||
_store: handler._store | ||
}); | ||
newHandler._initialised = true; | ||
return newHandler; | ||
}, | ||
//_____________________________________________________________ BRANCHES | ||
/** | ||
* asynch handler for chain branches creation | ||
* | ||
* if you return the branches function (the branch creator) : the chain will wait until all the branches are done before continuing | ||
* | ||
* Inject function result in chain as success or error. | ||
* | ||
* @example | ||
* deep().branches( function(branches) | ||
* { | ||
* branches.branch().query(...).load().log() | ||
* branches.branch().query(...).post().log(); | ||
* //... | ||
* return branches; | ||
* }); | ||
* | ||
* // if you want to return a subset of branches promises : | ||
* // you could use prom.all([array_of_promises]) : | ||
* | ||
* var branch = branches.branch().myChain()...; | ||
* //... | ||
* return prom.all([prom.when(branch), ...]); | ||
* | ||
* @method branches | ||
* @async | ||
* @chainable | ||
* @param {Function} func the callback that will receive the brancher (see above) | ||
* @return {chains.Chain} this | ||
*/ | ||
branches: function chainBranches(func) { | ||
var self = this; | ||
var create = function(s, e) { | ||
self.oldQueue = self.callQueue; | ||
self._queue = []; | ||
var a = func.call(self, brancher(self)); | ||
if (a === self) | ||
return; | ||
return a; | ||
}; | ||
create._isDone_ = true; | ||
return addInChain.call(this, create); | ||
}, | ||
/** | ||
* save current chain position. it means that it will save | ||
* - current entries | ||
* - current success and errors | ||
* - current store (if any) in private queue before continuing. | ||
* | ||
* asynch | ||
* transparent true | ||
* | ||
* @method position | ||
* @param name the name of position (its id/label) | ||
* @param options optional object (no options for the moment) | ||
* @return {chains.Chain} this | ||
*/ | ||
position: function chainPosition(name, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
chains.chain.position(self, name, options); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.call(this, func); | ||
return this; | ||
}, | ||
/** | ||
* go back to a previously saved position (see .position). | ||
* If no name is provided : go back to last position (if any) | ||
* | ||
* throw an error if no position founded. | ||
* | ||
* inject chain values as chain success | ||
* | ||
* @method back | ||
* @chainable | ||
* @param {String} name the name of the last position asked | ||
* @param {Object} options (optional - no options for the moment) | ||
* @return {chains.Chain} | ||
*/ | ||
back: function chainBack(name, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var position = null; | ||
if (name) { | ||
var pos = self.positions.concat([]), | ||
ok = false; | ||
while (true && pos.length > 0) { | ||
position = pos.pop(); | ||
if (position.name == name) { | ||
ok = true; | ||
break; | ||
} | ||
} | ||
} | ||
if (pos.length === 0 && !ok) | ||
position = null; | ||
} else | ||
position = self.positions[self.position.length - 1]; | ||
if (!position) | ||
return errors.Internal("chain handler error : no positions to go back with name : " + name); | ||
self._nodes = position.entries; | ||
self._store = position.store; | ||
self._queried = position.queried; | ||
return position; | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
return this; | ||
} | ||
}); | ||
if (pos.length === 0 && !ok) | ||
position = null; | ||
} else | ||
position = self.positions[self.position.length - 1]; | ||
if (!position) | ||
return errors.Internal("chain handler error : no positions to go back with name : " + name); | ||
self._nodes = position.entries; | ||
self._store = position.store; | ||
self._queried = position.queried; | ||
return position; | ||
}; | ||
func._isDone_ = true; | ||
addInChain.call(this, func); | ||
return this; | ||
} | ||
}); | ||
var brancher = function (handler) { | ||
var brancher = function(handler) { | ||
var self = this; | ||
var br = { | ||
branches: [], | ||
branch: function () { | ||
if(this._ended) | ||
branch: function() { | ||
if (this._ended) | ||
throw errors.Chain("Branching failed : brancher has already bean ended. Could not add branches any more."); | ||
@@ -194,3 +192,3 @@ var cloned = handler.clone(true); | ||
}, | ||
promise: function () { | ||
promise: function() { | ||
this._ended = true; | ||
@@ -204,4 +202,3 @@ return prom.all(this.branches); | ||
chains.Chain = compose.Classes(chains.BaseChain, | ||
{ | ||
chains.Chain = compose.Classes(chains.BaseChain, { | ||
/** | ||
@@ -222,11 +219,11 @@ * | ||
*/ | ||
logValues: function (title, options) { | ||
logValues: function(title, options) { | ||
var self = this; | ||
options = options || {}; | ||
var func = function (success, error) { | ||
var func = function(success, error) { | ||
console.log(title || "deep.logValues : ", " (" + self._nodes.length + " values)"); | ||
self._nodes.forEach(function (e) { | ||
self._nodes.forEach(function(e) { | ||
var val = e; | ||
var entry = null; | ||
if (!options.full) | ||
@@ -239,3 +236,3 @@ val = e.value; | ||
}; | ||
return addInChain.apply(this, [func]); | ||
return addInChain.call(this, func); | ||
}, | ||
@@ -260,7 +257,7 @@ /** | ||
*/ | ||
interpret: function (context) { | ||
interpret: function(context) { | ||
var self = this; | ||
var func = function () { | ||
var applyContext = function (context) { | ||
return chains.chain.transform(self, function (v) { | ||
var func = function() { | ||
var applyContext = function(context) { | ||
return chains.chain.transform(self, function(v) { | ||
return utils.interpret(v, context); | ||
@@ -275,3 +272,3 @@ }); | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -293,68 +290,16 @@ }, | ||
*/ | ||
deepLoad: function (context, destructive) { | ||
deepLoad: function(context, destructive, excludeFunctions) { | ||
var self = this; | ||
if(typeof destructive === 'undefined') | ||
if (typeof destructive === 'undefined') | ||
destructive = false; | ||
var func = function (s, e) { | ||
var doDeepLoad = function (toLoad) { | ||
if (typeof toLoad.value === 'string') { | ||
var val = toLoad.value; | ||
if (context) | ||
val = utils.interpret(val, context); | ||
return protoc.get(val, { entry:toLoad }); | ||
} | ||
else if (typeof toLoad.value === 'function') { | ||
var d = null; | ||
if (toLoad.ancestor) | ||
d = toLoad.ancestor.value[toLoad.key](context); | ||
else | ||
d = toLoad.value(context); | ||
return prom.when(d); | ||
} else | ||
return toLoad.value; | ||
}; | ||
var promises = []; | ||
self._nodes.forEach(function (node) { | ||
var value = node.value; | ||
if(typeof value === "string") | ||
{ | ||
if (context) | ||
value = utils.interpret(value, context); | ||
promises.push(protoc.get(value, { entry:node })); | ||
} | ||
if(typeof value === "function") | ||
{ | ||
var d = null; | ||
if (node.ancestor) | ||
d = node.ancestor.value[node.key](context); | ||
else | ||
d = node.value(context); | ||
promises.push(d); | ||
} | ||
else if(typeof value === 'object') | ||
{ | ||
if(!destructive) | ||
{ | ||
node = utils.simpleCopy(node); | ||
node.value = utils.copy(value); | ||
} | ||
var toLoads = querier.query(node, ".//!?or(_type=string,_type=function)", { | ||
resultType: "full" | ||
}); | ||
var p = chains.chain.transformNodes(toLoads, doDeepLoad) | ||
.done(function(e){ | ||
return node.value; | ||
}); | ||
promises.push(p); | ||
} | ||
}); | ||
return prom.all(promises) | ||
.done(function(res){ | ||
if(!self._queried) | ||
return res.shift(); | ||
return res; | ||
}); | ||
var func = function(s, e) { | ||
return nodes.deepLoad(self._nodes, context, destructive, excludeFunctions) | ||
.done(function(res) { | ||
if (!self._queried && res.shift) | ||
return res.shift(); | ||
return res; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
return addInChain.apply(this, [func]); | ||
return addInChain.call(this, func); | ||
}, | ||
@@ -380,11 +325,12 @@ /** | ||
*/ | ||
load: function (context, destructive) { | ||
load: function(context, destructive) { | ||
var self = this; | ||
if(typeof destructive === 'undefined') | ||
if (typeof destructive === 'undefined') | ||
destructive = false; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
//console.log("self.load : queried : ", self._queried, " - nodes : ", self._nodes); | ||
if(!self._queried && self._nodes[0] && self._nodes[0].value instanceof Array) | ||
{ | ||
self._nodes = querier.query(self._nodes[0], "./*", { resultType:"full"}); | ||
if (!self._queried && self._nodes[0] && self._nodes[0].value instanceof Array) { | ||
self._nodes = querier.query(self._nodes[0], "./*", { | ||
resultType: "full" | ||
}); | ||
self._queried = true; | ||
@@ -394,3 +340,3 @@ } | ||
var doLoad = function (v) { | ||
var doLoad = function(v) { | ||
//console.log("deep.load : node : ",v); | ||
@@ -401,35 +347,34 @@ if (!v.value) | ||
return prom.when(callFunctionFromValue(v, "load", [context])); | ||
else if (typeof v.value === 'string') | ||
{ | ||
else if (typeof v.value === 'string') { | ||
var val = v.value; | ||
if(context) | ||
if (context) | ||
val = utils.interpret(val, context); | ||
return prom.when(protoc.get(val, {entry:v})) | ||
.done(function(r){ | ||
//console.log("load res : ",r) | ||
if(destructive) | ||
{ | ||
if(v.ancestor) | ||
v.ancestor.value[v.key] = r; | ||
v.value = r; | ||
} | ||
return r; | ||
}); | ||
} | ||
else | ||
return prom.when(protoc.get(val, { | ||
entry: v | ||
})) | ||
.done(function(r) { | ||
//console.log("load res : ",r) | ||
if (destructive) { | ||
if (v.ancestor) | ||
v.ancestor.value[v.key] = r; | ||
v.value = r; | ||
} | ||
return r; | ||
}); | ||
} else | ||
return v.value; | ||
}; | ||
self._nodes.forEach(function(n){ | ||
self._nodes.forEach(function(n) { | ||
res.push(doLoad(n)); | ||
}); | ||
return prom.all(res) | ||
.done(function (res){ | ||
//console.log("load res : ", res) | ||
if(!self._queried) | ||
return res.shift(); | ||
return res; | ||
}); | ||
.done(function(res) { | ||
//console.log("load res : ", res) | ||
if (!self._queried) | ||
return res.shift(); | ||
return res; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
return addInChain.apply(this, [func]); | ||
return addInChain.call(this, func); | ||
}, | ||
@@ -449,6 +394,6 @@ // ________________________________________ READ ENTRIES | ||
*/ | ||
query: function () { | ||
query: function() { | ||
var self = this; | ||
var args = arguments; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
var nodes = []; | ||
@@ -470,4 +415,3 @@ var values = []; | ||
} else | ||
for(var j = 0; j < self._nodes.length; ++j) | ||
{ | ||
for (var j = 0; j < self._nodes.length; ++j) { | ||
var n = self._nodes[j]; | ||
@@ -510,10 +454,10 @@ n = querier.query(n, q, { | ||
*/ | ||
val: function (callBack) { | ||
val: function(callBack) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
if (typeof callBack === 'string') | ||
return prom.when(protoc.get(callBack)) | ||
.done(function (callBack) { | ||
return applyCallBackOrTreatment(callBack, chains.chain.val(self)); | ||
}); | ||
.done(function(callBack) { | ||
return applyCallBackOrTreatment(callBack, chains.chain.val(self)); | ||
}); | ||
else | ||
@@ -524,3 +468,3 @@ return applyCallBackOrTreatment(callBack, chains.chain.val(self)); | ||
if (callBack) { | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -543,6 +487,6 @@ } | ||
*/ | ||
first: function (callBack) { | ||
first: function(callBack) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var shouldModify = function (callBack) { | ||
var func = function(s, e) { | ||
var shouldModify = function(callBack) { | ||
if (callBack === true) | ||
@@ -558,4 +502,4 @@ return chains.chain.first(self, true); | ||
func._isDone_ = true; | ||
if (callBack){ | ||
addInChain.apply(this, [func]); | ||
if (callBack) { | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -580,6 +524,6 @@ } | ||
*/ | ||
last: function (callBack) { | ||
last: function(callBack) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var shouldModify = function (callBack) { | ||
var func = function(s, e) { | ||
var shouldModify = function(callBack) { | ||
if (callBack === true) | ||
@@ -598,3 +542,3 @@ return chains.chain.last(self, true); | ||
if (callBack) { | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -616,6 +560,6 @@ } | ||
*/ | ||
each: function (callBack) { | ||
each: function(callBack) { | ||
var self = this; | ||
var func = function () { | ||
var applyCallBackOrTreatment = function (callBack) { | ||
var func = function() { | ||
var applyCallBackOrTreatment = function(callBack) { | ||
return prom.all(chains.chain.each(self, callBack)); | ||
@@ -630,3 +574,3 @@ }; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -648,10 +592,10 @@ }, | ||
*/ | ||
values: function (callBack) { | ||
values: function(callBack) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
if (typeof callBack === 'string') | ||
return prom.when(protoc.get(callBack)) | ||
.done(function (callBack) { | ||
return applyCallBackOrTreatment(callBack, chains.chain.values(self)); | ||
}); | ||
.done(function(callBack) { | ||
return applyCallBackOrTreatment(callBack, chains.chain.values(self)); | ||
}); | ||
return applyCallBackOrTreatment(callBack, chains.chain.values(self)); | ||
@@ -661,3 +605,3 @@ }; | ||
if (callBack) { | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -685,6 +629,6 @@ } | ||
*/ | ||
transform: function (transformer) { | ||
transform: function(transformer) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var applyTransformer = function (transformer) { | ||
var func = function(s, e) { | ||
var applyTransformer = function(transformer) { | ||
return chains.chain.transform(self, transformer); | ||
@@ -699,3 +643,3 @@ }; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -719,11 +663,10 @@ }, | ||
*/ | ||
run: function (funcRef, args) { | ||
run: function(funcRef, args) { | ||
var self = this; | ||
args = args || []; | ||
if(funcRef && funcRef.forEach) | ||
{ | ||
if (funcRef && funcRef.forEach) { | ||
args = funcRef; | ||
funcRef = null; | ||
} | ||
var doRun = function(node){ | ||
var doRun = function(node) { | ||
@@ -746,8 +689,7 @@ //console.log("doRun : ", node) | ||
}; | ||
var create = function (s, e) { | ||
var create = function(s, e) { | ||
//console.log("deep.run : ", funcRef) | ||
if(!self._queried) | ||
{ | ||
if(!self._nodes[0]) | ||
if (!self._queried) { | ||
if (!self._nodes[0]) | ||
return undefined; | ||
@@ -757,3 +699,3 @@ return doRun(self._nodes[0]); | ||
var alls = []; | ||
self._nodes.forEach(function (node) { | ||
self._nodes.forEach(function(node) { | ||
alls.push(doRun(node)); | ||
@@ -784,6 +726,6 @@ }); | ||
*/ | ||
exec: function (func, args) { | ||
exec: function(func, args) { | ||
var self = this; | ||
args = args || []; | ||
var create = function () { | ||
var create = function() { | ||
return func.apply({}, args); | ||
@@ -805,5 +747,5 @@ }; | ||
*/ | ||
reverse: function () { | ||
reverse: function() { | ||
var self = this; | ||
var create = function (s, e) { | ||
var create = function(s, e) { | ||
if (self._nodes.length === 0) | ||
@@ -828,6 +770,6 @@ return; | ||
*/ | ||
sort: function () { | ||
sort: function() { | ||
var args = arguments; | ||
var self = this; | ||
var create = function (s, e) { | ||
var create = function(s, e) { | ||
if (args.length === 0) | ||
@@ -878,5 +820,5 @@ args = ["+"]; | ||
*/ | ||
range: function (start, end, query) { | ||
range: function(start, end, query) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
var total, count, res; | ||
@@ -887,29 +829,32 @@ if (self._nodes.length === 0) | ||
var val = self._nodes[0]; | ||
if(!self.queried && !(val.value instanceof Array)) | ||
// no range and no query could be applied : only one object | ||
if (!self.queried && !(val.value instanceof Array)) | ||
// no range and no query could be applied : only one object | ||
return errors.Range("no range could be applied on chain : chain holds only on object (not an array)."); | ||
if(query) // apply query, then slice | ||
if (query) // apply query, then slice | ||
{ | ||
if(self.queried) | ||
self._nodes = chains.chain.select(self, query, { resultType:"full" }); | ||
if (self.queried) | ||
self._nodes = chains.chain.select(self, query, { | ||
resultType: "full" | ||
}); | ||
else // (val instanceof Array) | ||
self._nodes = querier.query(val.value, query, { resultType:"full"}); | ||
self._nodes = querier.query(val.value, query, { | ||
resultType: "full" | ||
}); | ||
//console.log("rabge after query : nodes: ", total, self._nodes.length); | ||
total = self._nodes.length; | ||
self._nodes = self._nodes.slice(start, end+1); | ||
} | ||
else // simple slice | ||
self._nodes = self._nodes.slice(start, end + 1); | ||
} else // simple slice | ||
{ | ||
if(self.queried) | ||
{ | ||
if (self.queried) { | ||
total = self._nodes.length; | ||
self._nodes = self._nodes.slice(start, end+1); | ||
} | ||
else // (val instanceof Array) | ||
self._nodes = self._nodes.slice(start, end + 1); | ||
} else // (val instanceof Array) | ||
{ | ||
total = val.value.length; | ||
// ==> query = ./[start:end] | ||
self._nodes = querier.query(val, "./["+start+":"+end+"]", { resultType:"full"}); | ||
self._nodes = querier.query(val, "./[" + start + ":" + end + "]", { | ||
resultType: "full" | ||
}); | ||
} | ||
@@ -923,3 +868,3 @@ } | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -942,7 +887,7 @@ }, | ||
*/ | ||
parents: function (errorIfEmpty) { | ||
parents: function(errorIfEmpty) { | ||
var self = this; | ||
var func = function () { | ||
var func = function() { | ||
var res = []; | ||
self._nodes.forEach(function (r) { | ||
self._nodes.forEach(function(r) { | ||
if (r.ancestor) | ||
@@ -959,3 +904,3 @@ res.push(r.ancestor); | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return self; | ||
@@ -971,20 +916,20 @@ }, | ||
*/ | ||
deep: function (object, schema, options) { | ||
deep: function(object, schema, options) { | ||
var self = this; | ||
var func = function () { | ||
var func = function() { | ||
//console.log("deep chain restart") | ||
return deep(object, schema, options) | ||
.done(function (s) { | ||
//console.log("deep restart resolved: ", s) | ||
self._nodes = this._nodes; | ||
self._root = this._root; | ||
self._success = this._success; | ||
self._queried = false; | ||
//console.log("self : ",self._success) | ||
//return this.delay(100).log("done") | ||
//return chains.chain.val(self); | ||
}); | ||
.done(function(s) { | ||
//console.log("deep restart resolved: ", s) | ||
self._nodes = this._nodes; | ||
self._root = this._root; | ||
self._success = this._success; | ||
self._queried = false; | ||
//console.log("self : ",self._success) | ||
//return this.delay(100).log("done") | ||
//return chains.chain.val(self); | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1004,8 +949,8 @@ }, | ||
*/ | ||
setByPath: function (path, obj) { | ||
setByPath: function(path, obj) { | ||
var self = this; | ||
var func = function () { | ||
var applySet = function (obj) { | ||
var func = function() { | ||
var applySet = function(obj) { | ||
var res = []; | ||
self._nodes.forEach(function (result) { | ||
self._nodes.forEach(function(result) { | ||
res.push(utils.setValueByPath(result.value, path, obj, '/')); | ||
@@ -1021,3 +966,3 @@ }); | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1036,21 +981,21 @@ }, | ||
*/ | ||
up: function () { | ||
up: function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var self = this; | ||
var func = function () { | ||
var func = function() { | ||
return prom.when(protoc.getAll(args)) | ||
.done(function (objects) { | ||
self._nodes.forEach(function (result) { | ||
objects.forEach(function (object) { | ||
//console.log("deep.up : entry : ", result.value, " - to apply : ", object) | ||
result.value = utils.up(object, result.value); | ||
if (result.ancestor) | ||
result.ancestor.value[result.key] = result.value; | ||
.done(function(objects) { | ||
self._nodes.forEach(function(result) { | ||
objects.forEach(function(object) { | ||
//console.log("deep.up : entry : ", result.value, " - to apply : ", object) | ||
result.value = utils.up(object, result.value); | ||
if (result.ancestor) | ||
result.ancestor.value[result.key] = result.value; | ||
}); | ||
}); | ||
return chains.chain.val(self); | ||
}); | ||
return chains.chain.val(self); | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1069,21 +1014,21 @@ }, | ||
*/ | ||
bottom: function () { | ||
bottom: function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.reverse(); | ||
var self = this; | ||
var func = function () { | ||
var func = function() { | ||
return prom.when(protoc.getAll(args)) | ||
.done(function (objects) { | ||
self._nodes.forEach(function (result) { | ||
objects.forEach(function (object) { | ||
result.value = utils.bottom(object, result.value); | ||
if (result.ancestor) | ||
result.ancestor.value[result.key] = result.value; | ||
.done(function(objects) { | ||
self._nodes.forEach(function(result) { | ||
objects.forEach(function(object) { | ||
result.value = utils.bottom(object, result.value); | ||
if (result.ancestor) | ||
result.ancestor.value[result.key] = result.value; | ||
}); | ||
}); | ||
return chains.chain.val(self); | ||
}); | ||
return chains.chain.val(self); | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1127,5 +1072,5 @@ }, | ||
*/ | ||
replace: function (what, by, options) { | ||
replace: function(what, by, options) { | ||
var self = this; | ||
var func = function () { | ||
var func = function() { | ||
var replaced = []; | ||
@@ -1139,4 +1084,4 @@ | ||
} | ||
var doReplace = function (by) { | ||
self._nodes.forEach(function (r) { | ||
var doReplace = function(by) { | ||
self._nodes.forEach(function(r) { | ||
r = querier.query(r, what, { | ||
@@ -1160,3 +1105,3 @@ resultType: "full" | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1218,9 +1163,9 @@ }, | ||
*/ | ||
remove: function (what) { | ||
remove: function(what) { | ||
var self = this; | ||
var func = function () { | ||
var func = function() { | ||
return chains.chain.remove(self, what); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1242,5 +1187,5 @@ }, | ||
*/ | ||
valuesEqual: function (obj) { | ||
valuesEqual: function(obj) { | ||
var self = this; | ||
var func = function (s,e) { | ||
var func = function(s, e) { | ||
var toTest = chains.chain.val(self); | ||
@@ -1259,3 +1204,3 @@ var ok = utils.deepEqual(toTest, obj); | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return self; | ||
@@ -1291,6 +1236,6 @@ }, | ||
*/ | ||
validate: function (schema) { | ||
validate: function(schema) { | ||
var self = this; | ||
var func = function () { | ||
var runSchema = function (schema) { | ||
var func = function() { | ||
var runSchema = function(schema) { | ||
var report = { | ||
@@ -1300,3 +1245,3 @@ valid: true, | ||
}; | ||
self._nodes.forEach(function (e) { | ||
self._nodes.forEach(function(e) { | ||
var rep = deep.validate(e.value, schema || e.schema || {}); | ||
@@ -1321,3 +1266,3 @@ report.reports.push(rep); | ||
func._name = "chains.chain.validate"; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1331,7 +1276,7 @@ }, | ||
*/ | ||
assert: function (callBack) { | ||
assert: function(callBack) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
//console.log("chains.Chain.done : ",s,e) | ||
var doTest = function (a) { | ||
var doTest = function(a) { | ||
if (a !== true) | ||
@@ -1355,3 +1300,3 @@ return errors.Assertion("assertion failed"); | ||
func._isDone_ = true; | ||
return addInChain.apply(this, [func]); | ||
return addInChain.call(this, func); | ||
}, | ||
@@ -1398,7 +1343,7 @@ //__________________________________________________________ MAP | ||
*/ | ||
mapOn: function (what, localKey, foreignKey, whereToStore) { | ||
mapOn: function(what, localKey, foreignKey, whereToStore) { | ||
var self = this; | ||
var doMap = function (what, localKey, foreignKey, whereToStore) { | ||
var doMap = function(what, localKey, foreignKey, whereToStore) { | ||
var map = {}; | ||
what.forEach(function (w) { | ||
what.forEach(function(w) { | ||
//console.log("mapOn : w :", w) | ||
@@ -1416,6 +1361,6 @@ if (w === null) | ||
}); | ||
self._nodes.forEach(function (entry) { | ||
self._nodes.forEach(function(entry) { | ||
//console.log(" finalise mapping : ", entry.value, localKey, map, entry.value[localKey]) | ||
if(!self._queried && entry.value && entry.value.forEach) | ||
entry.value.forEach(function(item){ | ||
if (!self._queried && entry.value && entry.value.forEach) | ||
entry.value.forEach(function(item) { | ||
if (map[item[localKey]]) | ||
@@ -1430,3 +1375,3 @@ item[whereToStore || localKey] = map[item[localKey]]; | ||
}; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
if (self._nodes.length === 0) | ||
@@ -1439,4 +1384,4 @@ return chains.chain.values(self); | ||
var localKeyQuery = localKey; | ||
if(!self._queried && self._nodes[0].value && self._nodes[0].value.forEach) | ||
localKeyQuery = "*/"+localKey; | ||
if (!self._queried && self._nodes[0].value && self._nodes[0].value.forEach) | ||
localKeyQuery = "*/" + localKey; | ||
//console.log("____________________________ mapon : query : ","./" + localKey); | ||
@@ -1455,6 +1400,6 @@ var foreigns = chains.chain.select(cloned, "./" + localKeyQuery).join(","); | ||
return protoc.get(parsed) | ||
.done(function (results) { | ||
results = [].concat(results); | ||
return doMap(results, localKey, foreignKey, whereToStore); | ||
}); | ||
.done(function(results) { | ||
results = [].concat(results); | ||
return doMap(results, localKey, foreignKey, whereToStore); | ||
}); | ||
else | ||
@@ -1466,3 +1411,3 @@ return errors.Internal("deep.mapOn need array as 'what' : provided : " + JSON.stringify(what)); | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1512,9 +1457,9 @@ }, | ||
*/ | ||
getRelations: function () { | ||
getRelations: function() { | ||
var self = this; | ||
var relations = Array.prototype.slice.apply(arguments); | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
var alls = []; | ||
var temp = []; | ||
self._nodes.forEach(function (entry) { | ||
self._nodes.forEach(function(entry) { | ||
if (!entry.schema || !entry.schema.links) | ||
@@ -1528,16 +1473,16 @@ return; | ||
querier.query(entry.schema.links, "./*?rel=in=(" + relations.join(",") + ")") | ||
.forEach(function (relation) { | ||
//console.log("getRelations : got : ", relation) | ||
var path = utils.interpret(relation.href, entry.value); | ||
var parsed = utils.parseRequest(path); | ||
var wrap = { | ||
rel: relation | ||
//href: parsed | ||
}; | ||
r[relation] = wrap; | ||
alls.push(protoc.get(parsed, { | ||
defaultProtocole: "json", | ||
wrap: wrap | ||
})); | ||
}); | ||
.forEach(function(relation) { | ||
//console.log("getRelations : got : ", relation) | ||
var path = utils.interpret(relation.href, entry.value); | ||
var parsed = utils.parseRequest(path); | ||
var wrap = { | ||
rel: relation | ||
//href: parsed | ||
}; | ||
r[relation] = wrap; | ||
alls.push(protoc.get(parsed, { | ||
defaultProtocole: "json", | ||
wrap: wrap | ||
})); | ||
}); | ||
}); | ||
@@ -1547,9 +1492,9 @@ if (alls.length === 0) | ||
return prom.all(alls) | ||
.done(function (s) { | ||
//console.log("get relations : ", s) | ||
return s; | ||
}); | ||
.done(function(s) { | ||
//console.log("get relations : ", s) | ||
return s; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
@@ -1596,3 +1541,3 @@ }, | ||
*/ | ||
mapRelations: function (map, delimitter) { | ||
mapRelations: function(map, delimitter) { | ||
if (!delimitter) | ||
@@ -1605,5 +1550,5 @@ delimitter = "."; | ||
//console.log("mapRelations : relations : ", relations); | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
var promises = []; | ||
self._nodes.forEach(function (entry) { | ||
self._nodes.forEach(function(entry) { | ||
if (!entry.schema || !entry.schema.links) | ||
@@ -1614,22 +1559,22 @@ return; | ||
querier.query(entry.schema.links, "./*?rel=in=(" + relations.join(",") + ")") | ||
.forEach(function (relation) { | ||
//console.log("do map relations on : ", relation); | ||
var path = utils.interpret(relation.href, entry.value); | ||
alls.push(protoc.get(path, { | ||
defaultProtocole: "json", | ||
wrap: { | ||
path: map[relation.rel] | ||
} | ||
})); | ||
}); | ||
.forEach(function(relation) { | ||
//console.log("do map relations on : ", relation); | ||
var path = utils.interpret(relation.href, entry.value); | ||
alls.push(protoc.get(path, { | ||
defaultProtocole: "json", | ||
wrap: { | ||
path: map[relation.rel] | ||
} | ||
})); | ||
}); | ||
var d = prom.all(alls) | ||
.done(function (results) { | ||
//console.log("mapRelations : results : "); | ||
//console.log(JSON.stringify(results)); | ||
results.forEach(function (r) { | ||
//console.log("do : ", r, " - on : ", entry.value) | ||
utils.setValueByPath(entry.value, r.path, r.result, delimitter); | ||
.done(function(results) { | ||
//console.log("mapRelations : results : "); | ||
//console.log(JSON.stringify(results)); | ||
results.forEach(function(r) { | ||
//console.log("do : ", r, " - on : ", entry.value) | ||
utils.setValueByPath(entry.value, r.path, r.result, delimitter); | ||
}); | ||
return results; | ||
}); | ||
return results; | ||
}); | ||
promises.push(d); | ||
@@ -1640,12 +1585,13 @@ }); | ||
return prom.all(promises) | ||
.done(function(results){ | ||
if(!self._queried) | ||
return results.shift(); | ||
}); | ||
.done(function(results) { | ||
if (!self._queried) | ||
return results.shift(); | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
addInChain.call(this, func); | ||
return this; | ||
} | ||
}); | ||
function callFunctionFromValue(entry, functionName, args) { | ||
@@ -1665,2 +1611,3 @@ if (!entry._deep_query_node_) | ||
} | ||
function runFunctionFromValue(entry, func, args) { | ||
@@ -1680,2 +1627,3 @@ if (!entry._deep_query_node_) | ||
} | ||
function applyCallBackOrTreatment(callBack, value) { | ||
@@ -1696,3 +1644,3 @@ var r = null; | ||
addInChain: addInChain, | ||
/** | ||
/** | ||
* same as .query : but in place of holding queried entries : it return directly the query results. | ||
@@ -1709,3 +1657,3 @@ * Is the synch version of the query handle. | ||
*/ | ||
select: function (handler, q, options) { | ||
select: function(handler, q, options) { | ||
var self = handler; | ||
@@ -1715,4 +1663,4 @@ if (!(q instanceof Array)) | ||
var res = []; | ||
handler._nodes.forEach(function (r) { | ||
q.forEach(function (qu) { | ||
handler._nodes.forEach(function(r) { | ||
q.forEach(function(qu) { | ||
res = res.concat(querier.query(r, qu, options)); | ||
@@ -1726,3 +1674,3 @@ }); | ||
var res = ""; | ||
handler._nodes.forEach(function (e) { | ||
handler._nodes.forEach(function(e) { | ||
if (options.pretty) | ||
@@ -1749,3 +1697,3 @@ res += JSON.stringify(e.value, null, ' ') + "\n"; | ||
if (transfo.nodes.value instanceof Array) { | ||
transfo.nodes.value.forEach(function (v) { | ||
transfo.nodes.value.forEach(function(v) { | ||
transfo.results.push(transformer(v)); | ||
@@ -1760,3 +1708,3 @@ }); | ||
transfo.nodes = handler._nodes; | ||
transfo.nodes.forEach(function (e) { | ||
transfo.nodes.forEach(function(e) { | ||
transfo.results.push(transformer(e.value)); | ||
@@ -1767,33 +1715,16 @@ }); | ||
return transfo.promise | ||
.done(function (res) { | ||
if (handler._queried) | ||
transfo.nodes.forEach(function (n) { | ||
n.value = res.shift(); | ||
if (n.ancestor) | ||
n.ancestor.value[n.key] = n.value; | ||
}); | ||
else { | ||
transfo.nodes.value = res; | ||
if (transfo.nodes.ancestor) | ||
transfo.nodes.ancestor.value[res.key] = res.value; | ||
} | ||
return res; | ||
}); | ||
}, | ||
transformNodes: function utilsTransfoNodes(nodes, transformer) { | ||
var results = []; | ||
nodes.forEach(function (e) { | ||
results.push(transformer(e)); | ||
}); | ||
return prom.all(results) | ||
.done(function (res) { | ||
var fin = []; | ||
nodes.forEach(function (n) { | ||
n.value = res.shift(); | ||
if (n.ancestor) | ||
n.ancestor.value[n.key] = n.value; | ||
fin.push(n.value); | ||
.done(function(res) { | ||
if (handler._queried) | ||
transfo.nodes.forEach(function(n) { | ||
n.value = res.shift(); | ||
if (n.ancestor) | ||
n.ancestor.value[n.key] = n.value; | ||
}); | ||
else { | ||
transfo.nodes.value = res; | ||
if (transfo.nodes.ancestor) | ||
transfo.nodes.ancestor.value[res.key] = res.value; | ||
} | ||
return res; | ||
}); | ||
return fin; | ||
}); | ||
}, | ||
@@ -1805,3 +1736,3 @@ val: function utilsVal(handler) { | ||
return this.values(handler); | ||
if(handler._nodes.forEach) | ||
if (handler._nodes.forEach) | ||
return handler._nodes[0].value; | ||
@@ -1812,3 +1743,3 @@ return handler._nodes.value; | ||
console.log("chains.chain.first : ", handler, modifyNodes) | ||
if(!handler._nodes) | ||
if (!handler._nodes) | ||
return deep.Undefined; | ||
@@ -1859,3 +1790,3 @@ if (handler._nodes && handler._nodes.length === 0) | ||
var res = []; | ||
handler._nodes.forEach(function (e) { | ||
handler._nodes.forEach(function(e) { | ||
res.push(e.value); | ||
@@ -1868,3 +1799,3 @@ }); | ||
if (!handler._queried && (handler._nodes[0].value instanceof Array)) | ||
handler._nodes[0].value.forEach(function (v) { | ||
handler._nodes[0].value.forEach(function(v) { | ||
if (typeof callBack === 'object') | ||
@@ -1876,3 +1807,3 @@ res.push(utils.execTreatment.call(callBack, v)); | ||
else | ||
handler._nodes.forEach(function (e) { | ||
handler._nodes.forEach(function(e) { | ||
if (typeof callBack === 'object') | ||
@@ -1890,3 +1821,3 @@ res.push(utils.execTreatment.call(callBack, e.value)); | ||
var res = []; | ||
handler._nodes.forEach(function (e) { | ||
handler._nodes.forEach(function(e) { | ||
res.push(e); | ||
@@ -1898,3 +1829,3 @@ }); | ||
var res = []; | ||
handler._nodes.forEach(function (e) { | ||
handler._nodes.forEach(function(e) { | ||
res.push(e.paths); | ||
@@ -1904,5 +1835,5 @@ }); | ||
}, | ||
schemas: function (handler) { | ||
schemas: function(handler) { | ||
var res = []; | ||
handler._nodes.forEach(function (e) { | ||
handler._nodes.forEach(function(e) { | ||
res.push(e.schema); | ||
@@ -1922,4 +1853,5 @@ }); | ||
}, | ||
remove: function (handler, what) { | ||
remove: function(handler, what) { | ||
var removed = []; | ||
function finalise(r) { | ||
@@ -1935,3 +1867,3 @@ if (!r.ancestor) | ||
} | ||
handler._nodes.forEach(function (r) { | ||
handler._nodes.forEach(function(r) { | ||
r = querier.query(r, what, { | ||
@@ -1951,3 +1883,3 @@ resultType: "full" | ||
//_________________________________________________ | ||
chains.Chain.add = function addChainHandle(name, func) { | ||
@@ -1957,5 +1889,5 @@ chains.Chain.prototype[name] = func; | ||
}; | ||
chains.Chain.add("nodes", function (callBack) { | ||
chains.Chain.add("nodes", function(callBack) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
return callBack(chains.chain.nodes(self)); | ||
@@ -1970,8 +1902,8 @@ }; | ||
}); | ||
chains.Chain.add("init", function () { | ||
chains.Chain.add("init", function() { | ||
var args = arguments; | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
var alls = []; | ||
chains.chain.each(self, function (v) { | ||
chains.chain.each(self, function(v) { | ||
if (typeof v.init === "function") | ||
@@ -1988,5 +1920,5 @@ alls.push(v.init.apply(v, args)); | ||
}); | ||
chains.Chain.add("iterate", function (done, fail) { | ||
chains.Chain.add("iterate", function(done, fail) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
return deep.iterate(chains.chain.values(self), done, fail); | ||
@@ -1998,8 +1930,10 @@ }; | ||
}); | ||
chains.Chain.add("wired", function (args, context, done, fail) { | ||
chains.Chain.add("wired", function(args, context, done, fail) { | ||
var self = this; | ||
var func = function (s, e) { | ||
var func = function(s, e) { | ||
var nodes = null; | ||
if(!self._queried && self._nodes[0].value instanceof Array) | ||
nodes = querier.query(self._nodes[0], "./*", { resultType:"full" }); | ||
if (!self._queried && self._nodes[0].value instanceof Array) | ||
nodes = querier.query(self._nodes[0], "./*", { | ||
resultType: "full" | ||
}); | ||
else | ||
@@ -2013,3 +1947,3 @@ nodes = chains.chain.nodes(self); | ||
}); | ||
/** | ||
/** | ||
* will perform FULL backgrounds application on chain entries. (see backgrounds documentation) | ||
@@ -2055,7 +1989,7 @@ * @chainable | ||
*/ | ||
chains.Chain.add("flatten", function () { | ||
chains.Chain.add("flatten", function() { | ||
var self = this; | ||
var doFlatten = function () { | ||
var doFlatten = function() { | ||
var alls = []; | ||
self._nodes.forEach(function (node) { | ||
self._nodes.forEach(function(node) { | ||
if (!node.value || typeof node.value !== 'object') | ||
@@ -2068,5 +2002,5 @@ return; | ||
return prom.all(alls) | ||
.done(function () { | ||
return chains.chain.val(self); | ||
}); | ||
.done(function() { | ||
return chains.chain.val(self); | ||
}); | ||
}; | ||
@@ -2081,36 +2015,35 @@ //flattenBackgrounds._isDone_ = true; | ||
/** | ||
* apply arguments from UP on each entries : will merge objects and array together DEEPLY. see docs and examples. | ||
* | ||
* synch | ||
* inject entries values as chain success. | ||
* | ||
* @method up | ||
* @chainable | ||
* @param objects a list (coma separated - not an array) of objects to apply on each chain entries | ||
* @return {chains.Chain} this | ||
*/ | ||
chains.Chain.add("sheet", function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
var self = this; | ||
var func = function () { | ||
var alls = []; | ||
return prom.when(protoc.getAll(args)) | ||
.done(function (objects) { | ||
self._nodes.forEach(function (result) { | ||
objects.forEach(function (object) { | ||
alls.push(deep.sheet(object, result) ); | ||
/** | ||
* apply arguments from UP on each entries : will merge objects and array together DEEPLY. see docs and examples. | ||
* | ||
* synch | ||
* inject entries values as chain success. | ||
* | ||
* @method up | ||
* @chainable | ||
* @param objects a list (coma separated - not an array) of objects to apply on each chain entries | ||
* @return {chains.Chain} this | ||
*/ | ||
chains.Chain.add("sheet", function() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var self = this; | ||
var func = function() { | ||
var alls = []; | ||
return prom.when(protoc.getAll(args)) | ||
.done(function(objects) { | ||
self._nodes.forEach(function(result) { | ||
objects.forEach(function(object) { | ||
alls.push(deep.sheet(object, result)); | ||
}); | ||
}); | ||
if(args.length == 1) | ||
if (args.length == 1) | ||
return prom.when(alls[0]); | ||
return prom.all(alls); | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.apply(this, [func]); | ||
return this; | ||
}); | ||
return chains; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.call(this, func); | ||
return this; | ||
}); | ||
return chains; | ||
}); |
@@ -20,8 +20,10 @@ /** | ||
var args = Array.prototype.slice.apply(arguments); | ||
if(args.length === 0) | ||
return deep.when({}); | ||
return deep.getAll(args) | ||
.done(function(res){ | ||
var base = utils.copy(res[res.length-1]); | ||
var len = res.length-2; | ||
for(;len>-1;--len) | ||
utils.bottom( res[len], base ); | ||
var base = utils.copy(res[0]); | ||
var len = res.length; | ||
for(var i = 1;i < len ;++i) | ||
utils.up( res[i], base ); | ||
return base; | ||
@@ -31,2 +33,11 @@ }); | ||
utils.compile = function (){ | ||
var base = utils.copy(arguments[0]); | ||
var len = arguments.length; | ||
for(var i = 1;i < len ;++i) | ||
utils.up( arguments[i], base ); | ||
return base; | ||
}; | ||
asynch.up = function (){ | ||
@@ -56,9 +67,2 @@ var args = Array.prototype.slice.apply(arguments); | ||
utils.compile = function (){ | ||
var base = utils.copy(arguments[arguments.length-1]); | ||
var len = arguments.length-2; | ||
for(;len>-1;--len) | ||
utils.bottom( arguments[len], base ); | ||
return base; | ||
}; | ||
@@ -132,4 +136,19 @@ utils.upFromArgs = function (base, args){ | ||
} | ||
if(target && target._deep_compiler_) | ||
if(src._deep_sheet_) | ||
{ | ||
if(!target._deep_sheet_) | ||
{ | ||
deep.sheet(src, target); | ||
return target; | ||
} | ||
} | ||
else if(target._deep_sheet_) | ||
{ | ||
src = utils.copy(src); | ||
if(parent) | ||
parent[key] = src; | ||
return src; | ||
} | ||
if(target._deep_compiler_) | ||
{ | ||
target = target.up(src); | ||
@@ -142,3 +161,5 @@ if(parent) | ||
{ | ||
src = src.clone().bottom(target); | ||
if(src.clone) | ||
src = src.clone() | ||
src = src.bottom(target); | ||
if(parent) | ||
@@ -200,2 +221,7 @@ parent[key] = src; | ||
{ | ||
if(typeof target[i] === 'undefined') | ||
{ | ||
target[i] = utils.copy(src[i]); | ||
continue; | ||
} | ||
if(src[i] === null) | ||
@@ -237,2 +263,12 @@ { | ||
} | ||
if(target._deep_sheet_) | ||
{ | ||
if(!src._deep_sheet_) | ||
{ | ||
deep.sheet(target, src); | ||
return src; | ||
} | ||
} | ||
else if(src._deep_sheet_) | ||
return target; | ||
if(target._deep_compiler_) | ||
@@ -363,3 +399,2 @@ { | ||
utils.upArray = function (src, target, schema) | ||
@@ -366,0 +401,0 @@ { |
@@ -50,2 +50,5 @@ /** | ||
function Constructor(){ | ||
for(var i in this) | ||
if(this[i] && typeof this[i] === 'object' && !this[i]._deep_shared_) | ||
this[i] = utils.copy(this[i]); | ||
for(var i = 0; i < args.length; ++i) | ||
@@ -52,0 +55,0 @@ { |
@@ -7,3 +7,3 @@ /** | ||
} | ||
define(["require", "./utils", "./compiler"], function (require, utils) | ||
define(["require", "./utils", "./compiler", "./nodes"], function (require, utils, compiler, nodes) | ||
{ | ||
@@ -17,3 +17,3 @@ var flattener = {}; | ||
// todo manage list of arguments : compile them when flattened | ||
flattener.flatten = function flatten(node) { | ||
flattener.flatten = function (node) { | ||
//console.log("deep.flatten : ", node.value); | ||
@@ -25,3 +25,3 @@ if(node._deep_flattener_) | ||
if(!node._deep_query_node_) | ||
node = utils.createRootNode(node); | ||
node = nodes.root(node); | ||
var finalise = function(){ return node.value; }; | ||
@@ -46,6 +46,4 @@ if (node.value.backgrounds); | ||
/** | ||
* will perform the backgrounds application on any backgrounds properties at any level | ||
* will perform the backgrounds application on any backgrounds properties at any depth | ||
* | ||
@@ -59,3 +57,3 @@ * | ||
*/ | ||
flattener.extendsChilds = function extendsChilds(entry, descriptor) | ||
flattener.extendsChilds = function (entry, descriptor) | ||
{ | ||
@@ -66,3 +64,3 @@ //console.log("extends childs : ", entry, descriptor); | ||
if (!entry._deep_query_node_) | ||
entry = utils.createRootNode(entry); | ||
entry = nodes.root(entry); | ||
//var toExtends = deep.Querier.firstObjectWithProperties(entry, "backgrounds|_deep_ocm_"); | ||
@@ -114,3 +112,3 @@ descriptor = utils.preorder(descriptor || entry, function(){ return this.backgrounds || this._deep_flattener_; }, {first:true, returnStack:true}); | ||
*/ | ||
flattener.extendsBackgrounds = function extendsBackgrounds(entry) | ||
flattener.extendsBackgrounds = function (entry) | ||
{ | ||
@@ -121,6 +119,17 @@ // console.log("extends backgrounds : ", entry); | ||
if (!entry._deep_query_node_) | ||
entry = utils.createRootNode(entry); | ||
entry = nodes.root(entry); | ||
var value = entry.value; | ||
if (!value.backgrounds) | ||
{ | ||
if(value.sheets) | ||
return deep.getAll(value.sheets, { entry:entry }) | ||
.done(function(success){ | ||
delete value.sheets; | ||
return deep.sheets(success, value, { entry:entry }); | ||
}) | ||
.done(function(){ | ||
return entry; | ||
}); | ||
return entry; | ||
} | ||
var extendsLoaded = function (loadeds) | ||
@@ -131,3 +140,5 @@ { | ||
var needRecursion = false; | ||
loadeds.forEach(function (s) { | ||
for(var i = 0, len = loadeds.length;i<len;++i) | ||
{ | ||
var s = loadeds[i]; | ||
if (s && s.backgrounds) { | ||
@@ -137,3 +148,3 @@ stack.push(getBackgrounds(s.backgrounds)); | ||
} | ||
}); | ||
} | ||
if (!needRecursion) | ||
@@ -144,7 +155,9 @@ return loadeds; | ||
var finalStack = []; | ||
loadeds.forEach(function (s) { | ||
for(var i = 0, len = loadeds.length;i<len;++i) | ||
{ | ||
var s = loadeds[i]; | ||
if (s && s.backgrounds) | ||
finalStack = finalStack.concat(stack.shift()); | ||
finalStack.push(s); | ||
}); | ||
} | ||
return finalStack; | ||
@@ -159,6 +172,5 @@ }); | ||
if (typeof b === 'string') { | ||
var rget = deep.get(b, { | ||
all.push(deep.get(b, { | ||
entry: entry | ||
}); | ||
all.push(rget); | ||
})); | ||
needLoad = true; | ||
@@ -176,24 +188,52 @@ } else | ||
var r = getBackgrounds(backgrounds); | ||
if (r && r.then) | ||
return r | ||
.done(function (extendeds) { | ||
var len = extendeds.length-1; | ||
for(;len>=0;len--) | ||
var finalise = function(extendeds){ | ||
// var len = extendeds.length-1; | ||
var sheets = [], bck = null; | ||
for(var i = 0, len = extendeds.length; i < len;++i) | ||
{ | ||
var val = extendeds[i]; | ||
if(val._deep_sheet_) | ||
{ | ||
entry.value = utils.bottom(extendeds[len], entry.value); | ||
if(entry.ancestor) | ||
entry.ancestor.value[entry.key] = entry.value; | ||
if(!bck) | ||
bck = deep.utils.copy(val); | ||
else if(bck._deep_sheet_) | ||
bck = utils.up(val, bck); | ||
else | ||
sheets.push(deep.sheet(val, bck)); | ||
} | ||
delete entry.value.backgrounds; | ||
return entry; | ||
}); | ||
var len = r.length-1; | ||
for(;len>=0;len--) | ||
{ | ||
entry.value = utils.bottom(r[len], entry.value); | ||
else | ||
bck = utils.up(val, bck || {}); | ||
} | ||
delete entry.value.backgrounds; | ||
var value = entry.value = utils.bottom(bck, entry.value); | ||
if(entry.ancestor) | ||
entry.ancestor.value[entry.key] = entry.value; | ||
} | ||
delete entry.value.backgrounds; | ||
return entry; | ||
entry.ancestor.value[entry.key] = value; | ||
if(sheets.length > 0) | ||
return deep.all(sheets) | ||
.done(function(success){ | ||
if(value.sheets) | ||
return deep.getAll(value.sheets, { entry:entry }) | ||
.done(function(success){ | ||
delete value.sheets; | ||
return deep.sheets(success, value, { entry:entry }); | ||
}); | ||
}) | ||
.done(function(){ | ||
return entry; | ||
}); | ||
else if(value.sheets) | ||
return deep.getAll(value.sheets, { entry:entry }) | ||
.done(function(success){ | ||
delete value.sheets; | ||
return deep.sheets(success, value, { entry:entry }); | ||
}) | ||
.done(function(){ | ||
return entry; | ||
}); | ||
return entry; | ||
}; | ||
if (r.then) | ||
return r.then(finalise); | ||
return finalise(r); | ||
}; | ||
@@ -200,0 +240,0 @@ |
130
lib/ocm.js
@@ -51,3 +51,2 @@ /** | ||
mode:"public" | ||
applySheets:true | ||
}) | ||
@@ -64,3 +63,5 @@ * return an Object Capabilities Manager | ||
var params = { | ||
nocache:options.nocache || false, | ||
groups: options.groups || options.group || null, | ||
flattened : options.flattened || false, | ||
strict: options.strict || false, | ||
@@ -70,6 +71,5 @@ layer: layer || {}, | ||
compiled: {}, | ||
multiModes: (typeof options.multiModes !== 'undfined')?options.multiModes:true, | ||
applySheets:options.applySheets || false, | ||
multiModes: (typeof options.multiModes !== 'undefined')?options.multiModes:true, | ||
afterCompilation: options.afterCompilation || null, | ||
compileModes: function(modes, layer) { | ||
compile: function(modes, layer) { | ||
var self = this, | ||
@@ -89,3 +89,3 @@ res = null, | ||
{ | ||
console.warn("OCM : no associate mode found with : ", modes, " for protocol : ", options.protocol); | ||
console.warn("OCM : no associate entry found with : ", modes, " for protocol : ", options.protocol); | ||
return false; | ||
@@ -95,6 +95,3 @@ } | ||
} | ||
if (self.applySheets && r._deep_sheet_ && res) | ||
sheetsPromises.push(sheet.sheet(r, res)); | ||
else | ||
res = utils.up(r, res || {}); | ||
res = utils.up(r, res || {}); | ||
return true; | ||
@@ -105,7 +102,5 @@ }); | ||
if (res === null) { | ||
console.warn("OCM : no associate mode found with : ", modes, " for protocol : ", options.protocol); | ||
console.warn("OCM : no associate entries found with : ", modes, " for protocol : ", options.protocol); | ||
return {}; | ||
} | ||
if (sheetsPromises.length > 0) | ||
res._deep_sheets_ = prom.all(sheetsPromises); | ||
return res; | ||
@@ -116,14 +111,21 @@ } | ||
var modes = argToArr.call(arguments); | ||
if (modes.length === 0 || params.blocked) | ||
if (modes.length === 0/* || params.blocked*/) | ||
if (params.currentModes && params.currentModes.length > 0) | ||
modes = params.currentModes; | ||
else if (params.groups) { | ||
var checkIn = deep.context.modes || ocm.Modes(); | ||
if (params.groups.forEach) { | ||
modes = []; | ||
for (var i = 0, len = params.groups.length; i < len; ++i) | ||
if (checkIn[params.groups[i]]) | ||
modes = modes.concat(checkIn[params.groups[i]]); | ||
} else | ||
modes = checkIn[params.groups]; | ||
{ | ||
var groupi = params.groups[i]; | ||
if (deep.context.modes && deep.context.modes[groupi]) | ||
modes = modes.concat(deep.context.modes[groupi]); | ||
else if (generalModes[groupi]) | ||
modes = modes.concat(generalModes[groupi]); | ||
} | ||
} | ||
else if (deep.context.modes && deep.context.modes[params.groups]) | ||
modes = modes.concat(deep.context.modes[params.groups]); | ||
else if (generalModes[params.groups]) | ||
modes = modes.concat(generalModes[params.groups]); | ||
} | ||
@@ -134,9 +136,7 @@ if (!modes || modes.length === 0) | ||
modes = [modes]; | ||
var joined = modes; | ||
if (typeof modes.join === 'function') | ||
joined = modes.join("."); | ||
var joined = modes.join("."); | ||
if (params.compiled[joined]) | ||
return params.compiled[joined]; | ||
var compiled = params.compileModes(modes, params.layer); | ||
if (!ocm.nocache) | ||
var compiled = params.compile(modes, params.layer); | ||
if (!ocm.nocache && !params.nocache) | ||
params.compiled[joined] = compiled; | ||
@@ -149,3 +149,3 @@ if (params.afterCompilation) | ||
m.name = options.protocol; | ||
deep.protocol(options.protocol, m); | ||
protoc.protocol(options.protocol, m); | ||
} | ||
@@ -155,3 +155,3 @@ m._deep_ocm_ = true; | ||
m._deep_flattener_ = true; | ||
m.multiModes = function(yes) { // allow multiple modes : i.e. : allow ["dev","public"] (default : true) | ||
m.multiModes = function(yes) { // allow multiple modes : i.e. : allow ["xxx","yyy", ...] (default : true) | ||
params.multiModes = yes; | ||
@@ -174,3 +174,3 @@ }; | ||
}; | ||
m.block = function(key) { // block current modes | ||
/*m.block = function(key) { // block current modes | ||
params.block = true; | ||
@@ -182,6 +182,9 @@ m.unblock = function(ukey) { | ||
}; | ||
m.unblock = function(key) {}; | ||
m.unblock = function(key) {};*/ | ||
m.flatten = function(entry) { // flatten inner-layer | ||
//console.log("trying flatten ocm : ", deep.context.modes, params.blocked, params.flattened) | ||
if (params.blocked) | ||
return prom.when(null); | ||
if(params.flattened) | ||
return params.flattened.promise(); | ||
if (entry) { | ||
@@ -192,13 +195,18 @@ entry.value = params.layer; | ||
} | ||
return flattener.flatten(entry || params.layer) | ||
.done(function() { | ||
if (entry) { | ||
entry.value = m; | ||
if (entry.ancestor) | ||
entry.ancestor.value[entry.key] = m; | ||
} | ||
return m; | ||
}); | ||
var def = params.flattened = prom.Deferred(); | ||
flattener.flatten(entry || params.layer) | ||
.done(function() { | ||
if (entry) { | ||
entry.value = m; | ||
if (entry.ancestor) | ||
entry.ancestor.value[entry.key] = m; | ||
} | ||
def.resolve(m, deep.context); | ||
}).fail(function(error){ | ||
def.reject(error, deep.context); | ||
}); | ||
return def.promise(); | ||
}; | ||
m.up = function() { // apply arguments (up) on inner-layer | ||
params.flattened = false; | ||
for (var i = 0; i < arguments.length; ++i) | ||
@@ -209,2 +217,3 @@ params.layer = utils.up(arguments[i], params.layer); | ||
m.bottom = function() { // apply arguments (bottom) on inner-layer | ||
params.flattened = false; | ||
for (var i = 0; i < arguments.length; ++i) | ||
@@ -216,2 +225,3 @@ params.layer = utils.bottom(arguments[i], params.layer); | ||
var o = null; | ||
options.flattened = params.flattened; | ||
if (typeof protocol === 'string') | ||
@@ -223,3 +233,3 @@ o = ocm(utils.copy(params.layer), options); | ||
if (params.currentModes) | ||
o.mode(params.currentModes); | ||
o.modes(params.currentModes); | ||
return o; | ||
@@ -241,13 +251,43 @@ }; | ||
ocm.Modes = function(arg, arg2) { // general MODES | ||
if (arguments.length === 0) | ||
if (!arg) | ||
return generalModes; | ||
if (typeof arg === 'string') { | ||
var obj = {}; | ||
obj[arg] = arg2; | ||
arg = obj; | ||
if(typeof arg === 'string') | ||
{ | ||
if(arg2) | ||
generalModes[arg] = arg2; | ||
else | ||
return generalModes[arg]; | ||
} | ||
for (var i in arg) | ||
generalModes[i] = arg[i]; | ||
else | ||
for (var i in arg) | ||
generalModes[i] = arg[i]; | ||
}; | ||
ocm.getModes = function(arg){ | ||
if(arguments.length > 0 && (typeof arg === 'string' || arg.forEach)) | ||
{ | ||
var modes = [], args = arguments; | ||
if(arg.forEach) | ||
args = arg; | ||
for (var i = 0, len = args.length; i < len; ++i) | ||
{ | ||
var argi = args[i]; | ||
if (deep.context.modes && deep.context.modes[argi]) | ||
modes = modes.concat(deep.context.modes[argi]); | ||
else if (generalModes[argi]) | ||
modes = modes.concat(generalModes[argi]); | ||
} | ||
return modes; | ||
} | ||
var base = utils.copy(generalModes); | ||
if(deep.context.modes) | ||
for(var i in deep.context.modes) | ||
base[i] = deep.context.modes[i]; | ||
if(!arg) | ||
return base; | ||
for(var i in arg) | ||
base[i] = arg[i]; | ||
return base; | ||
} | ||
// deep chain's mode management | ||
@@ -259,3 +299,3 @@ ocm.modes = function(name, modes) { // local roles (i.e. in chain's context) | ||
// deep chain's roles management | ||
ocm.roles = function() { // local modes | ||
ocm.roles = function() { // local modes (i.e. in chain's context) | ||
return deep({}).roles(argToArr.call(arguments)); | ||
@@ -262,0 +302,0 @@ }; |
@@ -26,4 +26,4 @@ /** | ||
return promise.when.immediate(arg); | ||
if (arg._deep_promise_) | ||
return arg; | ||
//if (arg._deep_promise_) | ||
// return arg; | ||
if(arg._deep_chain_ || arg._deep_deferred_) | ||
@@ -121,5 +121,2 @@ return arg.promise(); | ||
var forceHandle = utils.forceHandle = function forceChainHandle() { | ||
@@ -164,3 +161,3 @@ if (!this._initialised) | ||
if (self._queue.length > 0) { | ||
if (self._queue.length !== 0) { | ||
self._executing = true; // synch flag | ||
@@ -178,2 +175,3 @@ while (!self._running) // while not asynch | ||
} | ||
var next = self._queue.shift(); | ||
@@ -192,5 +190,7 @@ if (self._error) | ||
if (res && (res.then || res.promise)) { | ||
promise.when(res) | ||
.done(asynchChainDone) | ||
.fail(asynchChainFail); | ||
if(res._deep_promise_ || res._deep_chain_) | ||
res.done(asynchChainDone).fail(asynchChainFail); | ||
else | ||
promise.when(res).done(asynchChainDone).fail(asynchChainFail); | ||
} else { | ||
@@ -201,4 +201,5 @@ self._running = false; | ||
res = undefined; | ||
self._success = (res instanceof Error) ? null : res; | ||
self._error = (res instanceof Error) ? res : null; | ||
var isError = res instanceof Error; | ||
self._success = (isError) ? null : res; | ||
self._error = (isError) ? res : null; | ||
} | ||
@@ -245,3 +246,2 @@ } | ||
return new promise.Deferred(); | ||
this._context = deep.context; | ||
this._promises = []; | ||
@@ -269,3 +269,3 @@ this._deep_deferred_ = true; | ||
*/ | ||
resolve: function resolveDef(argument) { | ||
resolve: function (argument) { | ||
//console.log("deep.Deferred.resolve : ", argument); | ||
@@ -278,4 +278,5 @@ if (this.rejected || this.resolved || this.canceled) | ||
this.resolved = true; | ||
var self = this; | ||
this._promises.forEach(function (promise) { | ||
promise._start(argument); | ||
promise._start(argument, null); | ||
}); | ||
@@ -289,3 +290,3 @@ }, | ||
*/ | ||
reject: function rejectDef(argument) { | ||
reject: function (argument) { | ||
// console.log("DeepDeferred.reject"); | ||
@@ -296,2 +297,3 @@ if (this.rejected || this.resolved || this.canceled) | ||
this.rejected = true; | ||
var self = this; | ||
this._promises.forEach(function (promise) { | ||
@@ -306,7 +308,7 @@ promise._start(null, argument); | ||
*/ | ||
promise: function promiseDef() { | ||
var prom = new promise.Promise({ context:this._context}); | ||
promise: function () { | ||
var prom = new promise.Promise(); | ||
//console.log("deep2.Deffered.promise : ", prom, " r,r,c : ", this.rejected, this.resolved, this.canceled) | ||
if (this.resolved || this.rejected || this.canceled) | ||
return prom._start(this._success, this._error); | ||
return prom._start(this._success, this._error/*, this._context*/); | ||
this._promises.push(prom); | ||
@@ -340,4 +342,5 @@ return prom; | ||
_start: function chainStart(s, e) { | ||
_start: function chainStart(s, e, context) { | ||
this._initialised = true; | ||
//this._context = context || this._context; | ||
this._success = (s instanceof Error) ? null : s; | ||
@@ -372,60 +375,14 @@ this._error = (s instanceof Error) ? s : e; | ||
}, | ||
condition: function (cond, handler) { | ||
/* | ||
equivalent to (without loading manager if needed) | ||
.always(function(s,e){ | ||
if(cond) | ||
manager.apply(self) | ||
}) | ||
.condition(deep.mode.dev, utils.dumpError) | ||
deep(1) | ||
.condition(deep.mode.dev, function(){ | ||
this.fail(function(e){ | ||
// handle error for dev | ||
}) | ||
}) | ||
.each("swig::./items.tpl", req.accept.contain("html")) | ||
*/ | ||
var self = this; | ||
var func = function (s, e) { // WARNING : it's an always | ||
if(typeof cond === 'function') | ||
cond = cond(); | ||
if(!cond) | ||
return; | ||
var applyCondition = function(handler) | ||
{ | ||
self.oldQueue = self._queue; | ||
self._queue = []; | ||
var res = handler.call(self, s, e); | ||
if (res === self) | ||
return; | ||
return res; | ||
}; | ||
if (typeof handler === 'string') | ||
{ | ||
return promise.when(deep.get(handler)) | ||
.done(function (handler){ | ||
if(cond) | ||
return applyCondition(handler); | ||
}); | ||
} | ||
return applyCondition(handler); | ||
}; | ||
utils.addInChain.call(this, func); | ||
return this; | ||
}, | ||
done: function chainDone(callBack) { | ||
done: function (callBack, condition) { | ||
if(!callBack) | ||
return this._success; | ||
if(condition === false) | ||
return this; | ||
var self = this; | ||
var func = function chainDoneHandle(s, e) | ||
{ | ||
if(typeof condition === 'function') | ||
condition = condition(s); | ||
if(condition === false) | ||
return; | ||
//console.log("deep.done : ",s,e) | ||
@@ -443,7 +400,13 @@ self.oldQueue = self._queue; | ||
fail: function chainFail(callBack) { | ||
fail: function (callBack, condition) { | ||
if(!callBack) | ||
return this._error; | ||
if(condition === false) | ||
return this; | ||
var self = this; | ||
var func = function chainFailHandle(s, e) { | ||
if(typeof condition === 'function') | ||
condition = condition(e); | ||
if(condition === false) | ||
return; | ||
self.oldQueue = self._queue; | ||
@@ -460,6 +423,12 @@ self._queue = []; | ||
always: function chainAlways(callBack) | ||
always: function (callBack, condition) | ||
{ | ||
if(condition === false) | ||
return this; | ||
var self = this; | ||
var func = function chainAlwaysHandle(s, e) { | ||
if(typeof condition === 'function') | ||
condition = condition(s,e); | ||
if(condition === false) | ||
return; | ||
self.oldQueue = self._queue; | ||
@@ -581,12 +550,19 @@ self._queue = []; | ||
*/ | ||
delay: function chainDelay(ms) { | ||
delay: function (ms, callback) { | ||
var self = this; | ||
var func = function (s, e) { | ||
//console.log("deep.delay : ", ms) | ||
deep.counter.delayCount += ms; | ||
//console.log("deep.delay : ", ms); | ||
//var time = Date.now().valueOf(); | ||
var def = promise.Deferred(); | ||
setTimeout(function () { | ||
console.log("deep.delay.end : ", ms); | ||
//console.log("deep.delay.end : ", ms, Date.now().valueOf()-time); | ||
def.resolve(undefined); | ||
}, ms); | ||
return def.promise(); | ||
var p = def.promise(); | ||
if(callback) | ||
p.done(function(){ | ||
return callback(s); | ||
}); | ||
return p; | ||
}; | ||
@@ -819,10 +795,10 @@ func._isDone_ = true; | ||
/** | ||
* iterate over an array of objects (could be array of promises). | ||
* Execute 'done' callback for each entry. (or 'fail' if item is error) | ||
* @param {[type]} collection [description] | ||
* @param {Function} done [description] | ||
* @param {[type]} fail [description] | ||
* @return {[type]} [description] | ||
*/ | ||
/** | ||
* iterate over an array of objects (could be array of promises). | ||
* Execute 'done' callback for each entry. (or 'fail' if item is error) | ||
* @param {[type]} collection [description] | ||
* @param {Function} done [description] | ||
* @param {[type]} fail [description] | ||
* @return {[type]} [description] | ||
*/ | ||
promise.iterate = function (collection, done, fail) | ||
@@ -829,0 +805,0 @@ { |
@@ -5,253 +5,261 @@ /** | ||
if (typeof define !== 'function') { | ||
var define = require('amdefine')(module); | ||
var define = require('amdefine')(module); | ||
} | ||
define(["require", "./utils"], function(require, utils) { | ||
if (typeof requirejs !== 'undefined') | ||
requirejs.onError = function(err) { | ||
utils.dumpError(err); | ||
console.log(err.requireType); | ||
if (err.requireType === 'timeout') | ||
console.log('modules: ' + err.requireModules); | ||
}; | ||
var proto = {}; | ||
/** | ||
* get or assign protocol | ||
*/ | ||
proto.protocol = function(name, ctrl) { | ||
if (ctrl) { | ||
proto.protocols[name] = ctrl; | ||
return ctrl; | ||
} | ||
return proto.protocols[name]; | ||
}; | ||
//_______________________________________________________________________________ GET/GET ALL REQUESTS | ||
if (typeof requirejs !== 'undefined') | ||
requirejs.onError = function(err) { | ||
utils.dumpError(err); | ||
console.log(err.requireType); | ||
if (err.requireType === 'timeout') | ||
console.log('modules: ' + err.requireModules); | ||
}; | ||
var proto = {}; | ||
/** | ||
* get or assign protocol | ||
*/ | ||
proto.protocol = function(name, ctrl) { | ||
if (ctrl) { | ||
proto.protocols[name] = ctrl; | ||
return ctrl; | ||
} | ||
//console.log("*************** Protocols : ", proto.protocols[name]) | ||
if (deep.context.protocols) { | ||
//console.log("***************Context Protocols : ", deep.context.protocols[name]) | ||
var protocs = deep.context.protocols; | ||
if (protocs._deep_ocm_) | ||
protocs = protocs(); | ||
if (protocs[name]) | ||
return protocs[name]; | ||
} | ||
if (proto.protocols[name]) | ||
return proto.protocols[name]; | ||
return null; | ||
}; | ||
//_______________________________________________________________________________ GET/GET ALL REQUESTS | ||
proto.protocol.parse = function(protocol, opt) { | ||
var handler = { | ||
//protocol:protocol, | ||
method: "get", | ||
provider: null | ||
}; | ||
opt = opt || {}; | ||
if (protocol._deep_ocm_) | ||
protocol = protocol(); | ||
if (typeof protocol === 'object') | ||
handler.provider = protocol; | ||
else { | ||
var argsPresence = protocol.indexOf("("); | ||
if (argsPresence > -1) { | ||
var parenthesisRes = utils.catchParenthesis(protocol.substring(argsPresence)); | ||
protocol = protocol.substring(0, argsPresence); | ||
if (parenthesisRes) { | ||
var rangeSplit = parenthesisRes.value.split(","); | ||
handler.range = { | ||
start: parseInt(rangeSplit[0], 10), | ||
end: parseInt(rangeSplit[1], 10) | ||
}; | ||
handler.method = "range"; | ||
} | ||
} | ||
if (deep.context.protocols) { | ||
var protocs = deep.context.protocols; | ||
if (protocs._deep_ocm_) | ||
protocs = protocs(); | ||
if (protocs[protocol]) | ||
handler.provider = protocs[protocol]; | ||
} | ||
if (!handler.provider) | ||
if(proto.protocols[protocol]) | ||
handler.provider = proto.protocols[protocol]; | ||
else { | ||
var splitted = protocol.split("."); | ||
handler.provider = proto.protocols[splitted[0]]; | ||
handler.method = splitted[1]; | ||
} | ||
} | ||
if (!handler.provider) | ||
return deep.errors.Protocol("no provider found with : " + protocol); | ||
if (handler.provider._deep_ocm_ && !opt.ignoreOCM) | ||
handler.provider = handler.provider(); | ||
if (typeof handler.provider === 'function' && handler.method == 'get') | ||
handler.provider = { | ||
_deep_store_: true, | ||
get: handler.provider | ||
}; | ||
else if (!handler.provider[handler.method]) | ||
return deep.errors.MethodNotAllowed("no method found in provider with : " + protocol); | ||
if (handler.provider.init && !opt.ignoreInit) | ||
return deep.when(handler.provider.init()) | ||
.done(function() { | ||
return handler; | ||
}); | ||
return handler; | ||
}; | ||
proto.protocol.parse = function(protocol, opt) { | ||
var handler = { | ||
//protocol:protocol, | ||
method: "get", | ||
provider: null | ||
}; | ||
opt = opt || {}; | ||
if (protocol._deep_ocm_) | ||
protocol = protocol(); | ||
if (typeof protocol === 'object') | ||
handler.provider = protocol; | ||
else { | ||
var protocs = deep.context.protocols || {}; | ||
if (protocs._deep_ocm_) | ||
protocs = protocs(); | ||
var argsPresence = protocol.indexOf("("); | ||
if (argsPresence > -1) { | ||
var parenthesisRes = utils.catchParenthesis(protocol.substring(argsPresence)); | ||
protocol = protocol.substring(0, argsPresence); | ||
if (parenthesisRes) { | ||
var rangeSplit = parenthesisRes.value.split(","); | ||
handler.range = { | ||
start: parseInt(rangeSplit[0], 10), | ||
end: parseInt(rangeSplit[1], 10) | ||
}; | ||
handler.method = "range"; | ||
} | ||
} | ||
handler.provider = protocs[protocol] || proto.protocols[protocol]; | ||
if (!handler.provider) | ||
{ | ||
var splitted = protocol.split("."); | ||
if(splitted.length == 2) | ||
{ | ||
protocol = splitted[0]; | ||
handler.provider = protocs[protocol] || proto.protocols[protocol]; | ||
handler.method = splitted[1]; | ||
} | ||
} | ||
} | ||
if (!handler.provider) | ||
return deep.errors.Protocol("no provider found with : " + protocol); | ||
if (handler.provider._deep_ocm_ && !opt.ignoreOCM) | ||
handler.provider = handler.provider(); | ||
if (typeof handler.provider === 'function' && handler.method == 'get') | ||
handler.provider = { | ||
_deep_store_: true, | ||
get: handler.provider | ||
}; | ||
else if (!handler.provider[handler.method]) | ||
return deep.errors.MethodNotAllowed("no method found in provider with : " + protocol); | ||
return handler; | ||
}; | ||
/** | ||
* parse 'retrievable' string request (e.g. "json::test.json") | ||
* @for deep | ||
* @method parseRequest | ||
* @static | ||
* @param {String} request | ||
* @return {Object} infos an object containing parsing result | ||
*/ | ||
utils.parseRequest = function(request, options) { | ||
if (!request) | ||
throw deep.errors.Error(500, "request parsing error : request undefined"); | ||
if (request[0] == '<') | ||
return { | ||
_deep_request_: true, | ||
request: request, | ||
uri: request | ||
}; | ||
var protoIndex = request.substring(0, 50).indexOf("::"); | ||
var protoc = null; | ||
var uri = request; | ||
var handler = null; | ||
if (protoIndex > -1) { | ||
protoc = request.substring(0, protoIndex); | ||
uri = request.substring(protoIndex + 2); | ||
} else | ||
return { | ||
_deep_request_: true, | ||
request: request, | ||
uri: uri | ||
}; | ||
if (request[0] == '#' || protoc == "this") | ||
handler = proto.protocol.parse(proto.protocols.dq); | ||
else | ||
handler = proto.protocol.parse(protoc); | ||
return { | ||
_deep_request_: true, | ||
request: request, | ||
handler: handler, | ||
protocol: protoc, | ||
uri: uri | ||
}; | ||
}; | ||
/** | ||
* parse 'retrievable' string request (e.g. "json::test.json") | ||
* @for deep | ||
* @method parseRequest | ||
* @static | ||
* @param {String} request | ||
* @return {Object} infos an object containing parsing result | ||
*/ | ||
utils.parseRequest = function(request, options) { | ||
if (!request) | ||
throw deep.errors.Error(500, "request parsing error : request undefined"); | ||
if (request[0] == '<') | ||
return { | ||
_deep_request_: true, | ||
request: request, | ||
uri: request | ||
}; | ||
var protoIndex = request.substring(0, 50).indexOf("::"); | ||
var protoc = null; | ||
var uri = request; | ||
var handler = null; | ||
if (protoIndex > -1) { | ||
protoc = request.substring(0, protoIndex); | ||
uri = request.substring(protoIndex + 2); | ||
} else | ||
return { | ||
_deep_request_: true, | ||
request: request, | ||
uri: uri | ||
}; | ||
if (request[0] == '#' || protoc == "this") | ||
protoc = "dq"; | ||
return { | ||
_deep_request_: true, | ||
request: request, | ||
handler: proto.protocol.parse(protoc), | ||
protocol: protoc, | ||
uri: uri | ||
}; | ||
}; | ||
/** | ||
* retrieve an array of retrievable strings (e.g. "json::test.json") | ||
* if request is not a string : will just return request | ||
* @for deep | ||
* @static | ||
* @method getAll | ||
* @param {String} requests a array of strings to retrieve | ||
* @param {Object} options (optional) | ||
* @return {deep.Chain} a handler that hold result | ||
*/ | ||
proto.getAll = function(requests, options) { | ||
var alls = []; | ||
requests.forEach(function(request) { | ||
//console.log("get all : ", request, options); | ||
alls.push(proto.get(request, options)); | ||
}); | ||
return deep.all(alls); | ||
}; | ||
/** | ||
* retrieve an array of retrievable strings (e.g. "json::test.json") | ||
* if request is not a string : will just return request | ||
* @for deep | ||
* @static | ||
* @method getAll | ||
* @param {String} requests a array of strings to retrieve | ||
* @param {Object} options (optional) | ||
* @return {deep.Chain} a handler that hold result | ||
*/ | ||
proto.getAll = function(requests, options) { | ||
var alls = []; | ||
if(!requests.forEach) | ||
requests = [requests]; | ||
requests.forEach(function(request) { | ||
//console.log("get all : ", request, options); | ||
alls.push(proto.get(request, options)); | ||
}); | ||
return deep.all(alls); | ||
}; | ||
/** | ||
* retrieve request (if string in retrievable format) (e.g. "json::test.json") | ||
* perform an http get | ||
* if request is not a string OR string doesn't start with protocols 'xxx::' : will just return request | ||
* @for deep | ||
* @static | ||
* @method get | ||
* @param {String} request a string to retrieve | ||
* @param {Object} options (optional) | ||
* @return {deep.Chain} a handler that hold result | ||
*/ | ||
proto.get = function(request, options) { | ||
if (!request || (typeof request !== "string" && !request._deep_request_)) | ||
return deep.when(request); | ||
options = options || {}; | ||
var infos = request; | ||
if (typeof infos === 'string') | ||
infos = utils.parseRequest(request, options); | ||
var res = null; | ||
if (!infos.handler && !infos.protocol) | ||
return deep.when(request); | ||
return deep.when(infos.handler) | ||
.done(function(handler) { | ||
var res = null; | ||
if (handler.range) | ||
res = handler.provider.range(handler.range.start, handler.range.end, infos.uri, options); | ||
else | ||
res = handler.provider[handler.method](infos.uri, options); | ||
if (options.wrap) { | ||
return deep.when(res) | ||
.done(function(res) { | ||
if (options.wrap.result) { | ||
if (typeof options.wrap.result.push === 'function') | ||
options.wrap.result.push(res); | ||
else | ||
options.wrap.result = [].concat(options.wrap.result); | ||
} else | ||
options.wrap.result = res; | ||
return options.wrap; | ||
}); | ||
} else | ||
return res; | ||
}); | ||
}; | ||
// ___________________________________________________________________________ CORE PROTOCOLS | ||
proto.protocols = { | ||
/** | ||
* deep-query protocol : | ||
* for code-sheet usage. | ||
* | ||
* options must contain the entry from where start query | ||
* @param {[type]} request [description] | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
dq: { | ||
get: function dqGet(request, options) { | ||
var entry = options.entry; | ||
if (!entry) | ||
return undefined; | ||
var root = entry.root || entry; | ||
var infos = request; | ||
if (typeof infos === 'string') | ||
infos = utils.parseRequest(infos); | ||
if (infos.uri[0] == '#') | ||
infos.uri = infos.uri.substring(1); | ||
var res = null; | ||
options = options || {}; | ||
options.keepCache = false; | ||
if (infos.uri.substring(0, 3) == "../") { | ||
infos.uri = ((entry.path != "/") ? (entry.path + "/") : "") + infos.uri; | ||
res = deep.query(root, infos.uri, options); | ||
} else if (infos.uri[0] == '/') | ||
res = deep.query(root, infos.uri, options); | ||
else | ||
res = deep.query(entry, infos.uri, options); | ||
return res; | ||
} | ||
}, | ||
js: function(path, options) { | ||
if (typeof path === 'object') | ||
path = path.uri; | ||
var def = deep.Deferred(); | ||
try { | ||
require([path], function(obj) { | ||
def.resolve(obj); | ||
}, function(err) { | ||
def.reject(err); | ||
}); | ||
} catch (e) { | ||
def.reject(e); | ||
} | ||
return def.promise(); | ||
}, | ||
instance: function(path, options) { | ||
return proto.protocols.js(path, options) | ||
.done(function(Cl) { | ||
if (typeof Cl === 'function') | ||
return new Cl(); | ||
return utils.copy(Cl); | ||
}); | ||
} | ||
}; | ||
return proto; | ||
/** | ||
* retrieve request (if string in retrievable format) (e.g. "json::test.json") | ||
* perform an http get | ||
* if request is not a string OR string doesn't start with protocols 'xxx::' : will just return request | ||
* @for deep | ||
* @static | ||
* @method get | ||
* @param {String} request a string to retrieve | ||
* @param {Object} options (optional) | ||
* @return {deep.Chain} a handler that hold result | ||
*/ | ||
proto.get = function(request, options) { | ||
if (!request || (typeof request !== "string" && !request._deep_request_)) | ||
return deep.when(request); | ||
options = options || {}; | ||
var infos = request; | ||
if (typeof infos === 'string') | ||
infos = utils.parseRequest(request, options); | ||
var res = null; | ||
if (!infos.handler && !infos.protocol) | ||
return deep.when(request); | ||
return deep.when(infos.handler) | ||
.done(function(handler){ | ||
return deep.when(deep.store.prepare(handler.provider)) | ||
.done(function(provider) { | ||
var res = null; | ||
if (handler.range) | ||
res = provider.range(handler.range.start, handler.range.end, infos.uri, options); | ||
else | ||
res = provider[handler.method](infos.uri, options); | ||
if (options.wrap) { | ||
return deep.when(res) | ||
.done(function(res) { | ||
if (options.wrap.result) { | ||
if (typeof options.wrap.result.push === 'function') | ||
options.wrap.result.push(res); | ||
else | ||
options.wrap.result = [].concat(options.wrap.result); | ||
} else | ||
options.wrap.result = res; | ||
return options.wrap; | ||
}); | ||
} else | ||
return res; | ||
}); | ||
}); | ||
}; | ||
// ___________________________________________________________________________ CORE PROTOCOLS | ||
proto.protocols = { | ||
/** | ||
* deep-query protocol : | ||
* for code-sheet usage. | ||
* | ||
* options must contain the entry from where start query | ||
* @param {[type]} request [description] | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
dq: { | ||
get: function dqGet(request, options) { | ||
var entry = options.entry; | ||
if (!entry) | ||
return undefined; | ||
var root = entry.root || entry; | ||
var infos = request; | ||
if (typeof infos === 'string') | ||
infos = utils.parseRequest(infos); | ||
if (infos.uri[0] == '#') | ||
infos.uri = infos.uri.substring(1); | ||
var res = null; | ||
options = options || {}; | ||
options.keepCache = false; | ||
if (infos.uri.substring(0, 3) == "../") { | ||
infos.uri = ((entry.path != "/") ? (entry.path + "/") : "") + infos.uri; | ||
res = deep.query(root, infos.uri, options); | ||
} else if (infos.uri[0] == '/') | ||
res = deep.query(root, infos.uri, options); | ||
else | ||
res = deep.query(entry, infos.uri, options); | ||
return res; | ||
} | ||
}, | ||
js: function(path, options) { | ||
if (typeof path === 'object') | ||
path = path.uri; | ||
var def = deep.Deferred(); | ||
try { | ||
require([path], function(obj) { | ||
def.resolve(obj); | ||
}, function(err) { | ||
def.reject(err); | ||
}); | ||
} catch (e) { | ||
def.reject(e); | ||
} | ||
return def.promise(); | ||
}, | ||
instance: function(path, options) { | ||
return proto.protocols.js(path, options) | ||
.done(function(Cl) { | ||
if (typeof Cl === 'function') | ||
return new Cl(); | ||
return utils.copy(Cl); | ||
}); | ||
} | ||
}; | ||
return proto; | ||
}); |
@@ -23,3 +23,3 @@ /** | ||
} | ||
define(["require", "./utils"], function defineDeepQuery(require, utils) | ||
define(["require", "./utils", "./nodes"], function defineDeepQuery(require, utils, nodes) | ||
{ | ||
@@ -311,36 +311,3 @@ /* | ||
}; | ||
/** | ||
* create a DeepQuery entry that hold info of objet node (path, value, ancestor, etc) | ||
* @method createEntry | ||
* @param {[type]} key | ||
* @param {[type]} ancestor | ||
* @return {[type]} | ||
*/ | ||
DQ.prototype.createEntry = function dqCeateEntry(key, ancestor) | ||
{ | ||
var path = ancestor.path; | ||
if(path[path.length-1] == '/') | ||
path += key; | ||
else | ||
path += "/"+key; | ||
//if(this.cache[path]) | ||
// return this.cache[path]; | ||
var schema = null; | ||
//console.log("ancestor.schema : ", ancestor.schema) | ||
if(ancestor.schema) | ||
schema = retrieveFullSchemaByPath(ancestor.schema, key, "/"); | ||
//console.log("deep.utils.createNode : "+path+" : schema : ",schema) | ||
var r = this.cache[path] = { | ||
_deep_query_node_:true, | ||
root:ancestor.root, | ||
value:ancestor.value[key], | ||
path:path, | ||
key:key, | ||
ancestor:ancestor, | ||
schema:schema, | ||
depth:ancestor.depth+1 | ||
}; | ||
return r; | ||
}; | ||
DQ.prototype.returnProperty = function dqreturnProperty(entry, key){ | ||
@@ -352,3 +319,3 @@ if(typeof entry.value === 'string' && key !== 'length') | ||
if(obj && typeof obj[key] !== 'undefined') | ||
entry = this.createEntry(key, entry); | ||
entry = deep.nodes.create(key, entry); | ||
else | ||
@@ -372,3 +339,3 @@ entry = null; | ||
continue; | ||
var ent = this.createEntry(i, entry); | ||
var ent = deep.nodes.create(i, entry); | ||
if(typeof ent !== 'undefined') | ||
@@ -390,3 +357,3 @@ childs.push(ent); | ||
continue; | ||
var child = self.createEntry(i, entry); | ||
var child = deep.nodes.create(i, entry); | ||
if(typeof child !== "undefined") | ||
@@ -648,3 +615,3 @@ childs.push(child); | ||
{ | ||
this.root = this.cache["/"] = deep.utils.createRootNode(obj, options.schema); | ||
this.root = this.cache["/"] = deep.nodes.root(obj, options.schema); | ||
//this.root.root = this.root; | ||
@@ -651,0 +618,0 @@ items = [this.cache["/"]]; |
2309
lib/schema.js
@@ -11,1015 +11,991 @@ /** | ||
} | ||
define(["require", "deepjs/deep", "deepjs/lib/utils"],function(require, deep) { | ||
define(["require", "deepjs/deep", "deepjs/lib/utils"], function(require, deep) { | ||
function findPatternProperties(name, patterns) { | ||
var res = []; | ||
for (var i in patterns) { | ||
if (!patterns.hasOwnProperty(i)) | ||
continue; | ||
if (new RegExp(i).test(name)) | ||
res.push(patterns[i]); | ||
function findPatternProperties(name, patterns) { | ||
var res = []; | ||
for (var i in patterns) { | ||
if (!patterns.hasOwnProperty(i)) | ||
continue; | ||
if (new RegExp(i).test(name)) | ||
res.push(patterns[i]); | ||
} | ||
return res; | ||
} | ||
/** | ||
* @class Validator | ||
* @namespace deep | ||
* @constructor | ||
*/ | ||
var Validator = function() {}; | ||
var getType = Validator.prototype.getType = function(value) { | ||
for (var i in this.lexic.type) | ||
if (this.lexic.type.hasOwnProperty(i) && i != "any" && i != "object" && i != "schema" && this.lexic.type[i].test.apply(this, [value])) | ||
return i; | ||
if (this.lexic.type.object.test.apply(this, [value])) | ||
return 'object'; | ||
return null; | ||
}; | ||
Validator.prototype.createDefault = function(schema) { | ||
//console.log("schema createDefault : ", schema); | ||
if (schema["default"]) | ||
return deep.utils.copy(schema["default"]); | ||
if (schema.type == 'object' && !schema.properties) | ||
return {}; | ||
var res = null; | ||
if (schema.properties) { | ||
res = {}; | ||
for (var j in schema.properties) { | ||
var sch = schema.properties[j]; | ||
res[j] = this.createDefault(sch); | ||
} | ||
return res; | ||
} | ||
/** | ||
* @class Validator | ||
* @namespace deep | ||
* @constructor | ||
*/ | ||
var Validator = function() {}; | ||
if (schema.type == 'array' && !schema.items) | ||
return []; | ||
if (schema.items) { | ||
res = []; | ||
res.push(this.createDefault(schema.items)); | ||
return res; | ||
} | ||
var type = schema.type; | ||
if (type.forEach) | ||
type = type[0]; | ||
switch (type) { | ||
case "string": | ||
return ""; | ||
case "number": | ||
return 0; | ||
case "integer": | ||
return 0; | ||
case "float": | ||
return 0.0; | ||
case "boolean": | ||
return true; | ||
case "date": | ||
return new Date(); | ||
case "null": | ||
return null; | ||
default: | ||
return "unrecognised type"; | ||
} | ||
}; | ||
var getType = Validator.prototype.getType = function(value) { | ||
for (var i in this.lexic.type) | ||
if (this.lexic.type.hasOwnProperty(i) && i != "any" && i != "object" && i != "schema" && this.lexic.type[i].test.apply(this, [value])) | ||
return i; | ||
if (this.lexic.type.object.test.apply(this, [value])) | ||
return 'object'; | ||
return null; | ||
}; | ||
Validator.prototype.convertStringTo = function(value, type) { | ||
switch (type) { | ||
case "number": | ||
if (!isNaN(value)) | ||
value = parseFloat(value); | ||
break; | ||
case "float": | ||
if (!isNaN(value)) | ||
value = parseFloat(value); | ||
break; | ||
case "integer": | ||
if (!isNaN(value)) | ||
value = parseInt(value, 10); | ||
break; | ||
case "boolean": | ||
value = (value == "true" || value == "1") ? true : false; | ||
break; | ||
} | ||
return value; | ||
}; | ||
Validator.prototype.createDefault = function(schema) { | ||
//console.log("schema createDefault : ", schema); | ||
if (schema["default"]) | ||
return deep.utils.copy(schema["default"]); | ||
if (schema.type == 'object' && !schema.properties) | ||
return {}; | ||
var res = null; | ||
if (schema.properties) { | ||
res = {}; | ||
for (var j in schema.properties) { | ||
var sch = schema.properties[j]; | ||
res[j] = this.createDefault(sch); | ||
} | ||
return res; | ||
} | ||
if (schema.type == 'array' && !schema.items) | ||
return []; | ||
if (schema.items) { | ||
res = []; | ||
res.push(this.createDefault(schema.items)); | ||
return res; | ||
} | ||
var type = schema.type; | ||
if (type.forEach) | ||
type = type[0]; | ||
switch (type) { | ||
case "string": | ||
return ""; | ||
case "number": | ||
return 0; | ||
case "integer": | ||
return 0; | ||
case "float": | ||
return 0.0; | ||
case "boolean": | ||
return true; | ||
case "date": | ||
return new Date(); | ||
case "null": | ||
return null; | ||
default: | ||
return "unrecognised type"; | ||
} | ||
}; | ||
Validator.prototype.castAndCheck = function(value, schema, valuePath) { | ||
//console.log("cast and check on : ", value, schema, valuePath); | ||
if (!schema.type) | ||
return value; | ||
Validator.prototype.convertStringTo = function(value, type) { | ||
var types = schema.type; | ||
if (!types.forEach) | ||
types = [types]; | ||
var error = null; | ||
var fin = null; | ||
var ok = false; | ||
for (var i = 0; i < types.length; ++i) { | ||
var type = types[i]; | ||
switch (type) { | ||
case "number": | ||
if(!isNaN(value)) | ||
value = parseFloat(value); | ||
if (isNaN(value)) { | ||
ok = false; | ||
break; | ||
} | ||
fin = parseFloat(value); | ||
if (!isNaN(fin) && fin !== Infinity) | ||
ok = true; | ||
break; | ||
case "float": | ||
if(!isNaN(value)) | ||
value = parseFloat(value); | ||
if (isNaN(value)) { | ||
ok = false; | ||
break; | ||
} | ||
fin = parseFloat(value); | ||
if (!isNaN(fin) && fin !== Infinity) | ||
ok = true; | ||
break; | ||
case "integer": | ||
if(!isNaN(value)) | ||
value = parseInt(value,10); | ||
if (isNaN(value)) { | ||
ok = false; | ||
break; | ||
} | ||
fin = parseInt(value, 10); | ||
if (!isNaN(fin) && fin !== Infinity) | ||
ok = true; | ||
break; | ||
case "boolean": | ||
value = (value == "true" || value == "1") ? true : false; | ||
if (value == "true" || value == "1") { | ||
fin = true; | ||
ok = true; | ||
} else if (value == "false" || value === "0") { | ||
fin = false; | ||
ok = true; | ||
} | ||
break; | ||
} | ||
return value; | ||
}; | ||
Validator.prototype.castAndCheck = function(value, schema, valuePath) { | ||
//console.log("cast and check on : ", value, schema, valuePath); | ||
if (!schema.type) | ||
return value; | ||
var types = schema.type; | ||
if (!types.forEach) | ||
types = [types]; | ||
var error = null; | ||
var fin = null; | ||
var ok = false; | ||
for (var i = 0; i < types.length; ++i) { | ||
var type = types[i]; | ||
switch (type) { | ||
case "number": | ||
if (isNaN(value)) | ||
{ | ||
ok = false; | ||
break; | ||
} | ||
fin = parseFloat(value); | ||
if (!isNaN(fin) && fin !== Infinity) | ||
ok = true; | ||
break; | ||
case "float": | ||
if (isNaN(value)) | ||
{ | ||
ok = false; | ||
break; | ||
} | ||
fin = parseFloat(value); | ||
if (!isNaN(fin) && fin !== Infinity) | ||
ok = true; | ||
break; | ||
case "integer": | ||
if (isNaN(value)) | ||
{ | ||
ok = false; | ||
break; | ||
} | ||
fin = parseInt(value, 10); | ||
if (!isNaN(fin) && fin !== Infinity) | ||
ok = true; | ||
break; | ||
case "boolean": | ||
if (value == "true" || value == "1") { | ||
fin = true; | ||
ok = true; | ||
} else if (value == "false" || value === "0") { | ||
fin = false; | ||
ok = true; | ||
} | ||
break; | ||
case "string": | ||
if (typeof value === 'string') { | ||
fin = value; | ||
ok = true; | ||
} | ||
break; | ||
} | ||
if (ok) | ||
case "string": | ||
if (typeof value === 'string') { | ||
fin = value; | ||
ok = true; | ||
} | ||
break; | ||
} | ||
if (!ok) { | ||
var rep = { | ||
value: value, | ||
schema: schema, | ||
errorsMap: {} | ||
}; | ||
rep.errorsMap[valuePath] = { | ||
errors: [{ | ||
detail: "casting failed. need : " + types.join(", ") + "." | ||
}] | ||
}; | ||
return deep.errors.PreconditionFail("casting failed", rep); | ||
} | ||
var report = deep.validate(fin, schema, { | ||
basePath: valuePath | ||
}); | ||
if (!report.valid) | ||
return deep.errors.PreconditionFail("cast and check failed : ", report); | ||
return fin; | ||
}; | ||
Validator.prototype.errors = null; | ||
Validator.prototype.errorsMap = null; | ||
Validator.prototype.doTest = function doTest(entry, value, type, schema, valuePath, schemaPath, schemaProperty) { | ||
//console.log("do test "+entry.test.apply(this, [value, type, schema, valuePath, schemaPath, schemaProperty])) | ||
if (entry.test && !entry.test.apply(this, [value, type, schema, valuePath, schemaPath, schemaProperty])) | ||
this.createError(entry.error, value, type, schema, valuePath, schemaPath, schemaProperty); | ||
}; | ||
Validator.prototype.createError = function createError(message, value, type, schema, valuePath, schemaPath, schemaProperty) { | ||
if (valuePath[0] == ".") | ||
valuePath = valuePath.substring(1); | ||
if (!schemaProperty) | ||
schemaProperty = ""; | ||
var detail = deep.utils.interpret(message, { | ||
if (ok) | ||
break; | ||
} | ||
if (!ok) { | ||
var rep = { | ||
value: value, | ||
type: type, | ||
path: valuePath, | ||
schema: schema, | ||
schemaPath: schemaPath, | ||
__this: this | ||
}); | ||
var error = { | ||
detail: detail, | ||
value: value, | ||
type: type, | ||
schema: schema, | ||
path: valuePath, | ||
schemaPath: schemaPath, | ||
schemaProperty: schemaProperty | ||
errorsMap: {} | ||
}; | ||
if (!this.errorsMap) | ||
this.errorsMap = {}; | ||
//console.log("deep-schema produce error : ", valuePath) | ||
if (!this.errorsMap[valuePath]) | ||
this.errorsMap[valuePath] = {}; | ||
if (!this.errorsMap[valuePath].errors) | ||
this.errorsMap[valuePath].errors = []; | ||
this.errorsMap[valuePath].errors.push(error); | ||
if (console.flags && console.flags.validationError) console.log("validator", "create error : ", JSON.stringify(error)); | ||
this.errors.push(error); | ||
return error; | ||
rep.errorsMap[valuePath] = { | ||
errors: [{ | ||
detail: "casting failed. need : " + types.join(", ") + "." | ||
}] | ||
}; | ||
return deep.errors.PreconditionFail("casting failed", rep); | ||
} | ||
var report = deep.validate(fin, schema, { | ||
basePath: valuePath | ||
}); | ||
if (!report.valid) | ||
return deep.errors.PreconditionFail("cast and check failed : ", report); | ||
return fin; | ||
}; | ||
Validator.prototype.errors = null; | ||
Validator.prototype.errorsMap = null; | ||
Validator.prototype.doTest = function doTest(entry, value, type, schema, valuePath, schemaPath, schemaProperty) { | ||
//console.log("do test "+entry.test.apply(this, [value, type, schema, valuePath, schemaPath, schemaProperty])) | ||
if (entry.test && !entry.test.apply(this, [value, type, schema, valuePath, schemaPath, schemaProperty])) | ||
this.createError(entry.error, value, type, schema, valuePath, schemaPath, schemaProperty); | ||
}; | ||
Validator.prototype.createError = function createError(message, value, type, schema, valuePath, schemaPath, schemaProperty) { | ||
if (valuePath[0] == ".") | ||
valuePath = valuePath.substring(1); | ||
if (!schemaProperty) | ||
schemaProperty = ""; | ||
var detail = deep.utils.interpret(message, { | ||
value: value, | ||
type: type, | ||
path: valuePath, | ||
schema: schema, | ||
schemaPath: schemaPath, | ||
__this: this | ||
}); | ||
var error = { | ||
detail: detail, | ||
value: value, | ||
type: type, | ||
schema: schema, | ||
path: valuePath, | ||
schemaPath: schemaPath, | ||
schemaProperty: schemaProperty | ||
}; | ||
Validator.prototype.checkRef = function checkRef(value, schema, valuePath, schemaPath, nextValidation) { | ||
if (valuePath[0] == ".") | ||
valuePath = valuePath.substring(1); | ||
if (nextValidation === undefined) | ||
nextValidation = this.validateProperty; | ||
var othis = this; | ||
return nextValidation.apply(othis, [value, schema, valuePath, schemaPath]); | ||
}; | ||
Validator.prototype.validateSchema = function validateSchema(schema, options) { | ||
if (!this.errorsMap) | ||
this.errorsMap = {}; | ||
this.errors = []; | ||
var othis = this; | ||
this.options = options | {}; | ||
if (!this.options.basePath) | ||
this.options.basePath = ""; | ||
if (!this.options.baseSchemaPath) | ||
this.options.baseSchemaPath = ""; | ||
this.validateSchemaProperties(null, schema, null, this.options.basePath); | ||
var report = { | ||
errorsMap: othis.errorsMap, | ||
schema: schema, | ||
value: null, | ||
date: Date.now(), | ||
valid: (othis.errors.length === 0) | ||
}; | ||
return report; | ||
//console.log("deep-schema produce error : ", valuePath) | ||
if (!this.errorsMap[valuePath]) | ||
this.errorsMap[valuePath] = {}; | ||
if (!this.errorsMap[valuePath].errors) | ||
this.errorsMap[valuePath].errors = []; | ||
this.errorsMap[valuePath].errors.push(error); | ||
if (console.flags && console.flags.validationError) console.log("validator", "create error : ", JSON.stringify(error)); | ||
this.errors.push(error); | ||
return error; | ||
}; | ||
Validator.prototype.checkRef = function checkRef(value, schema, valuePath, schemaPath, nextValidation) { | ||
if (valuePath[0] == ".") | ||
valuePath = valuePath.substring(1); | ||
if (nextValidation === undefined) | ||
nextValidation = this.validateProperty; | ||
var othis = this; | ||
return nextValidation.apply(othis, [value, schema, valuePath, schemaPath]); | ||
}; | ||
Validator.prototype.validateSchema = function validateSchema(schema, options) { | ||
this.errorsMap = {}; | ||
this.errors = []; | ||
var othis = this; | ||
this.options = options | {}; | ||
if (!this.options.basePath) | ||
this.options.basePath = ""; | ||
if (!this.options.baseSchemaPath) | ||
this.options.baseSchemaPath = ""; | ||
this.validateSchemaProperties(null, schema, null, this.options.basePath); | ||
var report = { | ||
errorsMap: othis.errorsMap, | ||
schema: schema, | ||
value: null, | ||
date: Date.now(), | ||
valid: (othis.errors.length === 0) | ||
}; | ||
return report; | ||
}; | ||
Validator.prototype.validate = function validate(value, schema, options) { | ||
// console.log("validate ___________________") | ||
if (options && options.partial) { | ||
options.fieldsToCheck = deep.query(value, ".//*").paths(); | ||
return this.partialValidation(value, schema, options); | ||
Validator.prototype.validate = function validate(value, schema, options) { | ||
// console.log("validate ___________________") | ||
if (options && options.partial) { | ||
options.fieldsToCheck = deep.query(value, ".//*").paths(); | ||
return this.partialValidation(value, schema, options); | ||
} | ||
this.rootValue = value; | ||
this.errors = []; | ||
this.errorsMap = {}; | ||
var othis = this; | ||
this.options = options || {}; | ||
if (!this.options.basePath) | ||
this.options.basePath = ""; | ||
if (!this.options.baseSchemaPath) | ||
this.options.baseSchemaPath = ""; | ||
// console.log("launch validation") | ||
this.validateProperty(value, schema, this.options.basePath, this.options.baseSchemaPath); | ||
var report = { | ||
errorsMap: othis.errorsMap, | ||
schema: schema, | ||
value: value, | ||
date: Date.now(), | ||
valid: (othis.errors.length === 0), | ||
toString: function() { | ||
console.log("\n\nValidationReport : \n"); | ||
console.log("valid : \n", this.valid); | ||
console.log("schema : \n", JSON.stringify(schema)); | ||
console.log("value : \n", JSON.stringify(this.value)); | ||
console.log("errors : \n"); | ||
for (var i in this.errorsMap) | ||
console.log(i, this.errorsMap[i].errors); | ||
} | ||
this.rootValue = value; | ||
this.errors = []; | ||
this.errorsMap = {}; | ||
var othis = this; | ||
this.options = options || {}; | ||
if (!this.options.basePath) | ||
this.options.basePath = ""; | ||
if (!this.options.baseSchemaPath) | ||
this.options.baseSchemaPath = ""; | ||
// console.log("launch validation") | ||
this.validateProperty(value, schema, this.options.basePath, this.options.baseSchemaPath); | ||
var report = { | ||
errorsMap: othis.errorsMap, | ||
schema: schema, | ||
value: value, | ||
date: Date.now(), | ||
valid: (othis.errors.length === 0), | ||
toString: function() { | ||
console.log("\n\nValidationReport : \n"); | ||
console.log("valid : \n", this.valid); | ||
console.log("schema : \n", JSON.stringify(schema)); | ||
console.log("value : \n", JSON.stringify(this.value)); | ||
console.log("errors : \n"); | ||
for (var i in this.errorsMap) | ||
console.log(i, this.errorsMap[i].errors); | ||
} | ||
}; | ||
return report; | ||
}; | ||
return report; | ||
}; | ||
Validator.prototype.partialValidation = function partialValidation(object, schema, options) { | ||
this.errors = []; | ||
this.errorsMap = {}; | ||
this.options = options || {}; | ||
Validator.prototype.partialValidation = function partialValidation(object, schema, options) { | ||
this.errors = []; | ||
this.errorsMap = {}; | ||
this.options = options || {}; | ||
var fieldsToCheck = options.fieldsToCheck || []; | ||
var parts = []; | ||
var promises = []; | ||
var schemaPaths = []; | ||
var deferred = deep.Deferred(); | ||
var othis = this; | ||
//console.log("Validator", "partialValidation : fieldsToCheck = " + fieldsToCheck); | ||
var fieldsToCheck = options.fieldsToCheck || []; | ||
var parts = []; | ||
var promises = []; | ||
var schemaPaths = []; | ||
var deferred = deep.Deferred(); | ||
var othis = this; | ||
//console.log("Validator", "partialValidation : fieldsToCheck = " + fieldsToCheck); | ||
fieldsToCheck.forEach(function(required) { | ||
//console.log("Validator", "partialValidation : forEach : field = " + required); | ||
fieldsToCheck.forEach(function(required) { | ||
//console.log("Validator", "partialValidation : forEach : field = " + required); | ||
var schem = deep.utils.retrieveFullSchemaByPath(schema, required); | ||
if (!schem) | ||
return; | ||
//console.log("partial schema : ", schem) | ||
var obj = deep.utils.fromPath(object, required); | ||
if (obj !== "" && !obj && schem.required) { | ||
//console.log("partial : missing prop : (required)"); | ||
othis.createError(othis.lexic[othis.lexic.__requiredEquivalent].error, obj, "undefined", schem, required); | ||
return; | ||
} | ||
promises.push(othis.validate(obj, schem, { | ||
basePath: required, | ||
baseSchemaPath: null | ||
})); | ||
}); | ||
var schem = deep.utils.retrieveFullSchemaByPath(schema, required); | ||
if (!schem) | ||
return; | ||
//console.log("partial schema : ", schem) | ||
var obj = deep.utils.fromPath(object, required); | ||
if (obj !== "" && !obj && schem.required) { | ||
//console.log("partial : missing prop : (required)"); | ||
othis.createError(othis.lexic[othis.lexic.__requiredEquivalent].error, obj, "undefined", schem, required); | ||
return; | ||
} | ||
promises.push(othis.validate(obj, schem, { | ||
basePath: required, | ||
baseSchemaPath: null | ||
})); | ||
}); | ||
deep.all(promises) | ||
.then(function partialValidationDone(results) { | ||
var valid = true; | ||
deep.all(promises) | ||
.then(function partialValidationDone(results) { | ||
var valid = true; | ||
results.forEach(function partialValidationDoneLoopResult(report) { | ||
//console.log("validator", "________________ partialValidation : report : "+JSON.stringify(report)); | ||
if (!report.valid) { | ||
valid = false; | ||
for (var i in report.errorsMap) { | ||
if (!othis.errorsMap[i]) | ||
othis.errorsMap[i] = { | ||
errors: [] | ||
}; | ||
othis.errorsMap[i].errors = report.errorsMap[i].errors; | ||
} | ||
results.forEach(function partialValidationDoneLoopResult(report) { | ||
//console.log("validator", "________________ partialValidation : report : "+JSON.stringify(report)); | ||
if (!report.valid) { | ||
valid = false; | ||
for (var i in report.errorsMap) { | ||
if (!othis.errorsMap[i]) | ||
othis.errorsMap[i] = { | ||
errors: [] | ||
}; | ||
othis.errorsMap[i].errors = report.errorsMap[i].errors; | ||
} | ||
}); | ||
//console.log("validator", "________________ partialValidation : final errorsMap : "+JSON.stringify(errorsMap)); | ||
deferred.resolve({ | ||
schema: schema, | ||
value: object, | ||
errorsMap: othis.errorsMap, | ||
valid: valid, | ||
date: Date.now(), | ||
partial: true | ||
}); | ||
} | ||
}); | ||
return deferred.promise(); | ||
}; | ||
//console.log("validator", "________________ partialValidation : final errorsMap : "+JSON.stringify(errorsMap)); | ||
deferred.resolve({ | ||
schema: schema, | ||
value: object, | ||
errorsMap: othis.errorsMap, | ||
valid: valid, | ||
date: Date.now(), | ||
partial: true | ||
}); | ||
}); | ||
return deferred.promise(); | ||
}; | ||
Validator.prototype.validateSchemaProperties = function validateSchemaProperties(value, schema, valuePath, schemaPath) { | ||
var validations = []; | ||
for (var i in schema) { | ||
if (!schema.hasOwnProperty(i)) | ||
continue; | ||
var type = getType.apply(this, [schema[i]]); | ||
switch (i) { | ||
case "type": | ||
if (typeof schema.type !== 'string' || !this.lexic.type[schema.type]) | ||
this.createError(this.lexic.__additionalErrors.unknownSchemaType, schema.type, this.getType(schema.type), null, null, schemaPath, "type"); | ||
break; | ||
case "format": | ||
if (typeof schema.format !== 'string' || !this.lexic.__defaultPattern[schema.format]) | ||
this.createError(this.lexic.__additionalErrors.unknownFormatType, schema.format, this.getType(schema.format), null, null, schemaPath, "format"); | ||
break; | ||
case "pattern": | ||
if (typeof schema.pattern !== 'string' || !this.lexic.__defaultPattern[schema.pattern]) | ||
this.createError(this.lexic.__additionalErrors.unknownFormatType, schema.pattern, this.getType(schema.pattern), null, null, schemaPath, "pattern"); | ||
break; | ||
Validator.prototype.validateSchemaProperties = function validateSchemaProperties(value, schema, valuePath, schemaPath) { | ||
var validations = []; | ||
for (var i in schema) { | ||
if (!schema.hasOwnProperty(i)) | ||
continue; | ||
var type = getType.apply(this, [schema[i]]); | ||
switch (i) { | ||
case "type": | ||
if (typeof schema.type !== 'string' || !this.lexic.type[schema.type]) | ||
this.createError(this.lexic.__additionalErrors.unknownSchemaType, schema.type, this.getType(schema.type), null, null, schemaPath, "type"); | ||
break; | ||
case "format": | ||
if (typeof schema.format !== 'string' || !this.lexic.__defaultPattern[schema.format]) | ||
this.createError(this.lexic.__additionalErrors.unknownFormatType, schema.format, this.getType(schema.format), null, null, schemaPath, "format"); | ||
break; | ||
case "pattern": | ||
if (typeof schema.pattern !== 'string' || !this.lexic.__defaultPattern[schema.pattern]) | ||
this.createError(this.lexic.__additionalErrors.unknownFormatType, schema.pattern, this.getType(schema.pattern), null, null, schemaPath, "pattern"); | ||
break; | ||
default: | ||
validations.push(this.checkRef(schema[i], this.lexic[i].schema, schemaPath, i + ".schema")); | ||
} | ||
default: | ||
validations.push(this.checkRef(schema[i], this.lexic[i].schema, schemaPath, i + ".schema")); | ||
} | ||
return validations; | ||
}; | ||
} | ||
return validations; | ||
}; | ||
Validator.prototype.validateProperty = function(value, schema, valuePath, schemaPath) { | ||
var validations = []; | ||
// console.log("_______________________________ validateProperty ", valuePath) | ||
Validator.prototype.validateProperty = function(value, schema, valuePath, schemaPath) { | ||
var validations = []; | ||
// console.log("_______________________________ validateProperty ", valuePath) | ||
var type = this.getType(value); | ||
var othis = this; | ||
var ok = true; | ||
// console.log("_______________________________ forceConversio sart") | ||
if (this.options.forceConversion && schema.type !== type) | ||
switch (schema.type) { | ||
case "number": | ||
if (isNaN(value)) | ||
{ | ||
value = NaN; | ||
ok = false; | ||
break; | ||
} | ||
value = parseFloat(value); | ||
var type = this.getType(value); | ||
var othis = this; | ||
var ok = true; | ||
// console.log("_______________________________ forceConversio sart") | ||
if (this.options.forceConversion && schema.type !== type) | ||
switch (schema.type) { | ||
case "number": | ||
if (isNaN(value)) { | ||
value = NaN; | ||
ok = false; | ||
break; | ||
case "float": | ||
if (isNaN(value)) | ||
{ | ||
value = NaN; | ||
ok = false; | ||
break; | ||
} | ||
value = parseFloat(value); | ||
} | ||
value = parseFloat(value); | ||
break; | ||
case "float": | ||
if (isNaN(value)) { | ||
value = NaN; | ||
ok = false; | ||
break; | ||
case "integer": | ||
if (isNaN(value)) | ||
{ | ||
value = NaN; | ||
ok = false; | ||
break; | ||
} | ||
value = parseInt(value, 10); | ||
} | ||
value = parseFloat(value); | ||
break; | ||
case "integer": | ||
if (isNaN(value)) { | ||
value = NaN; | ||
ok = false; | ||
break; | ||
case "boolean": | ||
//console.log("VERIFY A BOOLEAN VALUE - value = ", val ) | ||
value = (value == 'true' || value == "1" || value === true) ? true : false; | ||
break; | ||
} | ||
} | ||
value = parseInt(value, 10); | ||
break; | ||
case "boolean": | ||
//console.log("VERIFY A BOOLEAN VALUE - value = ", val ) | ||
value = (value == 'true' || value == "1" || value === true) ? true : false; | ||
break; | ||
} | ||
// console.log("_______________________________ forceConversio done : ", value, type, schema.type) | ||
if(ok) | ||
{ | ||
ok = false; | ||
if (type === null) | ||
type = typeof value; | ||
if (!schema.type) | ||
schema.type = "object"; | ||
if (ok) { | ||
ok = false; | ||
if (type === null) | ||
type = typeof value; | ||
if (!schema.type) | ||
schema.type = "object"; | ||
var types = schema.type; | ||
if (!types.push) | ||
types = [types]; | ||
var types = schema.type; | ||
if (!types.push) | ||
types = [types]; | ||
if (type == 'undefined' && !schema.required) | ||
ok = true; | ||
else | ||
for (var i = 0; i < types.length; ++i) { | ||
if (types[i] == "schema") { | ||
if (type != "object") | ||
this.createError(this.lexic.__additionalErrors.schemaIsNotObject, value, type, schema, valuePath, schemaPath, schemaPath + ".type"); | ||
else | ||
validations.push(this.validateSchemaProperties(null, value, null, valuePath)); | ||
return; | ||
} | ||
if (!this.lexic.type[types[i]]) { | ||
this.createError(this.lexic.__additionalErrors.unknownSchemaType, value, type, schema, valuePath, schemaPath, schemaPath + ".type"); | ||
continue; | ||
} | ||
if (type == types[i] || types[i] == "any") { | ||
ok = true; | ||
break; | ||
} | ||
if (type == 'undefined' && !schema.required) | ||
ok = true; | ||
else | ||
for (var i = 0; i < types.length; ++i) { | ||
if (types[i] == "schema") { | ||
if (type != "object") | ||
this.createError(this.lexic.__additionalErrors.schemaIsNotObject, value, type, schema, valuePath, schemaPath, schemaPath + ".type"); | ||
else | ||
validations.push(this.validateSchemaProperties(null, value, null, valuePath)); | ||
return; | ||
} | ||
} | ||
if (!ok) | ||
this.createError(this.lexic.__additionalErrors.badType, value, type, schema, valuePath, schemaPath, schemaPath + ".type"); | ||
if (!this.lexic.type[types[i]]) { | ||
this.createError(this.lexic.__additionalErrors.unknownSchemaType, value, type, schema, valuePath, schemaPath, schemaPath + ".type"); | ||
continue; | ||
} | ||
if (type == types[i] || types[i] == "any") { | ||
ok = true; | ||
break; | ||
} | ||
} | ||
} | ||
if (!ok) | ||
this.createError(this.lexic.__additionalErrors.badType, value, type, schema, valuePath, schemaPath, schemaPath + ".type"); | ||
var dependenciesMatch = false; | ||
if (schema.dependencies && schema.dependencies.length > 0) { | ||
var dependenciesMatch = false; | ||
if (schema.dependencies && schema.dependencies.length > 0) { | ||
schema.dependencies.forEach(function(dep) { | ||
var res = deep.Querier.query(value, dep.query); | ||
// console.log("test dependancy query: ", res, " - constraints : ", dep.constraints); | ||
if (res.length > 0) { | ||
dependenciesMatch = true; | ||
var finSchema = deep.utils.up(schema, {}); | ||
deep.utils.up(dep.constraints, finSchema); | ||
delete finSchema.dependencies; | ||
var rep = othis.validateProperty(value, finSchema, valuePath, schemaPath); | ||
///console.log("dependency validation ? ", rep.valid) | ||
ok = ok && rep.valid; | ||
} | ||
}); | ||
} | ||
schema.dependencies.forEach(function(dep) { | ||
var res = deep.Querier.query(value, dep.query); | ||
// console.log("test dependancy query: ", res, " - constraints : ", dep.constraints); | ||
if (res.length > 0) { | ||
dependenciesMatch = true; | ||
var finSchema = deep.utils.up(schema, {}); | ||
deep.utils.up(dep.constraints, finSchema); | ||
delete finSchema.dependencies; | ||
var rep = othis.validateProperty(value, finSchema, valuePath, schemaPath); | ||
///console.log("dependency validation ? ", rep.valid) | ||
ok = ok && rep.valid; | ||
} | ||
}); | ||
} | ||
if (!dependenciesMatch && schema.items && type == "array") { | ||
if (schema.items.push) { | ||
var i = 0; | ||
for (; i < schema.items.length; ++i) | ||
validations.push(this.checkRef(value[i], schema.items[i], valuePath + "." + i, schemaPath + ".items[" + i + "]")); | ||
if (i < value.length && (schema.additionalItems === undefined || schema.additionalItems !== false)) | ||
for (; i < value.length; ++i) | ||
validations.push(this.checkRef(value[i], schema.additionalItems || {}, valuePath + "[" + i + "]", schemaPath + ".additionalItems")); | ||
else if (schema.additionalItems === false) | ||
this.createError(this.lexic.additionalItems.error, value, type, schema, valuePath + "[" + i + "]", schemaPath + ".items"); | ||
} else | ||
for (var i = 0; i < value.length; ++i) | ||
validations.push(this.checkRef(value[i], schema.items, valuePath + "." + i, schemaPath + ".items")); | ||
} | ||
if (!dependenciesMatch && schema.items && type == "array") { | ||
if (schema.items.push) { | ||
var i = 0; | ||
for (; i < schema.items.length; ++i) | ||
validations.push(this.checkRef(value[i], schema.items[i], valuePath + "." + i, schemaPath + ".items[" + i + "]")); | ||
if (i < value.length && (schema.additionalItems === undefined || schema.additionalItems !== false)) | ||
for (; i < value.length; ++i) | ||
validations.push(this.checkRef(value[i], schema.additionalItems || {}, valuePath + "[" + i + "]", schemaPath + ".additionalItems")); | ||
else if (schema.additionalItems === false) | ||
this.createError(this.lexic.additionalItems.error, value, type, schema, valuePath + "[" + i + "]", schemaPath + ".items"); | ||
} else | ||
for (var i = 0; i < value.length; ++i) | ||
validations.push(this.checkRef(value[i], schema.items, valuePath + "." + i, schemaPath + ".items")); | ||
} | ||
if (!dependenciesMatch && type == "object") { | ||
// check all properties of object | ||
for (var i in value) { | ||
if (!value.hasOwnProperty(i)) | ||
continue; | ||
var schemas = []; | ||
// get schema pattern properties that match property name | ||
if (schema.patternProperties) | ||
schemas = findPatternProperties(i, schema.patternProperties); | ||
// get regular property | ||
if (schema.properties && schema.properties[i]) | ||
schemas.push(schema.properties[i]); | ||
if (schemas.length === 0) // no pattern nor regular schema find for this property | ||
{ | ||
if (schema.additionalProperties === undefined || schema.additionalProperties !== false) // try additionalProperties schema | ||
validations.push(this.checkRef(value[i], schema.additionalProperties || { | ||
type: "any" | ||
}, valuePath + "." + i, schemaPath + ".additionalProperties")); | ||
else if (schema.additionalProperties === false) | ||
this.createError(this.lexic.additionalProperties.error, value[i], getType.apply(this, [value[i]]), schema, valuePath + "." + i, schemaPath + ".properties." + i); | ||
} else { // merge array of schema found for this property (patterns and/or regular schema properties) | ||
var res = {}; | ||
schemas.forEach(function(e) { // merge : patterns in backgrounds, regular on top | ||
deep.utils.up(e, res); | ||
}); | ||
validations.push(this.checkRef(value[i], res, valuePath + "." + i, schemaPath + ".(merged)properties." + i)); | ||
} | ||
} | ||
//console.log("required ? "+this.lexic[this.lexic.__requiredEquivalent].schema.type) | ||
// check required that's missing | ||
if (this.lexic[this.lexic.__requiredEquivalent].schema.type == "boolean") // handling v2 and v3 behaviour. Ommited for v4. | ||
if (!dependenciesMatch && type == "object") { | ||
// check all properties of object | ||
for (var i in value) { | ||
if (!value.hasOwnProperty(i)) | ||
continue; | ||
var schemas = []; | ||
// get schema pattern properties that match property name | ||
if (schema.patternProperties) | ||
schemas = findPatternProperties(i, schema.patternProperties); | ||
// get regular property | ||
if (schema.properties && schema.properties[i]) | ||
schemas.push(schema.properties[i]); | ||
if (schemas.length === 0) // no pattern nor regular schema find for this property | ||
{ | ||
// console.log("handle required as boolean") | ||
for (var i in schema.properties) | ||
if (schema.properties[i][this.lexic.__requiredEquivalent] && typeof value[i] === 'undefined') | ||
this.createError(this.lexic[this.lexic.__requiredEquivalent].error, value[i], "undefined", schema, valuePath + "." + i, schemaPath + ".properties." + i); | ||
if (schema.additionalProperties === undefined || schema.additionalProperties !== false) // try additionalProperties schema | ||
validations.push(this.checkRef(value[i], schema.additionalProperties || { | ||
type: "any" | ||
}, valuePath + "." + i, schemaPath + ".additionalProperties")); | ||
else if (schema.additionalProperties === false) | ||
this.createError(this.lexic.additionalProperties.error, value[i], getType.apply(this, [value[i]]), schema, valuePath + "." + i, schemaPath + ".properties." + i); | ||
} else { // merge array of schema found for this property (patterns and/or regular schema properties) | ||
var res = {}; | ||
schemas.forEach(function(e) { // merge : patterns in backgrounds, regular on top | ||
deep.utils.up(e, res); | ||
}); | ||
validations.push(this.checkRef(value[i], res, valuePath + "." + i, schemaPath + ".(merged)properties." + i)); | ||
} | ||
} | ||
if (!dependenciesMatch) | ||
for (var i in schema) | ||
{ | ||
if (!schema.hasOwnProperty(i)) | ||
continue; | ||
//console.log("simple schema prop test : "+i + " - schema : "+JSON.stringify(schema)) | ||
switch (i) { | ||
case "type": | ||
break; | ||
case "properties": | ||
break; | ||
case "dependencies": | ||
break; | ||
case "patternProperties": | ||
break; | ||
case "items": | ||
break; | ||
case "additionalItems": | ||
break; | ||
case "additionalProperties": | ||
break; | ||
default: | ||
//console.log("Validator.lexic[i] ",i) | ||
if (this.lexic[i]) | ||
this.doTest(this.lexic[i], value, type, schema, valuePath, schemaPath); | ||
else | ||
if (console.flags && console.flags.validator) console.log("validator", "unrecognised schema property : " + i); | ||
} | ||
//console.log("required ? "+this.lexic[this.lexic.__requiredEquivalent].schema.type) | ||
// check required that's missing | ||
if (this.lexic[this.lexic.__requiredEquivalent].schema.type == "boolean") // handling v2 and v3 behaviour. Ommited for v4. | ||
{ | ||
// console.log("handle required as boolean") | ||
for (var i in schema.properties) | ||
if (schema.properties[i][this.lexic.__requiredEquivalent] && typeof value[i] === 'undefined') | ||
this.createError(this.lexic[this.lexic.__requiredEquivalent].error, value[i], "undefined", schema, valuePath + "." + i, schemaPath + ".properties." + i); | ||
} | ||
} | ||
if (!dependenciesMatch) | ||
for (var i in schema) { | ||
if (!schema.hasOwnProperty(i)) | ||
continue; | ||
//console.log("simple schema prop test : "+i + " - schema : "+JSON.stringify(schema)) | ||
switch (i) { | ||
case "type": | ||
break; | ||
case "properties": | ||
break; | ||
case "dependencies": | ||
break; | ||
case "patternProperties": | ||
break; | ||
case "items": | ||
break; | ||
case "additionalItems": | ||
break; | ||
case "additionalProperties": | ||
break; | ||
default: | ||
//console.log("Validator.lexic[i] ",i) | ||
if (this.lexic[i]) | ||
this.doTest(this.lexic[i], value, type, schema, valuePath, schemaPath); | ||
else | ||
if (console.flags && console.flags.validator) console.log("validator", "unrecognised schema property : " + i); | ||
} | ||
return validations; | ||
}; | ||
} | ||
return validations; | ||
}; | ||
Validator.prototype.applyLexic = function applyLexic(lexic) { | ||
deep.utils.up(lexic, this.lexic); | ||
}; | ||
Validator.prototype.lexic = { | ||
__additionalErrors: { | ||
schemaIsNotObject: "{ path }, trying to validate a schema (type:'schema') but the value isn't an object : Value provided : { value }", | ||
badType: "{ path }, type not allowed. Allowed type : { schema.type }", | ||
unknownSchemaType: "type from schema is unknown : { schema.type }" | ||
Validator.prototype.applyLexic = function applyLexic(lexic) { | ||
deep.utils.up(lexic, this.lexic); | ||
}; | ||
Validator.prototype.lexic = { | ||
__additionalErrors: { | ||
schemaIsNotObject: "{ path }, trying to validate a schema (type:'schema') but the value isn't an object : Value provided : { value }", | ||
badType: "{ path }, type not allowed. Allowed type : { schema.type }", | ||
unknownSchemaType: "type from schema is unknown : { schema.type }" | ||
}, | ||
__requiredEquivalent: "required", | ||
__defaultPattern: { | ||
uri: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with uri format" | ||
}, | ||
__requiredEquivalent: "required", | ||
__defaultPattern: { | ||
uri: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with uri format" | ||
date: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
date: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with date format" | ||
error: "need to be with date format" | ||
}, | ||
phone: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
phone: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with phone format" | ||
error: "need to be with phone format" | ||
}, | ||
email: { | ||
//test:function(value){ return (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/).test(value) }, | ||
test: function(value) { | ||
return (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/gi).test(value); | ||
}, | ||
email: { | ||
//test:function(value){ return (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/).test(value) }, | ||
test: function(value) { | ||
return (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/gi).test(value); | ||
}, | ||
error: "need to be with email format" | ||
error: "need to be with email format" | ||
}, | ||
zip: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
zip: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with zip format" | ||
error: "need to be with zip format" | ||
}, | ||
ipv4: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
ipv4: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with ipv4 format" | ||
error: "need to be with ipv4 format" | ||
}, | ||
ipv6: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
ipv6: { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with ipv6 format" | ||
error: "need to be with ipv6 format" | ||
}, | ||
"date-time": { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
"date-time": { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with date-time format" | ||
error: "need to be with date-time format" | ||
}, | ||
"utc-millisec": { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
"utc-millisec": { | ||
test: function(value) { | ||
return (/.*/g).test(value); | ||
}, | ||
error: "need to be with date-time format" | ||
error: "need to be with date-time format" | ||
} | ||
}, | ||
type: { | ||
any: { | ||
test: function(value) { | ||
return true; | ||
} | ||
}, | ||
type: { | ||
any: { | ||
test: function(value) { | ||
return true; | ||
} | ||
object: { | ||
test: function(value) { | ||
return typeof value === 'object'; | ||
}, | ||
object: { | ||
test: function(value) { | ||
return typeof value === 'object'; | ||
}, | ||
error: "{ path } need to be float." | ||
error: "{ path } need to be float." | ||
}, | ||
"boolean": { | ||
test: function(value) { | ||
return value === true || value === false; | ||
}, | ||
"boolean": { | ||
test: function(value) { | ||
return value === true || value === false; | ||
}, | ||
error: "{ path } need to be float." | ||
error: "{ path } need to be float." | ||
}, | ||
number: { | ||
test: function(value) { | ||
// console.log("DEEP-SCHEMA : test number type of : ", value, typeof value); | ||
return typeof value === 'number' && !isNaN(value); | ||
}, | ||
number: { | ||
test: function(value) { | ||
// console.log("DEEP-SCHEMA : test number type of : ", value, typeof value); | ||
return typeof value === 'number' && !isNaN(value); | ||
}, | ||
error: "{ path } need to be float." | ||
error: "{ path } need to be float." | ||
}, | ||
"null": { | ||
test: function(value) { | ||
return value === null; | ||
}, | ||
"null": { | ||
test: function(value) { | ||
return value === null; | ||
}, | ||
error: "{ path } need to be null." | ||
error: "{ path } need to be null." | ||
}, | ||
string: { | ||
test: function(value) { | ||
return typeof value === 'string'; | ||
}, | ||
string: { | ||
test: function(value) { | ||
return typeof value === 'string'; | ||
}, | ||
error: "{ path } need to be string." | ||
error: "{ path } need to be string." | ||
}, | ||
array: { | ||
test: function(value) { | ||
return value instanceof Array; | ||
}, | ||
array: { | ||
test: function(value) { | ||
return value instanceof Array; | ||
}, | ||
error: "{ path } need to be array." | ||
error: "{ path } need to be array." | ||
}, | ||
schema: { | ||
test: function(value) { | ||
return typeof value === 'object'; | ||
}, | ||
schema: { | ||
test: function(value) { | ||
return typeof value === 'object'; | ||
}, | ||
error: "{ path } need to be true." | ||
error: "{ path } need to be true." | ||
} | ||
}, | ||
dependencies: { | ||
schema: { | ||
type: "array", | ||
items: { | ||
properties: { | ||
query: { | ||
type: "string", | ||
required: true | ||
}, | ||
constraints: { | ||
type: "schema" | ||
} | ||
} | ||
} | ||
}, | ||
dependencies: { | ||
schema: { | ||
type: "array", | ||
items: { | ||
properties: { | ||
query: { | ||
type: "string", | ||
required: true | ||
}, | ||
constraints: { | ||
type: "schema" | ||
test: function(value, type, schema, valuePath, schemaPath) { | ||
var othis = this; | ||
var ok = true; | ||
//console.log("DEEP-SCHEMA : test dependencies : ", schema.dependencies); | ||
if (schema.dependencies && schema.dependencies.length > 0) | ||
schema.dependencies.forEach(function(dep) { | ||
var res = deep.Querier.query(value, dep.query); | ||
//console.log("test dependancy query: ", res) | ||
if (res.length > 0) { | ||
var schemaCopied = {}; | ||
for (var i in schema) { | ||
if (!schema.hasOwnProperty(i) || i == "dependencies") | ||
continue; | ||
schemaCopied[i] = deep.utils.up(schema[i], {}); | ||
} | ||
schemaCopied = deep.utils.up(dep.constraints, schemaCopied); | ||
var rep = othis.validateProperty(value, schemaCopied, valuePath, schemaPath); | ||
///console.log("dependency validation ? ", rep.valid) | ||
ok = ok && rep.valid; | ||
} | ||
} | ||
}, | ||
test: function(value, type, schema, valuePath, schemaPath) { | ||
var othis = this; | ||
var ok = true; | ||
//console.log("DEEP-SCHEMA : test dependencies : ", schema.dependencies); | ||
if (schema.dependencies && schema.dependencies.length > 0) | ||
schema.dependencies.forEach(function(dep) { | ||
var res = deep.Querier.query(value, dep.query); | ||
//console.log("test dependancy query: ", res) | ||
if (res.length > 0) { | ||
var schemaCopied = {}; | ||
for (var i in schema) { | ||
if (!schema.hasOwnProperty(i) || i == "dependencies") | ||
continue; | ||
schemaCopied[i] = deep.utils.up(schema[i], {}); | ||
} | ||
schemaCopied = deep.utils.up(dep.constraints, schemaCopied); | ||
var rep = othis.validateProperty(value, schemaCopied, valuePath, schemaPath); | ||
///console.log("dependency validation ? ", rep.valid) | ||
ok = ok && rep.valid; | ||
} | ||
}); | ||
}); | ||
return true; | ||
}, | ||
error: "{ path } unmatched dependency { schema.dependencies }. Value provided : { value|json }" | ||
}, | ||
format: { | ||
schema: { | ||
type: "string" | ||
}, | ||
test: function(value, type, schema, valuePath, schemaPath) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
}, | ||
error: "{ path } unmatched dependency { schema.dependencies }. Value provided : { value|json }" | ||
}, | ||
format: { | ||
schema: { | ||
type: "string" | ||
}, | ||
test: function(value, type, schema, valuePath, schemaPath) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type == "array" || type == "object") return true; | ||
//console.log("try interpret reg exp for format : "+this.lexic.__defaultPattern[schema.format].test) | ||
if (type == "array" || type == "object") return true; | ||
//console.log("try interpret reg exp for format : "+this.lexic.__defaultPattern[schema.format].test) | ||
if (this.lexic.__defaultPattern[schema.format]) | ||
return this.lexic.__defaultPattern[schema.format].test.apply(this, [value, type, schema, valuePath, schemaPath, schemaPath + ".format"]); | ||
//console.log("try interpret direct reg exp for format : "+schema.format) | ||
return new RegExp(schema.format).test(String(value)); | ||
}, | ||
error: "{ path } unmatched format { schema.format }." | ||
if (this.lexic.__defaultPattern[schema.format]) | ||
return this.lexic.__defaultPattern[schema.format].test.apply(this, [value, type, schema, valuePath, schemaPath, schemaPath + ".format"]); | ||
//console.log("try interpret direct reg exp for format : "+schema.format) | ||
return new RegExp(schema.format).test(String(value)); | ||
}, | ||
pattern: { | ||
schema: { | ||
type: "string" | ||
}, | ||
test: function(value, type, schema, valuePath, schemaPath) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type == "array" || type == "object") return true; | ||
if (this.lexic.__defaultPattern[schema.pattern]) | ||
return this.doTest(this.lexic.__defaultPattern[schema.pattern], value, type, schema, valuePath, schemaPath, schemaPath + ".pattern"); | ||
return new RegExp(schema.pattern).searchInterpretable(String(value)); | ||
}, | ||
error: "{ path } unmatched pattern { schema.pattern }." | ||
error: "{ path } unmatched format { schema.format }." | ||
}, | ||
pattern: { | ||
schema: { | ||
type: "string" | ||
}, | ||
minLength: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
test: function(value, type, schema) { | ||
//console.log("min length "+value.length+ " - type : "+type + " - have to be : "+schema.minLength) | ||
if (type != "array" && type != "string" && type != "integer") return true; | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
return value.length >= schema.minLength; | ||
}, | ||
error: "{ path } need to be at least { schema.minLength } length." | ||
test: function(value, type, schema, valuePath, schemaPath) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type == "array" || type == "object") return true; | ||
if (this.lexic.__defaultPattern[schema.pattern]) | ||
return this.doTest(this.lexic.__defaultPattern[schema.pattern], value, type, schema, valuePath, schemaPath, schemaPath + ".pattern"); | ||
return new RegExp(schema.pattern).searchInterpretable(String(value)); | ||
}, | ||
maxLength: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
if (type != "array" && type != "string" && type != "integer") return true; | ||
return value.length <= schema.maxLength; | ||
}, | ||
error: "{ path } need to be at max { schema.minLength } length." | ||
error: "{ path } unmatched pattern { schema.pattern }." | ||
}, | ||
minLength: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
minimum: { | ||
schema: { | ||
type: "number" | ||
}, | ||
test: function(value, type, schema) { | ||
if (type != "number" && type != "integer") return true; | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
if (schema.exclusiveMinimum) return value > schema.minimum; | ||
return value >= schema.minimum; | ||
}, | ||
error: "{ path } need to be at least { schema.exclusiveMinimum }." | ||
test: function(value, type, schema) { | ||
//console.log("min length "+value.length+ " - type : "+type + " - have to be : "+schema.minLength) | ||
if (type != "array" && type != "string" && type != "integer") return true; | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
return value.length >= schema.minLength; | ||
}, | ||
maximum: { | ||
schema: { | ||
type: "number" | ||
}, | ||
test: function(value, type, schema) { | ||
if (type != "number" && type != "integer") return true; | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (schema.exclusiveMaximum) return value < schema.maximum; | ||
return value <= schema.maximum; | ||
}, | ||
error: "{ path } need to be max { schema.exclusiveMaximum }." | ||
error: "{ path } need to be at least { schema.minLength } length." | ||
}, | ||
maxLength: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
minItems: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "array") return true; | ||
return value.length >= schema.minItems; | ||
}, | ||
error: "{ path } need to be at least { schema.minItems } long. Value provided : { value|json }" | ||
test: function(value, type, schema) { | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
if (type != "array" && type != "string" && type != "integer") return true; | ||
return value.length <= schema.maxLength; | ||
}, | ||
maxItems: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
if (type != "array") return true; | ||
return value.length <= schema.maxItems; | ||
}, | ||
error: "{ path } need to be at max { schema.maxItems } long. Value provided : { value|json }" | ||
error: "{ path } need to be at max { schema.minLength } length." | ||
}, | ||
minimum: { | ||
schema: { | ||
type: "number" | ||
}, | ||
required: { /// draft v3 | ||
schema: { | ||
type: "boolean" | ||
}, | ||
test: function(value, type, schema) { | ||
//console.log("Validator : check required : ", typeof value !== 'undefined' ) | ||
return typeof value !== 'undefined'; | ||
}, | ||
error: "{ path } is required and is missing." | ||
test: function(value, type, schema) { | ||
if (type != "number" && type != "integer") return true; | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
if (schema.exclusiveMinimum) return value > schema.minimum; | ||
return value >= schema.minimum; | ||
}, | ||
"enum": { | ||
schema: { | ||
type: "array", | ||
items: { | ||
type: "string" | ||
} | ||
}, | ||
test: function(value, type, schema) { | ||
if ((typeof value === 'undefined' || value === "") && !schema.required) | ||
return true; | ||
if (type != "string" && type != "number" && type != "integer") return true; | ||
var ok = false; | ||
for (var i = 0; i < schema["enum"].length; ++i) | ||
if (value == schema['enum'][i]) { | ||
ok = true; | ||
break; | ||
} | ||
return ok; | ||
}, | ||
error: "{ path } need to be equal to one of those values { schema.enum|join_coma }." | ||
error: "{ path } need to be at least { schema.exclusiveMinimum }." | ||
}, | ||
maximum: { | ||
schema: { | ||
type: "number" | ||
}, | ||
disallow: { | ||
schema: { | ||
type: ["array", "string"], | ||
'enum': ["string", "array", "number", "integer", "date", "function", "null", "object"], | ||
items: { | ||
type: "string", | ||
'enum': ["string", "array", "number", "integer", "date", "function", "null", "object"] | ||
} | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (typeof disallow.push !== 'function') | ||
return schema.disallow !== type; | ||
for (var i in schema.disallow) | ||
if (schema.disallow[i] == type) | ||
return false; | ||
test: function(value, type, schema) { | ||
if (type != "number" && type != "integer") return true; | ||
if ((!value) && !schema.required) | ||
return true; | ||
}, | ||
error: "{ path } need to be of different type than { schema.disallow|join_coma }. type provided : { type }" | ||
if (schema.exclusiveMaximum) return value < schema.maximum; | ||
return value <= schema.maximum; | ||
}, | ||
divisibleBy: { | ||
schema: { | ||
type: "integer", | ||
minimum: 1, | ||
absoluteMinimum: true | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
return value % schema.divisibleBy === 0; | ||
}, | ||
error: "{ path } ( value : { value }) need to be divisible by { schema.divisibleBy }." | ||
error: "{ path } need to be max { schema.exclusiveMaximum }." | ||
}, | ||
minItems: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
uniqueItems: { | ||
schema: { | ||
type: "boolean" | ||
}, | ||
test: function(value, type, schema) { | ||
if (type != "array") return true; | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (!schema.uniqueItems) | ||
return true; | ||
var uniques = deep.utils.arrayFusion(value, value); | ||
return uniques.length == value.length; | ||
}, | ||
error: "each item need to be unique" | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "array") return true; | ||
return value.length >= schema.minItems; | ||
}, | ||
exclusiveMinimum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
error: "{ path } need to be at least { schema.minItems } long. Value provided : { value|json }" | ||
}, | ||
maxItems: { | ||
schema: { | ||
type: "integer" | ||
}, | ||
exclusiveMaximum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
test: function(value, type, schema) { | ||
if ((!value || value === "") && !schema.required) | ||
return true; | ||
if (type != "array") return true; | ||
return value.length <= schema.maxItems; | ||
}, | ||
/* dependencies:{},*/ | ||
"default": { | ||
schema: { | ||
type: "any" | ||
} | ||
error: "{ path } need to be at max { schema.maxItems } long. Value provided : { value|json }" | ||
}, | ||
required: { /// draft v3 | ||
schema: { | ||
type: "boolean" | ||
}, | ||
title: { | ||
schema: { | ||
type: "string" | ||
} | ||
test: function(value, type, schema) { | ||
//console.log("Validator : check required : ", typeof value !== 'undefined' ) | ||
return typeof value !== 'undefined'; | ||
}, | ||
description: { | ||
schema: { | ||
error: "{ path } is required and is missing." | ||
}, | ||
"enum": { | ||
schema: { | ||
type: "array", | ||
items: { | ||
type: "string" | ||
} | ||
}, | ||
id: { | ||
schema: { | ||
type: "string" | ||
} | ||
test: function(value, type, schema) { | ||
if ((typeof value === 'undefined' || value === "") && !schema.required) | ||
return true; | ||
if (type != "string" && type != "number" && type != "integer") return true; | ||
var ok = false; | ||
for (var i = 0; i < schema["enum"].length; ++i) | ||
if (value == schema['enum'][i]) { | ||
ok = true; | ||
break; | ||
} | ||
return ok; | ||
}, | ||
readOnly: { | ||
schema: { | ||
type: "boolean" | ||
error: "{ path } need to be equal to one of those values { schema.enum|join_coma }." | ||
}, | ||
disallow: { | ||
schema: { | ||
type: ["array", "string"], | ||
'enum': ["string", "array", "number", "integer", "date", "function", "null", "object"], | ||
items: { | ||
type: "string", | ||
'enum': ["string", "array", "number", "integer", "date", "function", "null", "object"] | ||
} | ||
}, | ||
//EXTERNAL REFERENCES | ||
"backgrounds": { | ||
schema: { | ||
type: ["string", "array"], | ||
items: { | ||
type: "string" | ||
}, | ||
loadable: "direct" | ||
} | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (typeof disallow.push !== 'function') | ||
return schema.disallow !== type; | ||
for (var i in schema.disallow) | ||
if (schema.disallow[i] == type) | ||
return false; | ||
return true; | ||
}, | ||
"$schema": { | ||
schema: { | ||
type: "string", | ||
items: { | ||
type: "string" | ||
} | ||
}, | ||
test: function(value, type, schema) { | ||
console.log("$schema isn't implemented in this validator and will not be implemented (due to his self definition method)"); | ||
error: "{ path } need to be of different type than { schema.disallow|join_coma }. type provided : { type }" | ||
}, | ||
divisibleBy: { | ||
schema: { | ||
type: "integer", | ||
minimum: 1, | ||
absoluteMinimum: true | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
} | ||
if (type != "number" && type != "integer") return true; | ||
return value % schema.divisibleBy === 0; | ||
}, | ||
"$ref": { | ||
schema: { | ||
type: "string" | ||
} | ||
error: "{ path } ( value : { value }) need to be divisible by { schema.divisibleBy }." | ||
}, | ||
uniqueItems: { | ||
schema: { | ||
type: "boolean" | ||
}, | ||
links: { | ||
schema: { | ||
type: "array", | ||
items: { | ||
type: "object", | ||
properties: { | ||
rel: { | ||
type: "string", | ||
required: true | ||
}, | ||
href: { | ||
type: "string", | ||
required: true | ||
}, | ||
template: { | ||
type: "string" | ||
}, // replace template | ||
targetSchema: { | ||
type: "string" | ||
}, | ||
method: { | ||
type: "string", | ||
"enum": ["GET", "PUT", "POST", "DELETE"] | ||
}, | ||
enctype: { | ||
type: "string", | ||
"default": "application/json" | ||
}, | ||
schema: { | ||
type: "schema" | ||
} | ||
} | ||
} | ||
} | ||
test: function(value, type, schema) { | ||
if (type != "array") return true; | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (!schema.uniqueItems) | ||
return true; | ||
var uniques = deep.utils.arrayFusion(value, value); | ||
return uniques.length == value.length; | ||
}, | ||
additionalProperties: { | ||
schema: { | ||
type: ["false", "schema"] | ||
error: "each item need to be unique" | ||
}, | ||
exclusiveMinimum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
}, | ||
exclusiveMaximum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
}, | ||
/* dependencies:{},*/ | ||
"default": { | ||
schema: { | ||
type: "any" | ||
} | ||
}, | ||
title: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
description: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
id: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
readOnly: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
}, | ||
//EXTERNAL REFERENCES | ||
"backgrounds": { | ||
schema: { | ||
type: ["string", "array"], | ||
items: { | ||
type: "string" | ||
}, | ||
error: "no additional properties are allowed" | ||
loadable: "direct" | ||
} | ||
}, | ||
"$schema": { | ||
schema: { | ||
type: "string", | ||
items: { | ||
type: "string" | ||
} | ||
}, | ||
patternProperties: { | ||
schema: { | ||
test: function(value, type, schema) { | ||
console.log("$schema isn't implemented in this validator and will not be implemented (due to his self definition method)"); | ||
return true; | ||
} | ||
}, | ||
"$ref": { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
links: { | ||
schema: { | ||
type: "array", | ||
items: { | ||
type: "object", | ||
patternProperties: { | ||
"/.*/g": { | ||
properties: { | ||
rel: { | ||
type: "string", | ||
required: true | ||
}, | ||
href: { | ||
type: "string", | ||
required: true | ||
}, | ||
template: { | ||
type: "string" | ||
}, // replace template | ||
targetSchema: { | ||
type: "string" | ||
}, | ||
method: { | ||
type: "string", | ||
"enum": ["GET", "PUT", "POST", "DELETE"] | ||
}, | ||
enctype: { | ||
type: "string", | ||
"default": "application/json" | ||
}, | ||
schema: { | ||
type: "schema" | ||
@@ -1029,33 +1005,25 @@ } | ||
} | ||
} | ||
}, | ||
additionalProperties: { | ||
schema: { | ||
type: ["false", "schema"] | ||
}, | ||
properties: { | ||
schema: { | ||
type: "object", | ||
patternProperties: { | ||
"/.*/g": { | ||
type: "schema" | ||
} | ||
error: "no additional properties are allowed" | ||
}, | ||
patternProperties: { | ||
schema: { | ||
type: "object", | ||
patternProperties: { | ||
"/.*/g": { | ||
type: "schema" | ||
} | ||
} | ||
}, | ||
contentEncoding: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
mediaType: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
additionalItems: { | ||
schema: { | ||
type: ["false", "schema"] | ||
}, | ||
error: "no additional items are allowed" | ||
}, | ||
items: { | ||
schema: { | ||
type: ["array", "schema"], | ||
items: { | ||
} | ||
}, | ||
properties: { | ||
schema: { | ||
type: "object", | ||
patternProperties: { | ||
"/.*/g": { | ||
type: "schema" | ||
@@ -1065,23 +1033,48 @@ } | ||
} | ||
}; | ||
}, | ||
contentEncoding: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
mediaType: { | ||
schema: { | ||
type: "string" | ||
} | ||
}, | ||
additionalItems: { | ||
schema: { | ||
type: ["false", "schema"] | ||
}, | ||
error: "no additional items are allowed" | ||
}, | ||
items: { | ||
schema: { | ||
type: ["array", "schema"], | ||
items: { | ||
type: "schema" | ||
} | ||
} | ||
} | ||
}; | ||
var draftv4 = { | ||
divisibleBy: { | ||
"$ommit": true | ||
var draftv4 = { | ||
divisibleBy: { | ||
"$ommit": true | ||
}, | ||
mod: { | ||
schema: { | ||
type: "integer", | ||
minimum: 1, | ||
absoluteMinimum: true | ||
}, | ||
mod: { | ||
schema: { | ||
type: "integer", | ||
minimum: 1, | ||
absoluteMinimum: true | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
return value % schema.mod === 0; | ||
}, | ||
error: "need to be divisible by { schema.divisibleBy }" | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
return value % schema.mod === 0; | ||
}, | ||
/*required:{ // draft v4 | ||
error: "need to be divisible by { schema.divisibleBy }" | ||
}, | ||
/*required:{ // draft v4 | ||
schema:{ type:"array", items:{ type:"string" } }, | ||
@@ -1098,242 +1091,242 @@ test:function(value, type, schema){ | ||
},*/ | ||
maxProperties: { | ||
schema: { | ||
type: "integer", | ||
minimum: 0 | ||
}, | ||
test: function(value, type, schema) { | ||
var count = 0; | ||
for (var i in value) { | ||
if (!value.hasOwnProperties(i)) | ||
continue; | ||
count++; | ||
} | ||
return count <= schema.maxProperties; | ||
}, | ||
error: "need to have maximum { schema.maxProperties } properties" | ||
maxProperties: { | ||
schema: { | ||
type: "integer", | ||
minimum: 0 | ||
}, | ||
minProperties: { | ||
schema: { | ||
type: "integer", | ||
minimum: 0 | ||
}, | ||
test: function(value, type, schema) { | ||
var count = 0; | ||
for (var i in value) { | ||
if (!value.hasOwnProperties(i)) | ||
continue; | ||
count++; | ||
} | ||
return count >= schema.minProperties; | ||
}, | ||
error: "need to have minimum { schema.maxProperties } properties" | ||
} | ||
}; | ||
var deepSpecific = { | ||
__defaultPattern: { | ||
retrievable: { | ||
test: function(value) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
return (deep.utils.parseRequest(value).store !== null); | ||
}, | ||
error: "need to be in 'retrievable' format. (see deep/deep-request/isRetrievable())" | ||
test: function(value, type, schema) { | ||
var count = 0; | ||
for (var i in value) { | ||
if (!value.hasOwnProperties(i)) | ||
continue; | ||
count++; | ||
} | ||
} | ||
}; | ||
var newSpec = { | ||
type: { | ||
return count <= schema.maxProperties; | ||
}, | ||
notNull: { | ||
schema: { | ||
type: "boolean" | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (schema.notNull) return value !== null; | ||
return true; | ||
}, | ||
error: "need to be not null" | ||
error: "need to have maximum { schema.maxProperties } properties" | ||
}, | ||
minProperties: { | ||
schema: { | ||
type: "integer", | ||
minimum: 0 | ||
}, | ||
absoluteMaximum: { | ||
schema: { | ||
type: "boolean" | ||
test: function(value, type, schema) { | ||
var count = 0; | ||
for (var i in value) { | ||
if (!value.hasOwnProperties(i)) | ||
continue; | ||
count++; | ||
} | ||
return count >= schema.minProperties; | ||
}, | ||
absoluteMinimum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
}, | ||
minimum: { | ||
test: function(value, type, schema) { | ||
error: "need to have minimum { schema.maxProperties } properties" | ||
} | ||
}; | ||
var deepSpecific = { | ||
__defaultPattern: { | ||
retrievable: { | ||
test: function(value) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
if (schema.absoluteMinimum) value = Math.abs(value); | ||
if (schema.exclusiveMinimum) return value > schema.minimum; | ||
return value >= schema.minimum; | ||
} | ||
return (deep.utils.parseRequest(value).store !== null); | ||
}, | ||
error: "need to be in 'retrievable' format. (see deep/deep-request/isRetrievable())" | ||
} | ||
} | ||
}; | ||
var newSpec = { | ||
type: { | ||
}, | ||
notNull: { | ||
schema: { | ||
type: "boolean" | ||
}, | ||
maximum: { | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
if (schema.absoluteMaximum) value = Math.abs(value); | ||
if (schema.exclusiveMaximum) return value < schema.maximum; | ||
return value <= schema.maximum; | ||
} | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (schema.notNull) return value !== null; | ||
return true; | ||
}, | ||
needMatchingOn: { | ||
schema: { | ||
type: "string" | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
var q = schema.needMatchingOn; | ||
if (q[0] == "#") | ||
q = q.substring(1); | ||
var res = deep.Querier.query(this.rootValue, q); | ||
return res.length > 0 && res[0] == value; | ||
}, | ||
error: "this field need to match { schema.needMatchingOn }" | ||
error: "need to be not null" | ||
}, | ||
absoluteMaximum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
}; | ||
}, | ||
absoluteMinimum: { | ||
schema: { | ||
type: "boolean" | ||
} | ||
}, | ||
minimum: { | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
if (schema.absoluteMinimum) value = Math.abs(value); | ||
if (schema.exclusiveMinimum) return value > schema.minimum; | ||
return value >= schema.minimum; | ||
} | ||
}, | ||
maximum: { | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
if (type != "number" && type != "integer") return true; | ||
if (schema.absoluteMaximum) value = Math.abs(value); | ||
if (schema.exclusiveMaximum) return value < schema.maximum; | ||
return value <= schema.maximum; | ||
} | ||
}, | ||
needMatchingOn: { | ||
schema: { | ||
type: "string" | ||
}, | ||
test: function(value, type, schema) { | ||
if ((!value) && !schema.required) | ||
return true; | ||
var q = schema.needMatchingOn; | ||
if (q[0] == "#") | ||
q = q.substring(1); | ||
var res = deep.Querier.query(this.rootValue, q); | ||
return res.length > 0 && res[0] == value; | ||
}, | ||
error: "this field need to match { schema.needMatchingOn }" | ||
} | ||
}; | ||
var jsonExt = { | ||
type: { | ||
"function": { | ||
test: function(value) { | ||
return typeof value === 'function'; | ||
}, | ||
error: "need to be a function" | ||
var jsonExt = { | ||
type: { | ||
"function": { | ||
test: function(value) { | ||
return typeof value === 'function'; | ||
}, | ||
"false": { | ||
test: function(value) { | ||
return value === false; | ||
}, | ||
error: "need to be false" | ||
error: "need to be a function" | ||
}, | ||
"false": { | ||
test: function(value) { | ||
return value === false; | ||
}, | ||
"true": { | ||
test: function(value) { | ||
return value === true; | ||
}, | ||
error: "need to be true" | ||
error: "need to be false" | ||
}, | ||
"true": { | ||
test: function(value) { | ||
return value === true; | ||
}, | ||
"date": { | ||
test: function(value) { | ||
if (!value) return false; | ||
return typeof value.toUTCString === 'function'; | ||
}, | ||
error: "need to be a date object" | ||
} | ||
error: "need to be true" | ||
}, | ||
"date": { | ||
test: function(value) { | ||
if (!value) return false; | ||
return typeof value.toUTCString === 'function'; | ||
}, | ||
error: "need to be a date object" | ||
} | ||
}; | ||
} | ||
}; | ||
var se_spec = { | ||
__defaultPattern: { | ||
"coordination-number": { | ||
test: function(value, type, schema) { | ||
if (type != "string") | ||
return true; | ||
if (!schema.required && !value) | ||
return true; | ||
if (!value) | ||
return false; | ||
var tmp = value + ""; | ||
if (tmp.length != 10) | ||
return false; | ||
tmp = value.substring(4, 5); | ||
tmp = parseInt(tmp, 10); | ||
if (tmp < 60 || tmp > 91) | ||
return false; | ||
var se_spec = { | ||
__defaultPattern: { | ||
"coordination-number": { | ||
test: function(value, type, schema) { | ||
if (type != "string") | ||
return true; | ||
}, | ||
error: "need to be in coordination-number format" | ||
if (!schema.required && !value) | ||
return true; | ||
if (!value) | ||
return false; | ||
var tmp = value + ""; | ||
if (tmp.length != 10) | ||
return false; | ||
tmp = value.substring(4, 5); | ||
tmp = parseInt(tmp, 10); | ||
if (tmp < 60 || tmp > 91) | ||
return false; | ||
return true; | ||
}, | ||
"personal-number": { | ||
test: function(value, type, schema) { | ||
if (type != "string") | ||
return true; | ||
if (!schema.required && !value) | ||
return true; | ||
if (!value) | ||
return false; | ||
var tmp = value + ""; | ||
if (tmp.length != 10) | ||
return false; | ||
tmp = value.substring(4, 5); | ||
tmp = parseInt(tmp,10); | ||
if (tmp < 60 || tmp > 91) | ||
return false; | ||
error: "need to be in coordination-number format" | ||
}, | ||
"personal-number": { | ||
test: function(value, type, schema) { | ||
if (type != "string") | ||
return true; | ||
}, | ||
error: "need to be in personal-number format" | ||
} | ||
if (!schema.required && !value) | ||
return true; | ||
if (!value) | ||
return false; | ||
var tmp = value + ""; | ||
if (tmp.length != 10) | ||
return false; | ||
tmp = value.substring(4, 5); | ||
tmp = parseInt(tmp, 10); | ||
if (tmp < 60 || tmp > 91) | ||
return false; | ||
return true; | ||
}, | ||
error: "need to be in personal-number format" | ||
} | ||
}; | ||
} | ||
}; | ||
deep.utils.up(draftv4, Validator.prototype.lexic); | ||
deep.utils.up(jsonExt, Validator.prototype.lexic); | ||
deep.utils.up(newSpec, Validator.prototype.lexic); | ||
//deep.utils.up(se_spec, Validator.prototype.lexic); | ||
// deep.utils.deepCopy(leafSpecific, Validator.prototype.lexic); | ||
deep.utils.up(draftv4, Validator.prototype.lexic); | ||
deep.utils.up(jsonExt, Validator.prototype.lexic); | ||
deep.utils.up(newSpec, Validator.prototype.lexic); | ||
//deep.utils.up(se_spec, Validator.prototype.lexic); | ||
// deep.utils.deepCopy(leafSpecific, Validator.prototype.lexic); | ||
var valider = new Validator(); | ||
var valider = new Validator(); | ||
Validator.createDefault = function(schema) { | ||
return valider.createDefault(schema); | ||
}; | ||
Validator.convertStringTo = function(obj, type) { | ||
return valider.convertStringTo(obj, type); | ||
}; | ||
Validator.castAndCheck = function(value, schema, valuePath) { | ||
return valider.castAndCheck(value, schema, valuePath); | ||
}; | ||
Validator.validate = function(obj, schema, options) { | ||
//console.log("Validate : ", obj, schema) | ||
return valider.validate(obj, schema, options); | ||
}; | ||
Validator.getType = function(value) { | ||
return valider.getType(value); | ||
}; | ||
Validator.partialValidation = function(obj, schema, options) { | ||
return valider.partialValidation(obj, schema, options); | ||
}; | ||
Validator.createDefault = function(schema) { | ||
return valider.createDefault(schema); | ||
}; | ||
Validator.convertStringTo = function(obj, type) { | ||
return valider.convertStringTo(obj, type); | ||
}; | ||
Validator.castAndCheck = function(value, schema, valuePath) { | ||
return valider.castAndCheck(value, schema, valuePath); | ||
}; | ||
Validator.validate = function(obj, schema, options) { | ||
//console.log("Validate : ", obj, schema) | ||
return valider.validate(obj, schema, options); | ||
}; | ||
Validator.getType = function(value) { | ||
return valider.getType(value); | ||
}; | ||
Validator.partialValidation = function(obj, schema, options) { | ||
return valider.partialValidation(obj, schema, options); | ||
}; | ||
/** | ||
* the deep schema validator | ||
* @static | ||
* @property Validator | ||
*/ | ||
deep.Validator = Validator; | ||
/** | ||
* perform a schema validation | ||
* @static | ||
* @method validate | ||
* @param object the object to validate | ||
* @param schema the schema | ||
* @return {deep.validate.Report} the validation report | ||
*/ | ||
deep.validate = deep.Validator.validate; | ||
/** | ||
* perform a schema partial validation (only on certain field) | ||
* @static | ||
* @method partialValidation | ||
* @param object the object to validate | ||
* @param fields the array of properties paths to validate | ||
* @param schema the schema | ||
* @return {deep.validate.Report} the validation report | ||
*/ | ||
deep.partialValidation = deep.Validator.partialValidation; | ||
/** | ||
* the deep schema validator | ||
* @static | ||
* @property Validator | ||
*/ | ||
deep.Validator = Validator; | ||
/** | ||
* perform a schema validation | ||
* @static | ||
* @method validate | ||
* @param object the object to validate | ||
* @param schema the schema | ||
* @return {deep.validate.Report} the validation report | ||
*/ | ||
deep.validate = deep.Validator.validate; | ||
/** | ||
* perform a schema partial validation (only on certain field) | ||
* @static | ||
* @method partialValidation | ||
* @param object the object to validate | ||
* @param fields the array of properties paths to validate | ||
* @param schema the schema | ||
* @return {deep.validate.Report} the validation report | ||
*/ | ||
deep.partialValidation = deep.Validator.partialValidation; | ||
return Validator; | ||
}); | ||
return Validator; | ||
}); |
@@ -19,3 +19,3 @@ /** | ||
var sheet = {}; | ||
sheet.sheet = function applySheet(sheet, entry, options) | ||
sheet.sheet = function (sheet, entry, options) | ||
{ | ||
@@ -44,2 +44,12 @@ options = options || {}; | ||
sheet.sheets = function (sheets, entry, options) | ||
{ | ||
var proms = []; | ||
sheets.forEach(function(sh){ | ||
proms.push(sheet.sheet(sh, entry, options)); | ||
}); | ||
return deep.all(proms); | ||
}; | ||
sheet.Sheet = function(obj){ | ||
@@ -68,3 +78,3 @@ obj._deep_sheet_ = true; | ||
sheeter.queue.push(function(entry){ | ||
return deep(entry).deepLoad(context, destructive); | ||
return deep.deepLoad(entry, context, destructive); | ||
}); | ||
@@ -393,3 +403,3 @@ return sheeter; | ||
}); | ||
return res; | ||
return deep.all(res); | ||
}); | ||
@@ -396,0 +406,0 @@ }; |
@@ -19,205 +19,254 @@ /** | ||
define(["require"], function(require) { | ||
define(["require", "./store", "../utils", "../errors", "../chain", "../promise", "../nodes"], function(require, str, utils, errors, chains, prom, nodes) { | ||
return function(deep) { | ||
var addInChain = chains.chain.addInChain; | ||
//______________________________________________________________________ CHAIN DECORATION | ||
chains.Chain.add("store", function(store) { | ||
var self = this; | ||
var func = function(s, e) { | ||
self._storeDef = store; | ||
return deep.when(str.store.prepare(store)) | ||
.done(function(st){ | ||
self._store = st; | ||
}); | ||
}; | ||
str.Store.extendsChain(self); | ||
func._isDone_ = true; | ||
addInChain.call(self, func); | ||
return this; | ||
}); | ||
//______________________________________________________________________ CHAIN DECORATION | ||
deep.Chain.add("store", function(name) { | ||
var createWithBody = function(verb) { | ||
return function(object, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
self._store = name; | ||
return deep.when(deep.protocol.parse(name)) | ||
.done(function(handler) { | ||
//console.log("store init trough chain : ", handler.provider); | ||
self._nodes = [deep.utils.createRootNode(handler.provider)]; | ||
return handler.provider; | ||
var doIt = function(store) { | ||
self._store = store; | ||
var method = store[verb]; | ||
if (!method) | ||
return errors.MethodNotAllowed("provided store doesn't have " + verb + ". aborting POST !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return deep.when(method.call(store, object || chains.chain.val(self), options)) | ||
.done(function(success) { | ||
self._nodes = [nodes.root(success)]; | ||
}); | ||
}; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
deep.Store.extendsChain(self); | ||
func._isDone_ = true; | ||
deep.chain.addInChain.apply(self, [func]); | ||
return this; | ||
}); | ||
var createWithBody = function(verb) { | ||
return function(object, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
//console.log("Chain post : ", object); | ||
var store = storeHandler.provider, | ||
method = store[verb]; | ||
if (!method) | ||
return deep.errors.Store("provided store doesn't have " + verb + ". aborting POST !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return method.call(store, object || deep.chain.val(self), options); | ||
}) | ||
.done(function(success) { | ||
self._nodes = [deep.utils.createRootNode(success)]; | ||
}); | ||
addInChain.call(this, func); | ||
return self; | ||
}; | ||
}; | ||
var chainWithBody = { | ||
post: createWithBody("post"), | ||
put: createWithBody("put"), | ||
patch: createWithBody("patch") | ||
}; | ||
str.Store.extendsChain = function(handler) { | ||
handler.range = function(arg1, arg2, query, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var doIt = function(store) { | ||
self._store = store; | ||
var method = store.range; | ||
if (!method) | ||
return errors.MethodNotAllowed("provided store doesn't have RANGE. aborting RANGE !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return deep.when(method.call(store, arg1, arg2, query, options)) | ||
.done(function(success) { | ||
if (success._deep_range_) | ||
self._nodes = [nodes.root(success.results)]; | ||
else | ||
self._nodes = [nodes.root(success)]; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
deep.chain.addInChain.apply(this, [func]); | ||
return self; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
func._isDone_ = true; | ||
//self.range = chains.chain.prototype.range; | ||
addInChain.call(self, func); | ||
return self; | ||
}; | ||
var chainWithBody = { | ||
post: createWithBody("post"), | ||
put: createWithBody("put"), | ||
patch: createWithBody("patch") | ||
handler.get = function(id, options) { | ||
var self = this; | ||
if (id == "?" || !id) | ||
id = ""; | ||
var func = function(s, e) { | ||
var doIt = function(store){ | ||
self._store = store; | ||
var method = store.get; | ||
if (!method) | ||
return errors.MethodNotAllowed("provided store doesn't have GET. aborting GET !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
if (id[0] == "*") | ||
id = id.substring(1); | ||
return deep.when(method.call(store, id, options)) | ||
.done(function(success) { | ||
//console.log("Deep store chain Get success : ", success); | ||
if (success && success._deep_range_) | ||
self._nodes = [nodes.root(success.results, null, { | ||
uri: id | ||
})]; | ||
else | ||
self._nodes = [nodes.root(success, null, { | ||
uri: id | ||
})]; | ||
}); | ||
}; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
func._isDone_ = true; | ||
addInChain.call(self, func); | ||
//self.range = chains.chain.prototype.range; | ||
return self; | ||
}; | ||
deep.Store.extendsChain = function(handler) { | ||
handler.range = function(arg1, arg2, query, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
var store = storeHandler.provider, | ||
method = store.range; | ||
if (!method) | ||
return deep.errors.Store("provided store doesn't have RANGE. aborting RANGE !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return method.call(store, arg1, arg2, query, options); | ||
}) | ||
.done(function(success) { | ||
if (success._deep_range_) | ||
self._nodes = [deep.utils.createRootNode(success.results)]; | ||
else | ||
self._nodes = [deep.utils.createRootNode(success)]; | ||
}); | ||
handler.post = chainWithBody.post; | ||
handler.put = chainWithBody.put; | ||
handler.patch = chainWithBody.patch; | ||
handler.del = function(id, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var doIt = function(store){ | ||
self._store = store; | ||
var method = store.del; | ||
if (!method) | ||
return errors.MethodNotAllowed("provided store doesn't have DEL. aborting DELETE !"); | ||
var val = chains.chain.val(self); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return deep.when(method.call(store, id || val.id, options)) | ||
.done(function(success) { | ||
self._nodes = [nodes.root(success)]; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
//self.range = deep.Chain.prototype.range; | ||
deep.chain.addInChain.apply(this, [func]); | ||
return self; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
handler.get = function(id, options) { | ||
var self = this; | ||
if (id == "?" || !id) | ||
id = ""; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
var store = storeHandler.provider; | ||
var method = store.get; | ||
if (!method) | ||
return deep.errors.Store("provided store doesn't have GET. aborting GET !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
if (id[0] == "*") | ||
id = id.substring(1); | ||
return method.call(store, id, options); | ||
}) | ||
.done(function(success) { | ||
//console.log("Deep store chain Get success : ", success); | ||
if (success && success._deep_range_) | ||
self._nodes = [deep.utils.createRootNode(success.results, null, { | ||
uri: id | ||
})]; | ||
else | ||
self._nodes = [deep.utils.createRootNode(success, null, { | ||
uri: id | ||
})]; | ||
}); | ||
func._isDone_ = true; | ||
//self.range = chains.chain.prototype.range; | ||
addInChain.call(self, func); | ||
return self; | ||
}; | ||
handler.rpc = function(method, args, uri, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var doIt = function(store){ | ||
self._store = store; | ||
var action = store.rpc; | ||
if (!action) | ||
return errors.MethodNotAllowed("provided store doesn't have RPC. aborting RPC !"); | ||
if (action._deep_ocm_) | ||
action = action(); | ||
return deep.when(action.call(store, method, args, uri, options)) | ||
.done(function(success) { | ||
self._nodes = [ nodes.root(success) ]; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
deep.chain.addInChain.apply(this, [func]); | ||
//self.range = deep.Chain.prototype.range; | ||
return self; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
handler.post = chainWithBody.post; | ||
handler.put = chainWithBody.put; | ||
handler.patch = chainWithBody.patch; | ||
handler.del = function(id, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
var store = storeHandler.provider, | ||
method = store.del; | ||
if (!method) | ||
return deep.errors.Store("provided store doesn't have DEL. aborting DELETE !"); | ||
var val = deep.chain.val(self); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return method.call(store, id || val.id, options); | ||
}) | ||
.done(function(success) { | ||
self._nodes = [deep.utils.createRootNode(success)]; | ||
}); | ||
func._isDone_ = true; | ||
//self.range = chains.chain.prototype.range; | ||
addInChain.call(self, func); | ||
return self; | ||
}; | ||
handler.flush = function(method, body, uri, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var doIt = function(store){ | ||
self._store = store; | ||
var action = store.flush; | ||
if (!action) | ||
return errors.MethodNotAllowed("provided store doesn't have flush. aborting !"); | ||
if (action._deep_ocm_) | ||
action = action(); | ||
return action.call(store); | ||
}; | ||
func._isDone_ = true; | ||
//self.range = deep.Chain.prototype.range; | ||
deep.chain.addInChain.apply(this, [func]); | ||
return self; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
handler.rpc = function(method, body, uri, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
var store = storeHandler.provider, | ||
action = store.rpc; | ||
if (!action) | ||
return deep.errors.Store("provided store doesn't have RPC. aborting RPC !"); | ||
if (action._deep_ocm_) | ||
action = action(); | ||
return action.call(store, method, body, uri, options); | ||
}) | ||
.done(function(success) { | ||
self._nodes = [deep.utils.createRootNode(success)]; | ||
}); | ||
func._isDone_ = true; | ||
//self.range = chains.chain.prototype.range; | ||
addInChain.call(self, func); | ||
return self; | ||
}; | ||
handler.bulk = function(arr, uri, options) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var doIt = function(store){ | ||
self._store = store; | ||
var method = store.bulk; | ||
if (!method) | ||
return errors.MethodNotAllowed("provided store doesn't have BULK. aborting BULK !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return deep.when(method.call(store, arr, uri, options)) | ||
.done(function(success) { | ||
self._nodes = [nodes.root(success)]; | ||
}); | ||
}; | ||
func._isDone_ = true; | ||
//self.range = deep.Chain.prototype.range; | ||
deep.chain.addInChain.apply(this, [func]); | ||
return self; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
handler.flush = function(method, body, uri, options) { | ||
func._isDone_ = true; | ||
//self.range = chains.chain.prototype.range; | ||
addInChain.call(self, func); | ||
return self; | ||
}; | ||
handler.count = function(callback) { | ||
var self = this; | ||
var func = function(s, e) { | ||
var doIt = function(store){ | ||
self._store = store; | ||
var method = store.count; | ||
if (!method) | ||
return errors.MethodNotAllowed("provided store doesn't have COUNT. aborting !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return deep.when(method.call(store)) | ||
.done(callback); | ||
}; | ||
if(self._storeDef && !self._store) | ||
return prom.when(str.store.prepare(self._storeDef)).done(doIt); | ||
return doIt(self._store); | ||
}; | ||
func._isDone_ = true; | ||
//self.range = chains.chain.prototype.range; | ||
addInChain.call(self, func); | ||
return self; | ||
}; | ||
deep.utils.up({ | ||
roles:deep.compose.after(function(){ | ||
var self = this; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
var store = storeHandler.provider, | ||
action = store.flush; | ||
if (!action) | ||
return deep.errors.Store("provided store doesn't have flush. aborting !"); | ||
if (action._deep_ocm_) | ||
action = action(); | ||
return action.call(store); | ||
}); | ||
var func = function(s, e) { | ||
self._store = null; | ||
}; | ||
func._isDone_ = true; | ||
//self.range = deep.Chain.prototype.range; | ||
deep.chain.addInChain.call(this, func); | ||
return self; | ||
}; | ||
handler.bulk = function(arr, uri, options) { | ||
addInChain.call(self, func); | ||
}), | ||
modes:deep.compose.after(function(){ | ||
var self = this; | ||
var func = function(s, e) { | ||
return deep.when(deep.protocol.parse(self._store || self._storeName)) | ||
.done(function(storeHandler) { | ||
var store = storeHandler.provider, | ||
method = store.bulk; | ||
if (!method) | ||
return deep.errors.Store("provided store doesn't have BULK. aborting BULK !"); | ||
if (method._deep_ocm_) | ||
method = method(); | ||
return method.call(store, arr, uri, options); | ||
}) | ||
.done(function(success) { | ||
self._nodes = [deep.utils.createRootNode(success)]; | ||
}); | ||
var func = function(s, e) { | ||
self._store = null; | ||
}; | ||
func._isDone_ = true; | ||
//self.range = deep.Chain.prototype.range; | ||
deep.chain.addInChain.apply(this, [func]); | ||
return self; | ||
}; | ||
return handler; | ||
}; | ||
} | ||
addInChain.call(self, func); | ||
}) | ||
}, handler); | ||
return handler; | ||
}; | ||
}); |
@@ -22,7 +22,7 @@ /** | ||
function(protocol, collection, schema, options) { | ||
if (collection) | ||
this.collection = collection; | ||
this.collection = this.collection || []; | ||
if (schema) | ||
this.schema = schema; | ||
this.collection = collection || this.collection || []; | ||
if(schema && this.schema) | ||
deep.utils.up(schema, this.schema); | ||
else | ||
this.schema = schema || this.schema; | ||
if (options) | ||
@@ -29,0 +29,0 @@ deep.utils.up(options, this); |
@@ -171,2 +171,3 @@ /** | ||
return function(start, end, query, options) { | ||
//console.log("STORE HTTP ", start, end, query); | ||
options = options || {}; | ||
@@ -181,6 +182,12 @@ options.headers = deep.utils.compile(this.headers, deep.globalHeaders, options.headers || {}, { | ||
query = query || ""; | ||
console.log("client client range : ", this); | ||
query = (deep.context.rootPath || deep.globals.rootPath || "") + this.baseURI + (query || ""); | ||
//console.log("client client range : ", this); | ||
if(this.baseURI[this.baseURI.length-1] != "/") | ||
query = "/" + query; | ||
query = this.baseURI + (query || ""); | ||
return deep.when(old.call(this, start, end, query, options)) | ||
.done(function(res) { | ||
//console.log("****** HTTP RES ", res); | ||
if(res.status >= 300) | ||
return deep.errors.Range("You have a " + res.status + " response so no range !"); | ||
//res = { contentRange:"12-24", data:[...] } | ||
@@ -264,3 +271,6 @@ var rangePart = null, | ||
this.baseURI += "/"; | ||
schema = schema || this.schema || null; | ||
if(schema && this.schema) | ||
deep.utils.up(schema, this.schema); | ||
else | ||
this.schema = schema || this.schema; | ||
var self = this; | ||
@@ -267,0 +277,0 @@ if (schema) |
@@ -25,4 +25,6 @@ /** | ||
this.root = root; | ||
if (schema) | ||
this.schema = schema; | ||
if(schema && this.schema) | ||
deep.utils.up(schema, this.schema); | ||
else | ||
this.schema = schema || this.schema; | ||
if (options) | ||
@@ -29,0 +31,0 @@ deep.utils.up(options, this); |
@@ -21,4 +21,4 @@ /** | ||
var argToArr = Array.prototype.slice; | ||
var stores = {}; | ||
//deep.extensions = []; | ||
@@ -38,7 +38,35 @@ /** | ||
*/ | ||
stores.store = function(name) { | ||
stores.store = function(store) { | ||
//console.log("Store(name) : ", name) | ||
return deep({}).store(name); | ||
return deep(store || {}) | ||
.done(function(){ | ||
if(!this._storeDef) | ||
this.store(store); | ||
}) | ||
.done(function(s) { | ||
//console.log("store init trough chain : ", handler.provider); | ||
this._nodes = [deep.nodes.root(s)]; | ||
}); | ||
}; | ||
stores.store.prepare = function(store) | ||
{ | ||
if(typeof store === 'string') | ||
store = deep.protocol(store); | ||
if(!store) | ||
return errors.Store("no store found with : ",store); | ||
//console.log("PREPARE CONTEXT --------> ", deep.context.modes); | ||
if(store._deep_ocm_) | ||
return store.flatten() | ||
.done(function(store){ | ||
//console.log("Store prepare OCM flattened : ", deep.context.modes, store()); | ||
store = store(); | ||
if(store.init) | ||
return store.init() || store; | ||
}); | ||
if(store.init) | ||
return store.init() || store; | ||
return store; | ||
} | ||
/** | ||
@@ -61,5 +89,9 @@ * Empty class : Just there to get instanceof working (be warning with iframe issue in that cases). | ||
Store.prototype = { | ||
_deep_restrictable_:["get","rang","post","put","patch","del","rpc","bulk"] | ||
}; | ||
stores.Store.forbidden = function(message) { | ||
return function(any, options) { | ||
return prom.when(errors.Forbidden(message)); | ||
return errors.Forbidden(message); | ||
}; | ||
@@ -74,14 +106,62 @@ }; | ||
stores.store.AllowOnly = function() { | ||
var allowable = argToArr.call(arguments); | ||
var restrictions = { | ||
get: Store.forbidden(), | ||
range: Store.forbidden(), | ||
post: Store.forbidden(), | ||
put: Store.forbidden(), | ||
patch: Store.forbidden(), | ||
del: Store.forbidden(), | ||
rpc: Store.forbidden(), | ||
bulk: Store.forbidden() | ||
inner:{}, | ||
allowable:allowable, | ||
_deep_compiler_ : true, | ||
_deep_allow_only_ : true, | ||
up : function() { // apply arguments (up) on inner-layer : so merge | ||
// console.log("allow only up : ", arguments); | ||
var res = this.inner; | ||
for (var i = 0, len = arguments.length; i < len; ++i) | ||
{ | ||
var argi = arguments[i]; | ||
if(argi._deep_allow_only_) | ||
{ | ||
res = utils.up(argi.inner, res); | ||
this.allowable = utils.up(argi.allowable, this.allowable); | ||
} | ||
else | ||
res = utils.up(argi, res); | ||
} | ||
this.inner = res; | ||
return this; | ||
}, | ||
bottom : function() { // apply arguments (bottom) on this : so apply restrictions | ||
// console.log("allow only bottom : ", arguments); | ||
var res = this.inner, toKeep = null; | ||
for (var len = arguments.length-1; len >= 0; --len) | ||
{ | ||
var argi = arguments[len]; | ||
if(argi._deep_allow_only_) | ||
{ | ||
res = utils.bottom(argi.inner, res); | ||
this.allowable = utils.up(argi.allowable, this.allowable); | ||
} | ||
else | ||
res = utils.bottom(argi, res); | ||
} | ||
if(res._deep_restrictable_) | ||
{ | ||
var toRemove = deep.utils.removeInside(res._deep_restrictable_.slice(), allowable); | ||
for(var j = 0, lenj = toRemove.length; j < lenj; ++j) | ||
res[toRemove[j]] = Store.forbidden(); | ||
} | ||
else | ||
{ | ||
if(!toKeep) | ||
{ | ||
toKeep = {}; | ||
for(var l = 0, lenl = allowable.length; l < lenl; ++l) | ||
toKeep[allowable[l]] = true; | ||
} | ||
for(var k in res) | ||
if(!toKeep[k]) | ||
res[k] = Store.forbidden(); | ||
} | ||
// console.log("allow only bottom : res : ", res); | ||
return res; | ||
} | ||
}; | ||
for (var i in arguments) | ||
delete restrictions[arguments[i]]; | ||
return restrictions; | ||
@@ -104,2 +184,4 @@ }; | ||
return stores; | ||
}); | ||
}); | ||
@@ -51,3 +51,3 @@ /** | ||
var errors = []; | ||
var self = this; | ||
var self = this, totalTime = 0; | ||
@@ -71,3 +71,4 @@ if(functions.length === 0) | ||
errors:errors, | ||
valid:true | ||
valid:true, | ||
time:0 | ||
}; | ||
@@ -81,12 +82,9 @@ } | ||
if(options.verbose !== false) | ||
{ | ||
console.log("\n- unit test runned : ", fn.key); | ||
if(console.time) | ||
console.time(fn.key); | ||
} | ||
closure.fn = fn; | ||
var time = new Date().getTime(); | ||
return deep.when(fn.value.call(self.context)) | ||
.always(function(s,e){ | ||
if(options.verbose !== false && console.time) | ||
console.timeEnd(fn.key); | ||
time = new Date().getTime() - time; | ||
totalTime += time; | ||
if(options.verbose !== false) | ||
@@ -96,3 +94,3 @@ if(e) | ||
else | ||
console.log("\tok !"); | ||
console.log("\tok ! ("+time+" ms)"); | ||
}); | ||
@@ -123,4 +121,2 @@ }; | ||
console.log("\tsetup done."); | ||
if(console.time) | ||
console.time("unit"); | ||
} | ||
@@ -142,4 +138,3 @@ }) | ||
console.log("\n*************", self.title, " : time ****************"); | ||
if(console.time) | ||
console.timeEnd("unit"); | ||
if(e || results.length < numberOfTests || errors.length > 0) | ||
@@ -160,2 +155,3 @@ console.warn("*************",self.title," : FAILED **************"); | ||
console.log("\tommited : ", numberOfTests-results.length,"/",numberOfTests); | ||
console.log("\ttime : ", totalTime); | ||
} | ||
@@ -183,3 +179,4 @@ return self.clean(); | ||
errors:errors, | ||
valid:((errors.length === 0) && (results.length == numberOfTests)) | ||
valid:((errors.length === 0) && (results.length == numberOfTests)), | ||
time:totalTime | ||
}; | ||
@@ -193,3 +190,6 @@ }); | ||
Unit.run = function(units, options){ | ||
options = options || {}; | ||
if(options === false) | ||
options = { verbose:false }; | ||
else | ||
options = options || {}; | ||
//if(options.verbose !== false) | ||
@@ -211,2 +211,3 @@ //{ | ||
var report = { | ||
reports:[], | ||
errors:[], | ||
@@ -217,4 +218,6 @@ numberOfUnits:units.length, | ||
failure:0, | ||
ommited:0 | ||
ommited:0, | ||
time:0 | ||
}; | ||
deep.counter = { delayCount:0 }; | ||
if(alls.length === 0) | ||
@@ -224,2 +227,3 @@ return deep.when(report); | ||
.done(function(units){ | ||
deep.context = this._context = {}; | ||
//console.log("units loaded : ", units); | ||
@@ -245,2 +249,3 @@ if(options.profile) | ||
report.errors.push(e); | ||
report.reports.push(s); | ||
report.success += s.success; | ||
@@ -251,2 +256,3 @@ report.failure += s.failure; | ||
report.errors = report.errors.concat(s.errors); | ||
report.time += s.time; | ||
results.push(s); | ||
@@ -261,3 +267,3 @@ if(units.length > 0) | ||
console.profileEnd("bunch"); | ||
report.time = new Date().getTime() - startTime; | ||
report.totalTime = new Date().getTime() - startTime; | ||
//if(options.verbose !== false) | ||
@@ -288,2 +294,3 @@ //{ | ||
console.log("\ttime : ", report.time); | ||
console.log("\ttotalTime : ", report.totalTime); | ||
//console.log(JSON.stringify(report, null, ' ')); | ||
@@ -290,0 +297,0 @@ console.log("\n*******************************************************************"); |
124
lib/utils.js
@@ -123,2 +123,45 @@ /** | ||
utils.removeInside = function(obj, toRemove){ | ||
if(!toRemove.forEach) | ||
toRemove = [toRemove]; | ||
var tr = {}, item = null, key = null; | ||
for(var i = 0, len = toRemove.length; i < len; ++i) | ||
{ | ||
item = toRemove[i]; | ||
if(typeof item === 'object') | ||
key = item.id; | ||
else | ||
key = item; | ||
tr[key] = item; | ||
} | ||
if(obj.forEach) | ||
{ | ||
for(var i = 0, len = obj.length; i < len; ++i) | ||
{ | ||
item = obj[i]; | ||
if(typeof item === 'object') | ||
key = item.id; | ||
else | ||
key = item; | ||
if(tr[key]) | ||
obj.splice(i,1); | ||
} | ||
} | ||
else | ||
{ | ||
for(var i in obj) | ||
{ | ||
item = obj[i]; | ||
if(typeof item === 'object') | ||
key = item.id; | ||
else | ||
key = i; | ||
if(tr[key]) | ||
delete obj[i]; | ||
} | ||
} | ||
return obj; | ||
}; | ||
var outputToString = function(){ | ||
@@ -640,3 +683,3 @@ return "?"+utils.toQueryString(this); | ||
if(!tmp.properties || !tmp.properties[part]) | ||
return undefined; | ||
return null; | ||
tmp = tmp.properties[part]; | ||
@@ -673,3 +716,3 @@ } | ||
if (tmp.additionalProperties === undefined || tmp.additionalProperties === false) | ||
return undefined; | ||
return null; | ||
else | ||
@@ -686,2 +729,4 @@ return tmp.additionalProperties; | ||
finalSchema = res[0]; | ||
else | ||
return null; | ||
// console.log("retrieveSchemaByPath : finally : ", path, finalSchema); | ||
@@ -907,65 +952,2 @@ | ||
utils.createNode = function staticCreateEntry(key, ancestor) | ||
{ | ||
var path = ancestor.path; | ||
if(!ancestor.key) | ||
path += key; | ||
else | ||
path += "/"+key; | ||
var schema = null; | ||
if(ancestor.schema) | ||
schema = retrieveFullSchemaByPath(ancestor.schema, key, "/"); | ||
//console.log("deep.utils.createNode : "+path+" : schema : ",schema) | ||
return { | ||
_deep_query_node_:true, | ||
root:ancestor.root, | ||
value:ancestor.value[key], | ||
path:path, | ||
paths:ancestor.paths.concat(key), | ||
key:key, | ||
ancestor:ancestor, | ||
schema:schema, | ||
depth:ancestor.depth+1 | ||
}; | ||
}; | ||
utils.cloneNode = function staticCreateEntry(node) | ||
{ | ||
//console.log("deep.utils.createNode : "+path+" : schema : ",schema) | ||
var clone = utils.simpleCopy(node); | ||
if(clone.paths) | ||
clone.paths = clone.paths.slice(); | ||
return clone; | ||
}; | ||
/** | ||
* create a root DeepQuery node | ||
* | ||
* @static | ||
* @method createRootNode | ||
* @param {Object} obj | ||
* @param {Object} schema | ||
* @return {Object} a DeepQuery root node | ||
*/ | ||
utils.createRootNode = function createRootNode(obj, schema, options) { | ||
options = options || {}; | ||
if(obj && obj._deep_undefined_) | ||
obj = undefined; | ||
var node = { | ||
_deep_query_node_:true, | ||
value:obj, | ||
path:"/", | ||
paths:[], | ||
uri:options.uri || null, | ||
key:null, | ||
ancestor:null, | ||
schema:schema, | ||
depth:0 | ||
}; | ||
node.root = node; | ||
return node; | ||
}; | ||
var setHierarchy = function addHierarchy(entry, cache, results) | ||
@@ -1021,3 +1003,3 @@ { | ||
if(!root._deep_query_node_) | ||
root = deep.utils.createRootNode(root); | ||
root = deep.nodes.root(root); | ||
stack = [root]; | ||
@@ -1063,3 +1045,3 @@ } | ||
continue; | ||
r.unshift(deep.utils.createNode(i, current)); //{ path:current.path+i+'/', value:va }); | ||
r.unshift(deep.nodes.create(i, current)); //{ path:current.path+i+'/', value:va }); | ||
} | ||
@@ -1074,3 +1056,3 @@ } | ||
continue; | ||
r.unshift(deep.utils.createNode(j, current)); | ||
r.unshift(deep.nodes.create(j, current)); | ||
} | ||
@@ -1096,3 +1078,3 @@ stack = stack.concat(r); | ||
if(!root._deep_query_node_) | ||
root = deep.utils.createRootNode(root); | ||
root = deep.nodes.root(root); | ||
stack = [root]; | ||
@@ -1135,3 +1117,3 @@ } | ||
continue; | ||
stack.unshift(deep.utils.createNode(i, current)); //{ path:current.path+i+'/', value:va }); | ||
stack.unshift(deep.nodes.create(i, current)); //{ path:current.path+i+'/', value:va }); | ||
//stack.push({ path:current.path+i+'/', value:va }); | ||
@@ -1147,3 +1129,3 @@ } | ||
continue; | ||
stack.unshift(deep.utils.createNode(j, current)); | ||
stack.unshift(deep.nodes.create(j, current)); | ||
//stack.push({ path:current.path+j+'/', value:vb }); | ||
@@ -1150,0 +1132,0 @@ } |
{ | ||
"name" : "deepjs", | ||
"version" : "0.10.15", | ||
"version" : "0.11.1", | ||
"author" : "Gilles Coomans <gilles.coomans@gmail.com>", | ||
@@ -5,0 +5,0 @@ "description" : "Powerful atomic tools for managing objects, functions and promises", |
@@ -14,2 +14,3 @@ /** | ||
console.log("report : ", report); | ||
report.reports = null; | ||
$("#reports-container").html("<pre>"+JSON.stringify(report,null, ' ')+'</pre>'); | ||
@@ -16,0 +17,0 @@ }); |
16
TODO.txt
@@ -35,3 +35,3 @@ | ||
==> .post(obj, path, ?options) || .post(obj, ?options) | ||
- homogenise .createDefault of stores | ||
- homogenise .createDefault of stores OK | ||
@@ -41,7 +41,9 @@ | ||
- refactor swig + files accessors (json) for contextualised root (maybe multiple roots) OK | ||
- add options and head http action in restful middleware. | ||
- client micro caching + cache prefix with roles OR clearCache when roles change | ||
- add options and head http action in restful middleware. OK | ||
- client micro caching + cache prefix with roles OR clearCache when roles change | ||
==> work globally on cache : deep.mediacache should manage FileWatch | ||
- manage headers in autobahn : in config + middleware(s) | ||
- manage headers in autobahn : in config + middleware(s) OK | ||
@@ -61,2 +63,4 @@ - ligth DDP for deep : | ||
Workers : | ||
1.1.0 - Finalise context and parano modes. maybe contextualised Emitter. | ||
@@ -133,4 +137,2 @@ 1.2.0 - Finalise Chain Identities Management | ||
## DOCS : | ||
@@ -144,3 +146,3 @@ | ||
And as today, the architecture itself of web app are better controled, and use clasicaly Single-Page/Restful paradygm, deepjs wants to fits particulary well as a complete ThinServer/mVC/Asynch tools belt. | ||
And as today, the architecture itself of web app are better controled, and use classical Single-Page/Restful paradygm, deepjs wants to fits particulary well as a complete ThinServer/mVC/Asynch tools belt. | ||
@@ -147,0 +149,0 @@ |
@@ -427,2 +427,23 @@ if (typeof define !== 'function') { | ||
.equal("hello"); | ||
}, | ||
classes_defaulproto:function(){ | ||
var Mc = deep.compose.Classes(function(schema){ | ||
if(schema && this.schema) | ||
deep.utils.up(schema, this.schema); | ||
}, { | ||
schema:{ | ||
bloup:true | ||
} | ||
}); | ||
var a = new Mc({ | ||
fromA:true | ||
}); | ||
var b = new Mc({ | ||
fromB:true | ||
}); | ||
return deep(a.schema) | ||
.equal({ bloup:true, fromA:true }); | ||
} | ||
@@ -429,0 +450,0 @@ } |
@@ -80,2 +80,22 @@ if (typeof define !== 'function') { | ||
return deep.all(p1,p2,p3,p4); | ||
}, | ||
delayed2:function(){ | ||
deep.context = {}; | ||
var ocm = deep.ocm({ | ||
a:{ hello:"world" }, | ||
b:{ backgrounds:["this::../a"] } | ||
}); | ||
deep.Roles("a"); | ||
deep.flatten(ocm) | ||
.delay(10) | ||
deep.roles("b") | ||
.done(function(success){ | ||
return ocm.flatten().done(function(){ | ||
console.log("Roles : ", deep.getModes()) | ||
}) | ||
}) | ||
.done(function(){ | ||
console.log("Roles : ", deep.getModes()) | ||
}) | ||
} | ||
@@ -82,0 +102,0 @@ } |
@@ -1,2 +0,2 @@ | ||
if (typeof define !== 'function') { | ||
if (typeof define !== 'function') { | ||
var define = require('amdefine')(module); | ||
@@ -31,4 +31,5 @@ } | ||
var a = { how:"test::e1" }; | ||
deep(a) | ||
return deep(a) | ||
.deepLoad(null, false) | ||
.log() | ||
.done(function(r){ | ||
@@ -42,4 +43,5 @@ return [r,a]; | ||
var a = { how:"test::e1" }; | ||
deep(a) | ||
return deep(a) | ||
.deepLoad(null, true) | ||
.log() | ||
.done(function(r){ | ||
@@ -46,0 +48,0 @@ return [r,a]; |
412
units/ocm.js
@@ -5,39 +5,44 @@ if (typeof define !== 'function') { | ||
define(["require","../deep"], function (require, deep, Unit) { | ||
define(["require", "../deep"], function(require, deep, Unit) { | ||
//_______________________________________________________________ GENERIC STORE TEST CASES | ||
var unit = { | ||
title:"deep/units/ocm", | ||
tests : { | ||
base:function(){ | ||
title: "deep/units/ocm", | ||
tests: { | ||
base: function() { | ||
var myManager = deep.ocm({ | ||
mode1:{ | ||
test:1 | ||
mode1: { | ||
test: 1 | ||
}, | ||
mode2:{ | ||
test:2, | ||
title:"hello world" | ||
mode2: { | ||
test: 2, | ||
title: "hello world" | ||
}, | ||
mode3:{ | ||
backgrounds:["this::../mode2"], | ||
description:"mode 3 description" | ||
mode3: { | ||
backgrounds: ["this::../mode2"], | ||
description: "mode 3 description" | ||
} | ||
}); | ||
myManager.flatten(); // seek and apply backgrounds | ||
return deep.when([myManager("mode1"),myManager("mode2"), myManager("mode3")]).equal( | ||
[ | ||
{ test:1 }, | ||
{ test:2, title:"hello world"}, | ||
{ test:2, title:"hello world", description:"mode 3 description"} | ||
] | ||
return deep.when([myManager("mode1"), myManager("mode2"), myManager("mode3")]).equal( | ||
[{ | ||
test: 1 | ||
}, { | ||
test: 2, | ||
title: "hello world" | ||
}, { | ||
test: 2, | ||
title: "hello world", | ||
description: "mode 3 description" | ||
}] | ||
); | ||
}, | ||
currentMode:function(){ | ||
}, | ||
currentMode: function() { | ||
var myManager = deep.ocm({ | ||
mode1:{ | ||
title:"should not see this" | ||
mode1: { | ||
title: "should not see this" | ||
}, | ||
mode2:{ | ||
title:"hello world" | ||
mode2: { | ||
title: "hello world" | ||
} | ||
@@ -47,72 +52,98 @@ }); | ||
return deep.when(myManager()) | ||
.equal({ title:"hello world" }); | ||
.equal({ | ||
title: "hello world" | ||
}); | ||
}, | ||
modeCollection:function(){ | ||
modeCollection: function() { | ||
var myManager = deep.ocm({ | ||
mode1:{ | ||
test:1 | ||
mode1: { | ||
test: 1 | ||
}, | ||
mode2:{ | ||
title:"hello world" | ||
mode2: { | ||
title: "hello world" | ||
} | ||
}); | ||
return deep.when([myManager("mode1", "mode2"), myManager("mode2", "mode1")]) | ||
.equal([ { test:1, title:"hello world"}, { title:"hello world", test:1 }]); | ||
.equal([{ | ||
test: 1, | ||
title: "hello world" | ||
}, { | ||
title: "hello world", | ||
test: 1 | ||
}]); | ||
}, | ||
setGroup:function() | ||
{ | ||
setGroup: function() { | ||
var myManager = deep.ocm({ | ||
mode1:{ | ||
test:1 | ||
mode1: { | ||
test: 1 | ||
}, | ||
mode2:{ | ||
title:"hello world" | ||
mode2: { | ||
title: "hello world" | ||
} | ||
}); | ||
myManager.group("myGroup"); | ||
return deep.modes({ "myGroup":"mode1" }) // start a chain with provided modes | ||
return deep.modes({ | ||
"myGroup": "mode1" | ||
}) // start a chain with provided modes | ||
.delay(1) | ||
.done(function(success){ | ||
return myManager(); | ||
}) | ||
.equal({test:1}) | ||
.modes({ "myGroup":"mode2"} ) | ||
.delay(1) | ||
.done(function(success){ | ||
return myManager(); | ||
}) | ||
.equal({ title:"hello world"}); | ||
.done(function(success) { | ||
return myManager(); | ||
}) | ||
.equal({ | ||
test: 1 | ||
}) | ||
.modes({ | ||
"myGroup": "mode2" | ||
}) | ||
.delay(1) | ||
.done(function(success) { | ||
return myManager(); | ||
}) | ||
.equal({ | ||
title: "hello world" | ||
}); | ||
}, | ||
groupCollection:function(){ | ||
groupCollection: function() { | ||
return deep.modes({ | ||
group1:"mode1" | ||
group1: "mode1" | ||
}) | ||
.done(function(success){ | ||
return deep.modes({ group2:"mode2" }) | ||
.done(function(success) { | ||
return deep.modes({ | ||
group2: "mode2" | ||
}) | ||
.delay(1) | ||
.done(function(success) { | ||
return deep.context.modes; | ||
}) | ||
.equal({ | ||
group1: "mode1", | ||
group2: "mode2" | ||
}); | ||
}) | ||
.delay(1) | ||
.done(function(success){ | ||
.done(function(success) { | ||
return deep.context.modes; | ||
}) | ||
.equal({ group1:"mode1", group2:"mode2" }); | ||
}) | ||
.delay(1) | ||
.done(function(success){ | ||
return deep.context.modes; | ||
}) | ||
.equal({ group1:"mode1" }); | ||
.equal({ | ||
group1: "mode1" | ||
}); | ||
}, | ||
shared:function(){ | ||
shared: function() { | ||
var obj = deep.ocm({ | ||
mode1:{ | ||
myShared:deep.Shared([1,2,3]), | ||
myShared2:deep.Shared({ a:1 }) | ||
mode1: { | ||
myShared: deep.Shared([1, 2, 3]), | ||
myShared2: deep.Shared({ | ||
a: 1 | ||
}) | ||
}, | ||
mode2:{ | ||
backgrounds:["this::../mode1"], | ||
myShared:[4,5], | ||
myShared2:{ b:2 } | ||
mode2: { | ||
backgrounds: ["this::../mode1"], | ||
myShared: [4, 5], | ||
myShared2: { | ||
b: 2 | ||
} | ||
} | ||
}); | ||
return obj.flatten().done(function(obj){ | ||
return obj.flatten().done(function(obj) { | ||
obj("mode1").myShared.push(6); | ||
@@ -122,114 +153,215 @@ obj("mode1").myShared2.c = 3; | ||
}) | ||
.equal([ | ||
{ myShared:[1,2,3,4,5,6], myShared2:{ a:1, _deep_shared_:true, b:2, c:3}}, | ||
{ myShared:[1,2,3,4,5,6], myShared2:{ a:1, _deep_shared_:true, b:2, c:3}} | ||
]); | ||
.equal([{ | ||
myShared: [1, 2, 3, 4, 5, 6], | ||
myShared2: { | ||
a: 1, | ||
_deep_shared_: true, | ||
b: 2, | ||
c: 3 | ||
} | ||
}, { | ||
myShared: [1, 2, 3, 4, 5, 6], | ||
myShared2: { | ||
a: 1, | ||
_deep_shared_: true, | ||
b: 2, | ||
c: 3 | ||
} | ||
}]); | ||
}, | ||
cross_inheritance:function(){ | ||
cross_inheritance: function() { | ||
var a = { | ||
b:deep.ocm({ | ||
backgrounds:["this::../brol"], | ||
role:true | ||
b: deep.ocm({ | ||
backgrounds: ["this::../brol"], | ||
role: true | ||
}), | ||
brol:{ | ||
role2:false | ||
brol: { | ||
role2: false | ||
} | ||
}; | ||
deep.flatten(a); | ||
return deep([a.b("role2"),a.b("role")]).equal([false,true]); | ||
return deep([a.b("role2"), a.b("role")]).equal([false, true]); | ||
}, | ||
multiGroup:function(){ | ||
multiGroup: function() { | ||
var o = deep.ocm({ | ||
dev:{ | ||
get:function(arg){ | ||
return "dev:"+arg; | ||
dev: { | ||
get: function(arg) { | ||
return "dev:" + arg; | ||
} | ||
}, | ||
prod:{ | ||
get:function(arg){ | ||
return "prod:"+arg; | ||
prod: { | ||
get: function(arg) { | ||
return "prod:" + arg; | ||
} | ||
}, | ||
"public":{ | ||
get:deep.compose.after(function(s){ | ||
return s+":public"; | ||
"public": { | ||
get: deep.compose.after(function(s) { | ||
return s + ":public"; | ||
}) | ||
}, | ||
admin:{ | ||
get:deep.compose.after(function(s){ | ||
return s+":admin"; | ||
admin: { | ||
get: deep.compose.after(function(s) { | ||
return s + ":admin"; | ||
}) | ||
} | ||
}, { group:["env", "roles"]}); | ||
}, { | ||
group: ["env", "roles"] | ||
}); | ||
return deep.modes({ | ||
env:"dev", | ||
roles:"public" | ||
env: "dev", | ||
roles: "public" | ||
}) | ||
.done(function(){ | ||
return o().get("hello"); | ||
}) | ||
.equal("dev:hello:public"); | ||
.done(function() { | ||
return o().get("hello"); | ||
}) | ||
.equal("dev:hello:public"); | ||
}, | ||
multiGroup2:function(){ | ||
multiGroup2: function() { | ||
var o = deep.ocm({ | ||
dev:{ | ||
get:function(arg){ | ||
return "dev:"+arg; | ||
dev: { | ||
get: function(arg) { | ||
return "dev:" + arg; | ||
} | ||
}, | ||
prod:{ | ||
get:function(arg){ | ||
return "prod:"+arg; | ||
prod: { | ||
get: function(arg) { | ||
return "prod:" + arg; | ||
} | ||
}, | ||
"public":{ | ||
get:deep.compose.after(function(s){ | ||
return s+":public"; | ||
"public": { | ||
get: deep.compose.after(function(s) { | ||
return s + ":public"; | ||
}) | ||
}, | ||
admin:{ | ||
get:deep.compose.after(function(s){ | ||
return s+":admin"; | ||
admin: { | ||
get: deep.compose.after(function(s) { | ||
return s + ":admin"; | ||
}) | ||
} | ||
}, { group:["env", "roles"]}); | ||
}, { | ||
group: ["env", "roles"] | ||
}); | ||
return deep.modes({ | ||
env:"prod" | ||
env: "prod", | ||
roles:"admin" | ||
}) | ||
.done(function(){ | ||
.done(function() { | ||
return o().get("hello"); | ||
}) | ||
.equal("prod:hello"); | ||
.equal("prod:hello:admin"); | ||
}, | ||
ocm_sheets:function(){ | ||
ocm_sheets: function() { | ||
var o = deep.ocm({ | ||
"public":{ | ||
get:function(s){ | ||
return "public:"+s; | ||
"public": { | ||
get: function(s) { | ||
return "public:" + s; | ||
} | ||
}, | ||
prod:deep.Sheet({ | ||
"dq.up::./get":deep.compose.after(function(s){ | ||
return s+":prod"; | ||
prod: deep.Sheet({ | ||
"dq.up::./get": deep.compose.after(function(s) { | ||
return s + ":prod"; | ||
}) | ||
}), | ||
dev:deep.Sheet({ | ||
"dq.up::./get":deep.compose.before(function(s){ | ||
return "dev:"+s; | ||
dev: deep.Sheet({ | ||
"dq.up::./get": deep.compose.before(function(s) { | ||
return "dev:" + s; | ||
}) | ||
}) | ||
}, { groups:["roles","env"], applySheets:true }); | ||
return deep.modes({ env:"dev", roles:"public" }) | ||
.done(function(){ | ||
return o().get("hello"); | ||
}, { | ||
groups: ["roles", "env"] | ||
}); | ||
return deep.modes({ | ||
env: "dev", | ||
roles: "public" | ||
}) | ||
.equal("public:dev:hello") | ||
.modes({ env:"prod", roles:"public" }) | ||
.done(function(){ | ||
return o().get("hello"); | ||
}) | ||
.equal("public:hello:prod"); | ||
} | ||
.done(function() { | ||
return o().get("hello"); | ||
}) | ||
.equal("public:dev:hello") | ||
.modes({ | ||
env: "prod", | ||
roles: "public" | ||
}) | ||
.done(function() { | ||
return o().get("hello"); | ||
}) | ||
.equal("public:hello:prod"); | ||
}, | ||
ocm_afterCompilation: function() { | ||
var manager = deep.ocm({ | ||
mode1: { | ||
name: "John", | ||
familly: "Doe" | ||
}, | ||
mode2: { | ||
name: "Herbert", | ||
familly: "Laevus" | ||
} | ||
}, { | ||
afterCompilation: function(result) { | ||
return result.name + result.familly; | ||
} | ||
}); | ||
var res = [ | ||
manager("mode1"), // "JohnDoe" | ||
manager("mode1"), // object | ||
manager("mode1"), // object | ||
manager("mode1", "mode2"), // "HerbertLaevus" | ||
manager("mode1", "mode2"), // object | ||
manager("mode1", "mode2"), // object | ||
manager("mode2", "mode1"), // "JohnDoe" | ||
manager("mode2", "mode1"), // object | ||
manager("mode2", "mode1"), // object | ||
manager("mode1") // object | ||
]; | ||
return deep(res) | ||
.equal(["JohnDoe", { | ||
name: "John", | ||
familly: "Doe" | ||
}, { | ||
name: "John", | ||
familly: "Doe" | ||
}, | ||
"HerbertLaevus", { | ||
name: "Herbert", | ||
familly: "Laevus" | ||
}, { | ||
name: "Herbert", | ||
familly: "Laevus" | ||
}, "JohnDoe", { | ||
name: "John", | ||
familly: "Doe" | ||
}, { | ||
name: "John", | ||
familly: "Doe" | ||
}, { | ||
name: "John", | ||
familly: "Doe" | ||
}]); | ||
}, | ||
ocm_strict:function(){ | ||
var myManager = deep.ocm({ | ||
dev:{ dev:true }, | ||
prod:{ prod:true }, | ||
"public":{ "public":true }, | ||
admin:{ admin:true } | ||
}, { strict:true }); | ||
return deep(myManager("prod", "bloup")) | ||
.equal({}) | ||
}, | ||
multiModesFalse:function(){ | ||
var myManager = deep.ocm({ | ||
"public":{ "public":true }, | ||
"user":{ "user":true } | ||
}, { multiModes:false }); | ||
return deep(myManager("public", "user")) | ||
.equal({}); | ||
}, | ||
} | ||
@@ -239,2 +371,2 @@ }; | ||
return unit; | ||
}); | ||
}); |
@@ -85,2 +85,76 @@ if (typeof define !== 'function') { | ||
.equal("lolipop"); | ||
}, | ||
allow_only_up:function(){ | ||
var obj = { | ||
a:true, | ||
b:"hello", | ||
c:function(){ | ||
return "hello"; | ||
} | ||
} | ||
obj = deep.utils.up(deep.store.AllowOnly("b"), obj); | ||
var a,b,c; | ||
try{ | ||
a = obj.a().status; | ||
b = obj.b; | ||
c = obj.c().status; | ||
} | ||
catch(e) | ||
{ | ||
} | ||
var r = [a, b, c]; | ||
return deep(r) | ||
.equal([403, "hello", 403]) | ||
}, | ||
allow_only_backgrounds:function(){ | ||
var obj = { | ||
a:true, | ||
b:"hello", | ||
c:function(){ | ||
return "hello"; | ||
} | ||
} | ||
var obj2 = { | ||
backgrounds:[obj, deep.store.AllowOnly("b")] | ||
} | ||
deep.flatten(obj2); | ||
var a,b,c; | ||
try{ | ||
a = obj2.a().status; | ||
b = obj2.b; | ||
c = obj2.c().status; | ||
} | ||
catch(e) | ||
{ | ||
} | ||
var r = [a, b, c]; | ||
return deep(r) | ||
.equal([403, "hello", 403]) | ||
}, | ||
allow_only_backgrounds2:function(){ | ||
var obj = { | ||
backgrounds:[deep.store.AllowOnly("b")], | ||
a:true, | ||
b:"hello", | ||
c:function(){ | ||
return "world"; | ||
} | ||
} | ||
deep.flatten(obj); | ||
var a,b,c, d; | ||
try{ | ||
a = obj.a; | ||
b = obj.b; | ||
c = obj.c(); | ||
} | ||
catch(e) | ||
{ | ||
} | ||
var r = [a, b, c]; | ||
return deep(r) | ||
.equal([true, "hello", "world"]) | ||
} | ||
@@ -87,0 +161,0 @@ } |
@@ -5,3 +5,3 @@ if (typeof define !== 'function') { | ||
define(["require","../deep", "../lib/unit"], function (require, deep, Unit) { | ||
define(["require","../deep"], function (require, deep) { | ||
@@ -182,3 +182,2 @@ //_______________________________________________________________ GENERIC STORE TEST CASES | ||
}; | ||
var obj = { | ||
@@ -188,5 +187,211 @@ backgrounds:[{ lolipop:true }], | ||
}; | ||
deep.sheet(sheet, obj); | ||
return deep(obj).equal({ hello:"world", lolipop:true, a:true }); | ||
}, | ||
sheets_as_backgrounds:function(){ | ||
return deep({ | ||
test:false, | ||
backgrounds:[{ | ||
_deep_sheet_:true, | ||
"dq.bottom::./!":{ | ||
hello:"world" | ||
} | ||
}] | ||
}) | ||
.flatten() | ||
.equal({ | ||
test:false | ||
}); | ||
}, | ||
sheets_as_backgrounds2:function(){ | ||
return deep({ | ||
_deep_sheet_:true, | ||
"dq.up::./!":"testez", | ||
"dq.bottom::./!":{ test:true }, | ||
backgrounds:[{ | ||
_deep_sheet_:true, | ||
"dq.bottom::./!":{ | ||
hello:"world" | ||
} | ||
}] | ||
}) | ||
.flatten() | ||
.equal({ | ||
_deep_sheet_:true, | ||
"dq.bottom::./!":{ hello:"world" , test:true }, | ||
"dq.up::./!":"testez", | ||
}); | ||
}, | ||
sheets_as_backgrounds3:function(){ | ||
return deep({ | ||
test:false, | ||
backgrounds:[{ | ||
base:"yes" | ||
}, { | ||
_deep_sheet_:true, | ||
"dq.bottom::./!":{ | ||
hello:"world" | ||
} | ||
}] | ||
}) | ||
.flatten() | ||
.equal({ | ||
hello:"world", | ||
base:"yes", | ||
test:false | ||
}); | ||
}, | ||
sheets_as_backgrounds4:function(){ | ||
return deep({ | ||
_deep_sheet_:true, | ||
"dq.up::./!":{ fromUp:true }, | ||
"dq.bottom::./!":{ fromBottom:true }, | ||
backgrounds:[{ | ||
hello:"world" | ||
}] | ||
}) | ||
.flatten() | ||
.equal({ | ||
fromBottom:true, | ||
hello:"world", | ||
fromUp:true | ||
}); | ||
}, | ||
sheets_as_backgrounds_twice:function(){ | ||
return deep({ | ||
test:false, | ||
backgrounds:[{ | ||
base:"yes" | ||
}, { | ||
_deep_sheet_:true, | ||
"dq.bottom::./!":{ | ||
backgrounds:[{ doubleBack:true }], | ||
hello:"world" | ||
} | ||
}] | ||
}) | ||
.flatten() | ||
.equal({ | ||
doubleBack:true, | ||
hello:"world", | ||
base:"yes", | ||
test:false | ||
}); | ||
}, | ||
sheet_up_object:function(){ | ||
var a = deep.utils.up({ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"world" } | ||
}, { bloup:true }); | ||
return deep(a).equal({ | ||
hello:"world", | ||
bloup:true | ||
}); | ||
}, | ||
sheet_bottom_object:function(){ | ||
var a = deep.utils.bottom({ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"world" } | ||
}, { bloup:true }); | ||
return deep(a).equal({ | ||
bloup:true | ||
}); | ||
}, | ||
object_bottom_sheet:function(){ | ||
var a = deep.utils.bottom({ bloup:true }, { | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"world" } | ||
}); | ||
return deep(a).equal({ | ||
hello:"world", | ||
bloup:true | ||
}); | ||
}, | ||
object_up_sheet:function(){ | ||
var a = deep.utils.up({ bloup:true }, { | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"world" } | ||
}); | ||
return deep(a).equal({ | ||
bloup:true | ||
}); | ||
}, | ||
sheet_up_sheet:function(){ | ||
var a = deep.utils.up({ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ bloup:true } | ||
},{ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"world" } | ||
}); | ||
return deep(a).equal({ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ | ||
hello:"world", | ||
bloup:true | ||
} | ||
}); | ||
}, | ||
sheet_bottom_sheet:function(){ | ||
var a = deep.utils.bottom({ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ bloup:true } | ||
},{ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"world" } | ||
}); | ||
return deep(a).equal({ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ | ||
bloup:true, | ||
hello:"world" | ||
} | ||
}); | ||
}, | ||
sheets_in_classes:function(){ | ||
var C = deep.compose.Classes(function(){ | ||
}, { | ||
test:false | ||
}, | ||
{ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"tulip" } | ||
}); | ||
return deep(new C()) | ||
.equal({ | ||
hello:"tulip", | ||
test:false | ||
}); | ||
}, | ||
sheets_in_compile:function(){ | ||
var c = deep.compile({ | ||
test:false | ||
}, | ||
{ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"tulip" } | ||
}, { yop:14 }); | ||
return deep(c) | ||
.equal({ | ||
hello:"tulip", | ||
test:false, | ||
yop:14 | ||
}); | ||
}, | ||
sheets_entry:function(){ | ||
var a = { | ||
sheets:[{ | ||
_deep_sheet_:true, | ||
"dq.bottom::.//!":{ hello:"tulip" } | ||
}], | ||
bloup:true | ||
}; | ||
return deep(a).flatten() | ||
.equal({ | ||
hello:"tulip", | ||
bloup:true | ||
}); | ||
} | ||
@@ -193,0 +398,0 @@ } |
@@ -34,2 +34,92 @@ if (typeof define !== 'function') { | ||
.equal("jos&jos=2&a.bloup=3"); | ||
}, | ||
removeInside_obj_keys:function(){ | ||
var r = deep.utils.removeInside({ | ||
a:true, | ||
b:24, | ||
c:"hello" | ||
}, ["a", "c"]) | ||
return deep(r) | ||
.equal({ b:24 }); | ||
}, | ||
removeInside_obj_obj:function(){ | ||
var r = deep.utils.removeInside({ | ||
a:{ | ||
id:"anything" | ||
}, | ||
b:{ | ||
id:"anything2" | ||
}, | ||
c:"hello" | ||
}, { id:"anything" }) | ||
return deep(r) | ||
.equal({ | ||
b:{ | ||
id:"anything2" | ||
}, | ||
c:"hello" | ||
}); | ||
}, | ||
removeInside_obj_obj_key:function(){ | ||
var r = deep.utils.removeInside({ | ||
a:{ | ||
id:"anything" | ||
}, | ||
b:{ | ||
id:"anything2" | ||
}, | ||
c:"hello" | ||
}, [{ id:"anything"}, "c"]) | ||
return deep(r) | ||
.equal({ | ||
b:{ | ||
id:"anything2" | ||
} | ||
}); | ||
}, | ||
removeInside_arr_key:function(){ | ||
var r = deep.utils.removeInside([ | ||
"thus", | ||
"bloup", | ||
"hello" | ||
], ["thus", "hello"]) | ||
return deep(r) | ||
.equal([ | ||
"bloup" | ||
]); | ||
}, | ||
removeInside_arr_obj:function(){ | ||
var r = deep.utils.removeInside([ | ||
{ | ||
id:"anything" | ||
}, | ||
{ | ||
id:"anything2" | ||
}, | ||
"hello" | ||
], { id:"anything"}) | ||
return deep(r) | ||
.equal([ | ||
{ | ||
id:"anything2" | ||
}, | ||
"hello" | ||
]); | ||
}, | ||
removeInside_arr_obj_key:function(){ | ||
var r = deep.utils.removeInside([ | ||
{ | ||
id:"anything" | ||
}, | ||
{ | ||
id:"anything2" | ||
}, | ||
"hello" | ||
], [{ id:"anything"}, "hello"]) | ||
return deep(r) | ||
.equal([ | ||
{ | ||
id:"anything2" | ||
} | ||
]); | ||
} | ||
@@ -36,0 +126,0 @@ } |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
AI-detected potential security risk
Supply chain riskAI has determined that this package may contain potential security issues or vulnerabilities.
Found 1 instance in 1 package
758549
111
17243
5
7