Socket
Socket
Sign inDemoInstall

anchor

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

anchor - npm Package Compare versions

Comparing version 0.2.0 to 0.2.1

lib/match.js

126

index.js

@@ -24,3 +24,3 @@ var _ = require('underscore');

// Built-in data type rules
Anchor.prototype.rules = require('./rules');
Anchor.prototype.rules = require('./lib/rules');

@@ -31,11 +31,10 @@ // Enforce that the data matches the specified ruleset

Anchor.prototype.to = function (ruleset, cb) {
var self = this;
// If callback is specififed, trigger it at the end
// also, handle error instead of throwing it
if (cb) self.cb = cb;
if (cb) this.cb = cb;
// 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
Anchor.deepMatch(self.data, ruleset, self);
Anchor.match(this.data, ruleset, this);

@@ -45,3 +44,3 @@ // If a callback was specified, trigger it

// (otherwise we never should have made it this far, the error should have been thrown)
cb && cb(self.error);
cb && cb(this.error);
};

@@ -87,120 +86,7 @@

// Deep-match a complex collection or model against a schema
Anchor.match = require('./lib/match.js');
// Return whether a piece of data matches a rule
// ruleName :: (STRING)
Anchor.match = function match (datum, ruleName, ctx) {
try {
var outcome, rule;
// Determine rule
if (_.isEqual(ruleName,[])) {
// [] specified as data type checks for an array
rule = _.isArray;
}
else if (_.isEqual(ruleName,{})) {
// {} specified as data type checks for any object
rule = _.isObject;
}
else if (_.isRegExp(ruleName)) {
// Allow regexes to be used
rule = function (x) {
if (!_.isString(x)) return false;
x.match(ruleName);
};
}
else rule = Anchor.prototype.rules[ruleName];
// Determine outcome
if (!rule) {
throw new Error ('Unknown rule: ' + ruleName);
}
else outcome = rule(datum);
// False outcome is a failure
if (!outcome) return failure(datum,ruleName);
else return outcome;
}
catch (e) {
failure(datum, ruleName);
}
// On failure-- stop and get out.
// If a cb was specified, call it with a first-arity error object.
// Otherwise, throw an error.
function failure(datum, ruleName) {
// Construct error
var err = new Error ('Validation error: "'+datum+'" is not of type "'+ruleName+'"');
// Handle the error in callback instead of throwing it
if (ctx.cb) {
ctx.error = err;
return false;
}
// Or throw error if there was no callback
else throw err;
}
};
// Match a complex collection or model against a schema
Anchor.deepMatch = function deepMatch (data, ruleset, ctx, depth, maxDepth) {
// If ruleset is not an object or array, use the provided function to validate
if (!_.isObject(ruleset)) {
return Anchor.match(data,ruleset,ctx);
}
// Default value for maxDepth and depth
maxDepth = maxDepth || 50;
depth = depth || 0;
if (depth > maxDepth) {
throw new Error ('Depth of object being parsed exceeds maxDepth (). Maybe it links to itself?');
}
// If this is a schema rule, check each item in the data collection
if (_.isArray(ruleset) && ruleset.length !== 0) {
if (ruleset.length > 1) {
throw new Error ('[] (or schema) rules can contain only one item.');
}
// Handle plurals (arrays with a schema rule)
return _.all(data, matchArray);
}
// If the current rule is an object, check each key
else if (!_.isArray(ruleset) && _.isObject(ruleset)) {
// Don't treat empty object as a ruleset
if (_.keys(ruleset).length === 0) {
return Anchor.match(data, ruleset, ctx);
}
else return _.all(ruleset,matchDict);
}
// Leaf rules land here and execute the iterator
else return Anchor.match(data, ruleset, ctx);
// Iterate through rules in dictionary until error is detected
function matchDict(subRule,key) {
if (ctx && ctx.error) return false;
else return Anchor.deepMatch(data[key], ruleset[key], ctx, depth+1);
}
// Match each object in array against ruleset until error is detected
function matchArray(model) {
if (ctx && ctx.error) return false;
else return Anchor.deepMatch(model, ruleset[0], ctx, depth+1);
}
};
function todo() {
throw new Error("Not implemented yet! If you'd like to contribute, tweet @mikermcneil.");
}
{
"name": "anchor",
"version": "0.2.0",
"version": "0.2.1",
"description": "Recursive validation library with support for objects and lists",

@@ -21,4 +21,5 @@ "main": "index.js",

"validator": "~0.4.22",
"underscore": "~1.4.3"
"underscore": "~1.4.3",
"async": "~0.2.6"
}
}

@@ -44,6 +44,6 @@ anchor

// If you want to handle the error instead of throwing it, add .error
anchor('something').to("string").error(function (err) {
// If you want to handle the error instead of throwing it, use a callback
anchor('something').to("string", function (err) {
// Err is an error object with a subset of the original data that didn't pass
// Specifying .error will prevent an error from being thrown
// Specifying a callback will prevent an error from being thrown
});

@@ -84,2 +84,3 @@

<!--
## Custom rules

@@ -178,3 +179,3 @@

// You can use the same .error notation from above in your definition to handle the error yourself
// You can use the same callback from above in your definition to handle the error yourself
$.get = anchor($.get).usage(

@@ -184,4 +185,4 @@ ['urlish',{}, 'function'],

['urlish',{}],
['urlish']
).error(function (err) {
['urlish'],
function (err) {
// Do something about the error here

@@ -237,13 +238,4 @@ });

<!--
> The api will have to change a bit here, so omitting this part for now.
Or even use deferred object notation!
```
$.getById.url('/user').id(3).done(cb);
$.getById('/user').id(3);
```
-->
## Default values

@@ -441,2 +433,4 @@ You can also specify default values. If it's not required, if a value listed in defaults is undefined, the default value will be substituted. A value should not have a default AND be required-- one or the other.

-->
## Tests

@@ -443,0 +437,0 @@ ```

var _ = require('underscore');
var anchor = require('../index.js');
var testRule = require('./testRule.js');
var testRule = require('./util/testRule.js');

@@ -5,0 +5,0 @@ describe('arrays', function() {

var _ = require('underscore');
var anchor = require('../index.js');
var testRule = require('./testRule.js');
var testRule = require('./util/testRule.js');

@@ -5,0 +5,0 @@

var _ = require('underscore');
var anchor = require('../index.js');
var testRule = require('./testRule.js');
var testRule = require('./util/testRule.js');

@@ -5,0 +5,0 @@ describe('error usage', function() {

var _ = require('underscore');
var anchor = require('../index.js');
var testRule = require('./testRule.js');
var testRule = require('./util/testRule.js');

@@ -5,0 +5,0 @@ describe('objects', function() {

var _ = require('underscore');
var anchor = require('../index.js');
var testRule = require('./testRule.js');
var testRule = require('./util/testRule.js');
var shouldFail = require('./util/shouldFail.js');
describe('usage', function() {

@@ -50,11 +50,2 @@

});
});
// Return function which flip-flops error state of callback
function shouldFail (cb) {
return function (err) {
if (!err) return cb('Should have thrown error!');
else return cb();
};
}
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc