diff --git a/README.md b/README.md index 7aedd0f..598b584 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,14 @@ The `Array.of` method has three signatures: ### Functions ### -`Function.reference(func)` matches `x` if `x === func`. +The `Function.reference(func)` matches `x` if `x === func`. + +The `Function.custom(func)` takes a user-defined function and passes `x` to it. The user-defined function must return `{valid: myBooleanValue, msg: 'My fail message'}` where the `valid` field tells js-schema to pass or fail the test, and `msg` is the error message shown if `valid` is `false`. For example: +```javascript +var validate = schema({ +  'name': Function.custom(x => ( { valid: x !== 'Bob' && x.length < 4, msg: 'Name is Bob or is too long' } )) +}); +``` Future plans ============ diff --git a/index.js b/index.js index 5fd271e..e9f850a 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ module.exports = require('./lib/schema') // Patterns +require('./lib/patterns/custom') require('./lib/patterns/reference') require('./lib/patterns/nothing') require('./lib/patterns/anything') diff --git a/lib/extensions/Function.js b/lib/extensions/Function.js index 5954cbb..9d10bff 100644 --- a/lib/extensions/Function.js +++ b/lib/extensions/Function.js @@ -1,5 +1,10 @@ var ReferenceSchema = require('../patterns/reference') +var CustomSchema = require('../patterns/custom') -Function.reference = function(f) { - return new ReferenceSchema(f).wrap() +Function.reference = function (f) { + return new ReferenceSchema(f).wrap() +} + +Function.custom = function (f) { + return new CustomSchema(f).wrap() } diff --git a/lib/patterns/custom.js b/lib/patterns/custom.js new file mode 100644 index 0000000..061572e --- /dev/null +++ b/lib/patterns/custom.js @@ -0,0 +1,25 @@ +var Schema = require('../BaseSchema') + +var CustomSchema = module.exports = Schema.patterns.CustomSchema = Schema.extend({ + initialize: function (func) { + this.func = func + }, + errors: function (instance) { + var self = this + var result = self.func(instance); + + if (!result.valid) + return result.msg + return false + }, + validate: function (instance) { + return this.func(instance).valid + }, + toJSON: function () { + return { type: 'custom' } + } +}) + +Schema.fromJS.def(function (func) { + return new CustomSchema(func) +})