anchor
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -1,19 +0,2 @@ | ||
module.exports = { | ||
'custom': true, | ||
'isAfter': true, | ||
'isBefore': true, | ||
'isCreditCard': true, | ||
'isEmail': true, | ||
'isHexColor': true, | ||
'isIn': true, | ||
'isInteger': true, | ||
'isIP': true, | ||
'isNotIn': true, | ||
'isURL': true, | ||
'isUUID': true, | ||
'max': true, | ||
'min': true, | ||
'maxLength': true, | ||
'minLength': true, | ||
'regex': true | ||
}; | ||
var _ = require('@sailshq/lodash'); | ||
module.exports = require('../lib/rules'); |
285
index.js
@@ -9,2 +9,4 @@ /** | ||
var rules = require('./lib/rules'); | ||
var match = require('./lib/match'); | ||
@@ -16,47 +18,4 @@ | ||
module.exports = function (entity) { | ||
return new Anchor(entity); | ||
}; | ||
module.exports = function (entity, ruleset) { | ||
/** | ||
* Constructor of individual instance of Anchor | ||
* Specify the function, object, or list to be anchored | ||
*/ | ||
function Anchor (entity) { | ||
if (util.isFunction(entity)) { | ||
this.fn = entity; | ||
throw new Error ('Anchor does not support functions yet!'); | ||
} | ||
else { | ||
this.data = entity; | ||
} | ||
return this; | ||
} | ||
/** | ||
* Built-in data type rules | ||
*/ | ||
Anchor.prototype.rules = require('./lib/match/rules'); | ||
/** | ||
* Enforce that the data matches the specified ruleset | ||
*/ | ||
Anchor.prototype.to = function (ruleset, context) { | ||
var errors = []; | ||
@@ -70,42 +29,22 @@ | ||
if (rule === 'type') { | ||
// Normalize the value if it looks like a boolean | ||
if(ruleset[rule] === 'true') { | ||
ruleset[rule] = true; | ||
} | ||
// Use deep match to descend into the collection and verify each item and/or key | ||
// Stop at default maxDepth (50) to prevent infinite loops in self-associations | ||
errors = errors.concat(Anchor.match.type.call(context, this.data, ruleset.type)); | ||
if(ruleset[rule] === 'false') { | ||
ruleset[rule] = false; | ||
} | ||
// Validate a dbType rule | ||
else if (rule === 'dbType') { | ||
// only if a validation rule exists for it so it doesn't break on an adapter that | ||
// doesn't support the particular dbType | ||
if(Anchor.prototype.rules[ruleset.dbType]) { | ||
errors = errors.concat(Anchor.match.type.call(context, this.data, ruleset.dbType)); | ||
} | ||
// If the value is false, then we shouldn't even run the validation | ||
if(ruleset[rule] === false) { | ||
break; | ||
} | ||
// Validate a non-type rule | ||
else { | ||
// Normalize the value if it looks like a boolean | ||
if(ruleset[rule] === 'true') { | ||
ruleset[rule] = true; | ||
} | ||
if(ruleset[rule] === 'false') { | ||
ruleset[rule] = false; | ||
} | ||
// If the value is false, then we shouldn't even run the validation | ||
if(ruleset[rule] === false) { | ||
break; | ||
} | ||
// If the rule value is a boolean we don't need to pass the value along. | ||
// Otherwise we can pass it along so it's options are available in | ||
// the validation. | ||
var ruleVal = _.isBoolean(ruleset[rule]) ? undefined : ruleset[rule]; | ||
errors = errors.concat(Anchor.match.rule.call(context, this.data, rule, ruleVal)); | ||
} | ||
// If the rule value is a boolean we don't need to pass the value along. | ||
// Otherwise we can pass it along so it's options are available in | ||
// the validation. | ||
var ruleVal = _.isBoolean(ruleset[rule]) ? undefined : ruleset[rule]; | ||
errors = errors.concat(match(entity, rule, ruleVal)); | ||
} | ||
@@ -120,192 +59,6 @@ | ||
else { | ||
return false; | ||
return []; | ||
} | ||
}; | ||
Anchor.prototype.hasErrors = Anchor.prototype.to; | ||
/** | ||
* Coerce the data to the specified ruleset if possible | ||
* otherwise throw an error | ||
* Priority: this should probably provide the default | ||
* implementation in Waterline core. Currently it's completely | ||
* up to the adapter to define type coercion. | ||
* | ||
* Which is fine!.. but complicates custom CRUD adapter development. | ||
* Much handier would be an evented architecture, that allows | ||
* for adapter developers to write: | ||
* | ||
{ | ||
// Called before find() receives criteria | ||
// Here, criteria refers to just attributes (the `where`) | ||
// limit, skip, and sort are not included | ||
coerceCriteria: function (criteria) { | ||
return criteria; | ||
}, | ||
// Called before create() or update() receive values | ||
coerceValues: function () {} | ||
} | ||
* | ||
* Adapter developers would be able to use Anchor.prototype.cast() | ||
* to declaritively define these type coercions. | ||
* Down the line, we could take this further for an even nicer API, | ||
* but for now, this alone would be a nice improvement. | ||
* | ||
*/ | ||
Anchor.prototype.cast = function (ruleset) { | ||
todo(); | ||
}; | ||
/** | ||
* Coerce the data to the specified ruleset no matter what | ||
*/ | ||
Anchor.prototype.hurl = function (ruleset) { | ||
// Iterate trough given data attributes | ||
// to check if they exist in the ruleset | ||
for (var attr in this.data) { | ||
if (this.data.hasOwnProperty(attr)) { | ||
// If it doesnt... | ||
if (!ruleset[attr]) { | ||
// Declaring err here as error helpers live in match.js | ||
var err = new Error('Validation error: Attribute \"' + attr + '\" is not in the ruleset.'); | ||
// just throw it | ||
throw err; | ||
} | ||
} | ||
} | ||
// Once we make sure that attributes match | ||
// we can just proceed to deepMatch | ||
Anchor.match(this.data, ruleset, this); | ||
}; | ||
/** | ||
* Specify default values to automatically populated when undefined | ||
*/ | ||
Anchor.prototype.defaults = function (ruleset) { | ||
todo(); | ||
}; | ||
/** | ||
* Declare a custom data type | ||
* If function definition is specified, `name` is required. | ||
* Otherwise, if dictionary-type `definition` is specified, | ||
* `name` must not be present. | ||
* | ||
* @param {String} name [optional] | ||
* @param {Object|Function} definition | ||
*/ | ||
Anchor.prototype.define = function (name, definition) { | ||
// check to see if we have an dictionary | ||
if ( util.isObject(name) ) { | ||
// if so all the attributes should be validation functions | ||
for (var attr in name) { | ||
if(!util.isFunction(name[attr])){ | ||
throw new Error('Definition error: \"' + attr + '\" does not have a definition'); | ||
} | ||
} | ||
// add the new custom data types | ||
util.extend(Anchor.prototype.rules, name); | ||
return this; | ||
} | ||
if ( util.isFunction(definition) && util.isString(name) ) { | ||
// Add a single data type | ||
Anchor.prototype.rules[name] = definition; | ||
return this; | ||
} | ||
throw new Error('Definition error: \"' + name + '\" is not a valid definition.'); | ||
}; | ||
/** | ||
* Specify custom ruleset | ||
*/ | ||
Anchor.prototype.as = function (ruleset) { | ||
todo(); | ||
}; | ||
/** | ||
* Specify named arguments and their rulesets as an object | ||
*/ | ||
Anchor.prototype.args = function (args) { | ||
todo(); | ||
}; | ||
/** | ||
* Specify each of the permitted usages for this function | ||
*/ | ||
Anchor.prototype.usage = function () { | ||
var usages = util.toArray(arguments); | ||
todo(); | ||
}; | ||
/** | ||
* Deep-match a complex collection or model against a schema | ||
*/ | ||
Anchor.match = require('./lib/match'); | ||
/** | ||
* Expose `define` so it can be used globally | ||
*/ | ||
module.exports.define = Anchor.prototype.define; | ||
function todo() { | ||
throw new Error('Not implemented yet! If you\'d like to contribute, tweet @mikermcneil.'); | ||
} |
{ | ||
"name": "anchor", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Recursive validation library with support for objects and lists", | ||
@@ -5,0 +5,0 @@ "homepage": "http://sailsjs.org", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
14634
9
289
1