diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..54376a9 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,20 @@ +{ + "bitwise": false, + "curly": true, + "eqeqeq": true, + "esversion": 5, + "freeze": true, + "funcscope": true, + "loopfunc": false, + "maxdepth": 5, + "noarg": true, + "nocomma": true, + "nonbsp": true, + "nonew": true, + "notypeof": true, + "predef": [ "MY_GLOBAL" ], + "shadow": true, + "singleGroups": false, + "undef": true, + "unused": false +} diff --git a/.travis.yml b/.travis.yml index d4a62c7..c424cbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: node_js node_js: - - "0.10" + - "4.0" before_script: - - npm install -g gulp \ No newline at end of file + - npm install -g gulp diff --git a/Gulpfile.js b/Gulpfile.js index 72f3610..ef5b94d 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -8,6 +8,7 @@ var qunit = require('gulp-qunit'); var shell = require('gulp-shell'); var merge = require('merge-stream'); var size = require('gulp-check-filesize'); +var jshint = require('gulp-jshint'); var build = { filename: 'rekord-validation.js', @@ -43,6 +44,9 @@ var executeBuild = function(props) .pipe( plugins.concat( props.filename ) ) .pipe( size({enableGzip: true}) ) .pipe( gulp.dest( props.output ) ) + .pipe(jshint()) + .pipe(jshint.reporter('default')) + .pipe(jshint.reporter('fail')) ; }; }; @@ -54,6 +58,15 @@ var executeTest = function(file) }; }; +gulp.task('lint', function() { + return gulp + .src(build.output + build.filename) + .pipe(jshint()) + .pipe(jshint.reporter('default')) + .pipe(jshint.reporter('fail')) + ; +}); + gulp.task( 'docs', shell.task(['./node_modules/.bin/jsdoc -c jsdoc.json'])); gulp.task( 'clean', shell.task(['rm -rf build/*.js', 'rm -rf build/*.map'])); gulp.task( 'test', executeTest( './test/index.html' ) ); diff --git a/bower.json b/bower.json index 91aa9a9..9934230 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "rekord-validation", - "version": "1.0.0", + "version": "1.0.1", "homepage": "https://github.com/Rekord/rekord-validation", "authors": [ "Philip Diffenderfer " @@ -21,5 +21,8 @@ "bower_components", "test", "tests" - ] + ], + "dependencies": { + "rekord": "^1.2.0" + } } diff --git a/build/rekord-validation.js b/build/rekord-validation.js index f1cefe9..1625a14 100644 --- a/build/rekord-validation.js +++ b/build/rekord-validation.js @@ -4,6 +4,7 @@ var Database = Rekord.Database; var Promise = Rekord.Promise; var Collection = Rekord.Collection; + var ModelCollection = Rekord.ModelCollection; var isEmpty = Rekord.isEmpty; var isString = Rekord.isString; @@ -16,6 +17,7 @@ var isValue = Rekord.isValue; var isPrimitiveArray = Rekord.isPrimitiveArray; var isRegExp = Rekord.isRegExp; + var isRekord = Rekord.isRekord; var noop = Rekord.noop; var equalsCompare = Rekord.equalsCompare; @@ -116,7 +118,7 @@ function determineMessage(ruleName, message) return message || Validation.Rules[ ruleName ].message; } -function joinFriendly(arr, lastSeparator, itemSeparator, getAlias) +function joinFriendly(arr, lastSeparatorCustom, itemSeparatorCustom, getAlias) { var copy = arr.slice(); @@ -129,8 +131,8 @@ function joinFriendly(arr, lastSeparator, itemSeparator, getAlias) } var last = copy.pop(); - var lastSeparator = lastSeparator || 'and'; - var itemSeparator = itemSeparator || ', '; + var lastSeparator = lastSeparatorCustom || 'and'; + var itemSeparator = itemSeparatorCustom || ', '; switch (copy.length) { case 0: @@ -207,7 +209,7 @@ Rekord.on( Rekord.Events.Plugins, function(model, db, options) for ( var field in rules ) { - db.validations[ field ] = Validation.parseRules( rules[ field ], field, db, getAlias, messages[ field ] ) + db.validations[ field ] = Validation.parseRules( rules[ field ], field, db, getAlias, messages[ field ] ); } addMethod( model.prototype, '$validate', function() @@ -226,7 +228,7 @@ Rekord.on( Rekord.Events.Plugins, function(model, db, options) var value = this.$get( field ); var fieldValid = true; - var setMessage = function(message) + var setMessage = function(message) // jshint ignore:line { // Only accept for the first valid message if ( message && fieldValid ) @@ -316,16 +318,16 @@ var Validation = for (var i = 0; i < rules.length; i++) { var rule = rules[ i ]; - var validator = this.parseRule( rule, field, database, getAlias, message ); + var defaultMessageValidator = this.parseRule( rule, field, database, getAlias, message ); - validators.push( validator ); + validators.push( defaultMessageValidator ); } } else if ( isObject( rules ) ) { - for (var rule in rules) + for (var ruleProperty in rules) { - var ruleMessageOrData = rules[ rule ]; + var ruleMessageOrData = rules[ ruleProperty ]; var ruleMessage = isObject( ruleMessageOrData ) ? ruleMessageOrData.message : ( isString( ruleMessageOrData ) ? ruleMessageOrData : undefined ); @@ -333,9 +335,9 @@ var Validation = var ruleInput = isObject( ruleMessageOrData ) && ruleMessageOrData.message ? ruleMessageOrData.input : ( isString( ruleMessageOrData ) ? undefined : ruleMessageOrData ); - var validator = this.parseRule( rule, field, database, getAlias, ruleMessage || message, ruleInput ); + var customMessageValidator = this.parseRule( ruleProperty, field, database, getAlias, ruleMessage || message, ruleInput ); - validators.push( validator ); + validators.push( customMessageValidator ); } } @@ -641,7 +643,7 @@ function collectionRuleGenerator(ruleName, defaultMessage, isInvalid) if ( indexOf( database.fields, matchField ) === -1 ) { - throw otherField + ' is not a valid field for the ' + ruleName + ' rule'; + throw matchField + ' is not a valid field for the ' + ruleName + ' rule'; } var messageTemplate = determineMessage( ruleName, message ); @@ -679,11 +681,11 @@ Validation.Rules.validate = function(field, params, database, getAlias, message) for (var i = 0; i < value.length; i++) { - var model = value[ i ]; + var related = value[ i ]; - if ( model && model.$validate && !model.$validate() ) + if ( related && related.$validate && !related.$validate() ) { - invalid.push( model ); + invalid.push( related ); } } @@ -1080,7 +1082,7 @@ function fieldsRuleGenerator(ruleName, defaultMessage, isInvalid) }; Validation.Rules[ ruleName ].message = defaultMessage; -}; +} // exists:X,Y foreignRuleGenerator('exists', @@ -1299,7 +1301,7 @@ listRuleGenerator('not_in', '{$alias} must not be one of {$list}.', function isInvalid(value, model, inList) { - return inList( value, model ) + return inList( value, model ); } ); @@ -1949,22 +1951,29 @@ Validation.Rules.startOfDay = function(field, params, database, alias, message) Validation.Rules.trim = function(field, params, database, alias, message) { - // String.trim polyfill - if ( !String.prototype.trim ) + var trim = (function() { + if ( String.prototype.trim ) + { + return function(x) { + return x.trim(); + }; + } + var regex = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - String.prototype.trim = function() + return function(x) { - return this.replace( regex, '' ); + return x.replace( regex, '' ); }; - } + + })(); return function(value, model, setMessage) { if ( isString( value ) ) { - value = value.trim(); + value = trim( value ); } return value; @@ -2010,4 +2019,4 @@ Validation.Rules.unbase64 = function(field, params, database, alias, message) Rekord.checkNoParams = checkNoParams; Rekord.generateMessage = generateMessage; -})(this, Rekord); +})(this, this.Rekord); diff --git a/build/rekord-validation.min.js b/build/rekord-validation.min.js index 7c6553e..ce2cba8 100644 --- a/build/rekord-validation.min.js +++ b/build/rekord-validation.min.js @@ -1,2 +1,2 @@ -!function(e,t,r){function n(e){var t=parseFloat(e);return isNaN(t)||(e=t),e}function a(e){var t=parseInt(e);return isNaN(t)||(e=t),e}function i(e){return V(e)?e.setHours(0,0,0,0):z(e)&&(e-=e%864e5),e}function s(e){return V(e)?e.setHours(23,59,59,999):z(e)&&(e=e-e%864e5+864e5-1),e}function u(e,t,r){B.Rules[e]=function(t,n,a,i,s){c(e,t,n);var u=o(e,s);return function(e,n,a){function s(t){e=t}return r(e,n,s)&&a(m(t,i(t),e,n,u)),e}},B.Rules[e].message=t}function o(e,t){return t||B.Rules[e].message}function l(e,t,r,n){var a=e.slice();if(n)for(var i=0;ie}),h("before","{$alias} must be before {$date}.",function(e,t){return e>t}),h("before_on","{$alias} must be before or equal to {$date}.",function(e,t){return e>s(t)}),u("date_like","{$alias} must be a valid date.",function(e,t,r){var n=W(e),a=n===!1;return a||r(n.getTime()),a}),v("required_if","{$alias} is required.",function(e,t,r,n,a){var i=a[t.$get(r)];return i&&_(e)}),v("required_unless","{$alias} is required.",function(e,t,r,n,a){var i=!a[t.$get(r)];return i&&_(e)}),$("confirmed","{$alias} must match {$fieldAliases}.",function(e,t,r,n){for(var a=!0,i=0;i0}),b("if_any",function(e,t){return e>=t}),b("if_not",function(e,t){return t>e}),p("in","{$alias} must be one of {$list}.",function(e,t,r){return!r(e,t)}),p("not_in","{$alias} must not be one of {$list}.",function(e,t,r){return r(e,t)}),R("between",{string:"{$alias} must have between {$start} to {$end} characters.",number:"{$alias} must be between {$start} and {$end}.",object:"{$alias} must have between {$start} to {$end} items."},function(e,t,r){return t>e||e>r}),R("not_between",{string:"{$alias} must not have between {$start} to {$end} characters.",number:"{$alias} must not be between {$start} and {$end}.",object:"{$alias} must not have between {$start} to {$end} items."},function(e,t,r){return e>=t&&r>=e}),w("alpha","{$alias} should only contain alphabetic characters.",/^[a-zA-Z]*$/),w("alpha_dash","{$alias} should only contain alpha-numeric characters, dashes, and underscores.",/^[a-zA-Z0-9_-]*$/),w("alpha_num","{$alias} should only contain alpha-numeric characters.",/^[a-zA-Z0-9]*$/),w("email","{$alias} is not a valid email.",/^.+@.+\..+$/),w("url","{$alias} is not a valid URL.",/^(https?:\/\/)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)$/),w("uri","{$alias} is not a valid URI.",/^(\w+:\/\/)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)$/),w("phone","{$alias} is not a valid phone number.",/^1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?$/),B.Rules.regex=function(e,t,r,n,a){var i;if(A(t)){var s=/^\/(.*)\/([gmi]*)$/.exec(t);s&&(i=new RegExp(s[1],s[2]))}else T(t)&&(i=t);if(!i)throw t+" is not a valid regular expression for the regex rule";var u=o("regex",a);return function(t,r,a){return i.test(t)||a(m(e,n(e),t,r,u)),t}},B.Rules.regex.message="{$alias} is not a valid value.",u("required","{$alias} is required.",function(e){return _(e)}),y("min",{string:"{$alias} must have a minimum of {$number} characters.",number:"{$alias} must be at least {$number}.",object:"{$alias} must have at least {$number} items."},function(e,t){return t>e}),y("greater_than",{string:"{$alias} must have more than {$number} characters.",number:"{$alias} must be greater than {$number}.",object:"{$alias} must have more than {$number} items."},function(e,t){return t>=e}),y("max",{string:"{$alias} must have no more than {$number} characters.",number:"{$alias} must be no more than {$number}.",object:"{$alias} must have no more than {$number} items."},function(e,t){return e>t}),y("less_than",{string:"{$alias} must have less than {$number} characters.",number:"{$alias} must be less than {$number}.",object:"{$alias} must have less than {$number} items."},function(e,t){return e>=t}),y("equal",{string:"{$alias} must have {$number} characters.",number:"{$alias} must equal {$number}.",object:"{$alias} must have {$number} items."},function(e,t){return e!==t}),y("not_equal",{string:"{$alias} must not have {$number} characters.",number:"{$alias} must not equal {$number}.",object:"{$alias} must not have {$number} items."},function(e,t){return e===t}),u("array","{$alias} must be an array.",function(e){return!D(e)}),u("object","{$alias} must be an object.",function(e){return!M(e)}),u("string","{$alias} must be a string.",function(e){return!A(e)}),u("number","{$alias} must be a number.",function(e){return!z(e)}),u("boolean","{$alias} must be a true or false.",function(e){return!N(e)}),u("model","{$alias} must have a value.",function(e){return!(e instanceof x)}),u("whole","{$alias} must be a whole number.",function(e,t,r){var n=a(e),i=parseFloat(e),s=!z(n);return s||(s=Math.floor(n)!==i,s||r(n)),s}),u("numeric","{$alias} must be numeric.",function(e,t,r){var a=n(e),i=!z(a);return i||r(a),i}),u("yesno","{$alias} must be a yes or no.",function(e,t,r){var n=B.Rules.yesno.map[e],a=!N(n);return a||r(n),a}),B.Rules.yesno.map={"true":!0,t:!0,yes:!0,y:!0,1:!0,"false":!1,f:!1,no:!1,n:!1,0:!1},B.Rules.abs=function(e,t,r,a,i){return function(e,t,r){return e=n(e),z(e)&&(e=Math.abs(e)),e}},B.Rules.apply=function(e,t,r,n,a){return function(t,r,n){return r.$set(e,t),t}},B.Rules.base64=function(t,r,n,a,i){return function(t,r,n){return e.btoa&&(t=e.btoa(t)),t}},B.Rules.ceil=function(e,t,r,a,i){return function(e,t,r){return e=n(e),z(e)&&(e=Math.ceil(e)),e}},B.Rules.endOfDay=function(e,t,r,n,a){return function(e,t,r){return s(e)}},B.Rules.filter=function(e,t,r,n,a){return function(e,t,r){if(D(e))for(var n=e.length-1;n>=0;n--)k(e[n])||e.splice(n,1);else if(M(e))for(var a in e)k(e[a])||delete e[a];return e}},B.Rules.floor=function(e,t,r,a,i){return function(e,t,r){return e=n(e),z(e)&&(e=Math.floor(e)),e}},B.Rules.mod=function(e,t,r,a,i){var s=n(t);if(!z(s))throw'"'+s+'" is not a valid number for the mod rule.';return function(e,t,r){return e=n(e),z(e)&&(e%=s),e}},B.Rules["null"]=function(e,t,r,n,a){return function(t,r,n){return r.$set(e,null),null}},B.Rules.round=function(e,t,r,a,i){return function(e,t,r){return e=n(e),z(e)&&(e=Math.round(e)),e}},B.Rules.startOfDay=function(e,t,r,n,a){return function(e,t,r){return i(e)}},B.Rules.trim=function(e,t,r,n,a){if(!String.prototype.trim){var i=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;String.prototype.trim=function(){return this.replace(i,"")}}return function(e,t,r){return A(e)&&(e=e.trim()),e}},B.Rules.unbase64=function(t,r,n,a,i){return function(t,r,n){return e.atob&&(t=e.atob(t)),t}},t.Validation=B,t.ruleGenerator=u,t.rangeRuleGenerator=R,t.collectionRuleGenerator=d,t.dateRuleGenerator=h,t.fieldListRuleGenerator=v,t.fieldsRuleGenerator=$,t.foreignRuleGenerator=g,t.subRuleGenerator=b,t.listRuleGenerator=p,t.regexRuleGenerator=w,t.sizeRuleGenerator=y,t.joinFriendly=l,t.tryParseFloat=n,t.tryParseInt=a,t.startOfDay=i,t.endOfDay=s,t.determineMessage=o,t.mapFromArray=f,t.checkNoParams=c,t.generateMessage=m}(this,Rekord); +!function(e,t,r){function n(e){var t=parseFloat(e);return isNaN(t)||(e=t),e}function a(e){var t=parseInt(e);return isNaN(t)||(e=t),e}function i(e){return z(e)?e.setHours(0,0,0,0):N(e)&&(e-=e%864e5),e}function s(e){return z(e)?e.setHours(23,59,59,999):N(e)&&(e=e-e%864e5+864e5-1),e}function u(e,t,r){K.Rules[e]=function(t,n,a,i,s){c(e,t,n);var u=o(e,s);return function(e,n,a){function s(t){e=t}return r(e,n,s)&&a(m(t,i(t),e,n,u)),e}},K.Rules[e].message=t}function o(e,t){return t||K.Rules[e].message}function l(e,t,r,n){var a=e.slice();if(n)for(var i=0;ie}),h("before","{$alias} must be before {$date}.",function(e,t){return e>t}),h("before_on","{$alias} must be before or equal to {$date}.",function(e,t){return e>s(t)}),u("date_like","{$alias} must be a valid date.",function(e,t,r){var n=U(e),a=n===!1;return a||r(n.getTime()),a}),v("required_if","{$alias} is required.",function(e,t,r,n,a){var i=a[t.$get(r)];return i&&A(e)}),v("required_unless","{$alias} is required.",function(e,t,r,n,a){var i=!a[t.$get(r)];return i&&A(e)}),$("confirmed","{$alias} must match {$fieldAliases}.",function(e,t,r,n){for(var a=!0,i=0;i0}),b("if_any",function(e,t){return e>=t}),b("if_not",function(e,t){return t>e}),p("in","{$alias} must be one of {$list}.",function(e,t,r){return!r(e,t)}),p("not_in","{$alias} must not be one of {$list}.",function(e,t,r){return r(e,t)}),R("between",{string:"{$alias} must have between {$start} to {$end} characters.",number:"{$alias} must be between {$start} and {$end}.",object:"{$alias} must have between {$start} to {$end} items."},function(e,t,r){return t>e||e>r}),R("not_between",{string:"{$alias} must not have between {$start} to {$end} characters.",number:"{$alias} must not be between {$start} and {$end}.",object:"{$alias} must not have between {$start} to {$end} items."},function(e,t,r){return e>=t&&r>=e}),w("alpha","{$alias} should only contain alphabetic characters.",/^[a-zA-Z]*$/),w("alpha_dash","{$alias} should only contain alpha-numeric characters, dashes, and underscores.",/^[a-zA-Z0-9_-]*$/),w("alpha_num","{$alias} should only contain alpha-numeric characters.",/^[a-zA-Z0-9]*$/),w("email","{$alias} is not a valid email.",/^.+@.+\..+$/),w("url","{$alias} is not a valid URL.",/^(https?:\/\/)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)$/),w("uri","{$alias} is not a valid URI.",/^(\w+:\/\/)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)$/),w("phone","{$alias} is not a valid phone number.",/^1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?$/),K.Rules.regex=function(e,t,r,n,a){var i;if(D(t)){var s=/^\/(.*)\/([gmi]*)$/.exec(t);s&&(i=new RegExp(s[1],s[2]))}else P(t)&&(i=t);if(!i)throw t+" is not a valid regular expression for the regex rule";var u=o("regex",a);return function(t,r,a){return i.test(t)||a(m(e,n(e),t,r,u)),t}},K.Rules.regex.message="{$alias} is not a valid value.",u("required","{$alias} is required.",function(e){return A(e)}),y("min",{string:"{$alias} must have a minimum of {$number} characters.",number:"{$alias} must be at least {$number}.",object:"{$alias} must have at least {$number} items."},function(e,t){return t>e}),y("greater_than",{string:"{$alias} must have more than {$number} characters.",number:"{$alias} must be greater than {$number}.",object:"{$alias} must have more than {$number} items."},function(e,t){return t>=e}),y("max",{string:"{$alias} must have no more than {$number} characters.",number:"{$alias} must be no more than {$number}.",object:"{$alias} must have no more than {$number} items."},function(e,t){return e>t}),y("less_than",{string:"{$alias} must have less than {$number} characters.",number:"{$alias} must be less than {$number}.",object:"{$alias} must have less than {$number} items."},function(e,t){return e>=t}),y("equal",{string:"{$alias} must have {$number} characters.",number:"{$alias} must equal {$number}.",object:"{$alias} must have {$number} items."},function(e,t){return e!==t}),y("not_equal",{string:"{$alias} must not have {$number} characters.",number:"{$alias} must not equal {$number}.",object:"{$alias} must not have {$number} items."},function(e,t){return e===t}),u("array","{$alias} must be an array.",function(e){return!M(e)}),u("object","{$alias} must be an object.",function(e){return!j(e)}),u("string","{$alias} must be a string.",function(e){return!D(e)}),u("number","{$alias} must be a number.",function(e){return!N(e)}),u("boolean","{$alias} must be a true or false.",function(e){return!k(e)}),u("model","{$alias} must have a value.",function(e){return!(e instanceof x)}),u("whole","{$alias} must be a whole number.",function(e,t,r){var n=a(e),i=parseFloat(e),s=!N(n);return s||(s=Math.floor(n)!==i,s||r(n)),s}),u("numeric","{$alias} must be numeric.",function(e,t,r){var a=n(e),i=!N(a);return i||r(a),i}),u("yesno","{$alias} must be a yes or no.",function(e,t,r){var n=K.Rules.yesno.map[e],a=!k(n);return a||r(n),a}),K.Rules.yesno.map={"true":!0,t:!0,yes:!0,y:!0,1:!0,"false":!1,f:!1,no:!1,n:!1,0:!1},K.Rules.abs=function(e,t,r,a,i){return function(e,t,r){return e=n(e),N(e)&&(e=Math.abs(e)),e}},K.Rules.apply=function(e,t,r,n,a){return function(t,r,n){return r.$set(e,t),t}},K.Rules.base64=function(t,r,n,a,i){return function(t,r,n){return e.btoa&&(t=e.btoa(t)),t}},K.Rules.ceil=function(e,t,r,a,i){return function(e,t,r){return e=n(e),N(e)&&(e=Math.ceil(e)),e}},K.Rules.endOfDay=function(e,t,r,n,a){return function(e,t,r){return s(e)}},K.Rules.filter=function(e,t,r,n,a){return function(e,t,r){if(M(e))for(var n=e.length-1;n>=0;n--)G(e[n])||e.splice(n,1);else if(j(e))for(var a in e)G(e[a])||delete e[a];return e}},K.Rules.floor=function(e,t,r,a,i){return function(e,t,r){return e=n(e),N(e)&&(e=Math.floor(e)),e}},K.Rules.mod=function(e,t,r,a,i){var s=n(t);if(!N(s))throw'"'+s+'" is not a valid number for the mod rule.';return function(e,t,r){return e=n(e),N(e)&&(e%=s),e}},K.Rules["null"]=function(e,t,r,n,a){return function(t,r,n){return r.$set(e,null),null}},K.Rules.round=function(e,t,r,a,i){return function(e,t,r){return e=n(e),N(e)&&(e=Math.round(e)),e}},K.Rules.startOfDay=function(e,t,r,n,a){return function(e,t,r){return i(e)}},K.Rules.trim=function(e,t,r,n,a){var i=function(){if(String.prototype.trim)return function(e){return e.trim()};var e=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;return function(t){return t.replace(e,"")}}();return function(e,t,r){return D(e)&&(e=i(e)),e}},K.Rules.unbase64=function(t,r,n,a,i){return function(t,r,n){return e.atob&&(t=e.atob(t)),t}},t.Validation=K,t.ruleGenerator=u,t.rangeRuleGenerator=R,t.collectionRuleGenerator=d,t.dateRuleGenerator=h,t.fieldListRuleGenerator=v,t.fieldsRuleGenerator=$,t.foreignRuleGenerator=g,t.subRuleGenerator=b,t.listRuleGenerator=p,t.regexRuleGenerator=w,t.sizeRuleGenerator=y,t.joinFriendly=l,t.tryParseFloat=n,t.tryParseInt=a,t.startOfDay=i,t.endOfDay=s,t.determineMessage=o,t.mapFromArray=f,t.checkNoParams=c,t.generateMessage=m}(this,this.Rekord); //# sourceMappingURL=rekord-validation.min.js.map diff --git a/build/rekord-validation.min.js.map b/build/rekord-validation.min.js.map index bc83aac..cb1ea1d 100644 --- a/build/rekord-validation.min.js.map +++ b/build/rekord-validation.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["header.js","util.js","rules/collection.js","rules/dates.js","rules/field_list.js","rules/fields.js","rules/foreign.js","rules/if.js","rules/list.js","rules/range.js","rules/regex.js","rules/sizes.js","validation.js","expressions/date.js","expressions/field.js","expressions/relative.js","expressions/today.js","expressions/tomorrow.js","expressions/yesterday.js","rules/accepted.js","rules/required.js","rules/types.js","transforms/abs.js","transforms/apply.js","transforms/base64.js","transforms/ceil.js","transforms/endOfDay.js","transforms/filter.js","transforms/floor.js","transforms/mod.js","transforms/null.js","transforms/round.js","transforms/startOfDay.js","transforms/trim.js","transforms/unbase64.js","footer.js"],"names":["global","Rekord","undefined","tryParseFloat","x","parsed","parseFloat","isNaN","tryParseInt","parseInt","startOfDay","d","isDate","setHours","isNumber","endOfDay","ruleGenerator","ruleName","defaultMessage","isInvalid","Validation","Rules","field","params","database","getAlias","message","checkNoParams","messageTemplate","determineMessage","value","model","setMessage","setValue","newValue","generateMessage","joinFriendly","arr","lastSeparator","itemSeparator","copy","slice","i","length","last","pop","join","mapFromArray","map","alias","extra","isFunction","base","$field","$alias","$value","transfer","isObject","format","collectionRuleGenerator","matchField","matchValue","equality","isString","comma","indexOf","substring","isArray","equals","equalsCompare","fields","otherField","$matchField","$matchAlias","$matchValue","dateRuleGenerator","dateExpression","parseExpression","parseDate","parsedTime","getTime","noop","$date","date","fieldListRuleGenerator","matchValues","parts","split","shift","values","list","$params","$list","fieldsRuleGenerator","fieldNames","fieldAliases","$fields","$fieldAliases","foreignRuleGenerator","modelName","models","fieldName","isValue","name","ModelCollection","get","success","modelClass","all","isRekord","$class","subRuleGenerator","otherRules","colon","rules","validators","parseRules","invalids","setInvalid","Stop","listRuleGenerator","inList","isPrimitiveArray","rangeRuleGenerator","defaultMessages","start","end","range","string","number","object","$start","$end","size","sizeof","type","typeMessage","$size","regexRuleGenerator","regex","test","sizeRuleGenerator","$number","Model","Database","Promise","Collection","isEmpty","isBoolean","isRegExp","addMethod","replaceMethod","on","Events","Plugins","db","options","aliases","validation","Defaults","messages","required","validations","prototype","$this","this","$trigger","PreValidate","$valid","$validations","$validationMessages","chain","$get","fieldValid","push","ValidatePass","ValidateFail","$init","apply","arguments","$save","$isDeleted","debug","Debugs","SAVE_DELETED","$db","resolve","$validate","Expression","Expressions","Delimiter","Escape","RuleSeparator","rule","validator","parseRule","ruleMessageOrData","ruleMessage","ruleInput","input","charAt","customValidator","ruleParams","validatorFactory","expr","parsers","parser","expressionFunction","functionName","result","RELATIVE_REGEX","RELATIVE_UNITS","ms","millisecond","milliseconds","s","second","seconds","min","mins","minute","minutes","hr","hour","hours","day","days","wk","week","weeks","month","months","yr","year","years","relative","exec","amount","unit","unitScale","Date","setTime","getter","setter","today","tomorrow","setDate","getDate","yesterday","accepted","acceptable","valueString","toLowerCase","1","yes","y","true","contains","m","validate","messageOption","invalid","pluck","confirmed","different","valid","invalidCount","totalCount","RegExp","numeric","Math","floor","mapped","yesno","t","false","f","no","n","0","abs","$set","base64","btoa","ceil","filter","splice","prop","mod","round","trim","String","replace","unbase64","atob"],"mappings":"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","file":"rekord-validation.min.js","sourcesContent":["(function(global, Rekord, undefined)\n{\n var Model = Rekord.Model;\n var Database = Rekord.Database;\n var Promise = Rekord.Promise;\n var Collection = Rekord.Collection;\n\n var isEmpty = Rekord.isEmpty;\n var isString = Rekord.isString;\n var isArray = Rekord.isArray;\n var isObject = Rekord.isObject;\n var isFunction = Rekord.isFunction;\n var isDate = Rekord.isDate;\n var isNumber = Rekord.isNumber;\n var isBoolean = Rekord.isBoolean;\n var isValue = Rekord.isValue;\n var isPrimitiveArray = Rekord.isPrimitiveArray;\n var isRegExp = Rekord.isRegExp;\n\n var noop = Rekord.noop;\n var equalsCompare = Rekord.equalsCompare;\n var equals = Rekord.equals;\n var indexOf = Rekord.indexOf;\n var sizeof = Rekord.sizeof;\n\n var split = Rekord.split;\n var transfer = Rekord.transfer;\n var format = Rekord.format;\n\n var parseDate = Rekord.parseDate;\n\n var addMethod = Rekord.addMethod;\n var replaceMethod = Rekord.replaceMethod;\n","function tryParseFloat(x)\n{\n var parsed = parseFloat( x );\n\n if ( !isNaN( parsed ) )\n {\n x = parsed;\n }\n\n return x;\n}\n\nfunction tryParseInt(x)\n{\n var parsed = parseInt( x );\n\n if ( !isNaN( parsed ) )\n {\n x = parsed;\n }\n\n return x;\n}\n\nfunction startOfDay(d)\n{\n if ( isDate( d ) )\n {\n d.setHours( 0, 0, 0, 0 );\n }\n else if ( isNumber( d ) )\n {\n d = d - (d % 86400000);\n }\n\n return d;\n}\n\nfunction endOfDay(d)\n{\n if ( isDate( d ) )\n {\n d.setHours( 23, 59, 59, 999 );\n }\n else if ( isNumber( d ) )\n {\n d = d - (d % 86400000) + 86400000 - 1;\n }\n\n return d;\n}\n\nfunction ruleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n checkNoParams( ruleName, field, params );\n\n var messageTemplate = determineMessage( ruleName, message );\n\n return function(value, model, setMessage)\n {\n function setValue( newValue )\n {\n value = newValue;\n }\n\n if ( isInvalid( value, model, setValue ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n\nfunction determineMessage(ruleName, message)\n{\n return message || Validation.Rules[ ruleName ].message;\n}\n\nfunction joinFriendly(arr, lastSeparator, itemSeparator, getAlias)\n{\n var copy = arr.slice();\n\n if ( getAlias )\n {\n for (var i = 0; i < copy.length; i++)\n {\n copy[ i ] = getAlias( copy[ i ] );\n }\n }\n\n var last = copy.pop();\n var lastSeparator = lastSeparator || 'and';\n var itemSeparator = itemSeparator || ', ';\n\n switch (copy.length) {\n case 0:\n return last;\n case 1:\n return copy[ 0 ] + ' ' + lastSeparator + ' ' + last;\n default:\n return copy.join( itemSeparator ) + itemSeparator + lastSeparator + ' ' + last;\n }\n}\n\nfunction mapFromArray(arr, value)\n{\n var map = {};\n\n for (var i = 0; i < arr.length; i++)\n {\n map[ arr[ i ] ] = value;\n }\n\n return map;\n}\n\nfunction checkNoParams(ruleName, field, params)\n{\n if ( params )\n {\n throw 'the rule ' + ruleName + ' for field ' + field + ' has no arguments';\n }\n}\n\nfunction generateMessage(field, alias, value, model, message, extra)\n{\n if ( isFunction( message ) )\n {\n message = message( field, alias, value, model, extra );\n }\n\n var base = {};\n base.$field = field;\n base.$alias = alias;\n base.$value = value;\n\n transfer( model, base );\n\n if ( isObject( extra ) )\n {\n transfer( extra, base );\n }\n\n return format( message, base );\n}\n","// contains:field,value\ncollectionRuleGenerator('contains',\n '{$alias} does not contain an item whose {$matchAlias} equals {$matchValue}.',\n function isInvalid(value, model, matchField, matchValue, equality)\n {\n return !value.contains(function isMatch(m)\n {\n return m !== model && equality( matchValue, m.$get( matchField ) );\n });\n }\n);\n\n// not_contains:field,value\ncollectionRuleGenerator('not_contains',\n '{$alias} contains an item whose {$matchAlias} equals {$matchValue}.',\n function isInvalid(value, model, matchField, matchValue, equality)\n {\n return value.contains(function isMatch(m)\n {\n return m !== model && equality( matchValue, m.$get( matchField ) );\n });\n }\n);\n\nfunction collectionRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires field & value arguments';\n }\n\n var matchField, matchValue, equality;\n\n if ( isString( params ) )\n {\n var comma = params.indexOf(',');\n\n if ( comma === -1 )\n {\n throw ruleName + ' validation rule requires field & value arguments';\n }\n\n matchField = params.substring( 0, comma );\n matchValue = params.substring( comma + 1 );\n }\n else if ( isArray( params ) )\n {\n matchField = params[ 0 ];\n matchValue = params[ 1 ];\n equality = params[ 2 ];\n }\n else if ( isObject( params ) )\n {\n matchField = params.field;\n matchValue = params.value;\n equality = params.equals;\n }\n\n if ( !isFunction( equality ) )\n {\n equality = equalsCompare;\n }\n\n if ( indexOf( database.fields, matchField ) === -1 )\n {\n throw otherField + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $matchField: matchField,\n $matchAlias: getAlias( matchField ),\n $matchValue: matchValue\n };\n\n return function(value, model, setMessage)\n {\n if ( isInvalid( value, model, matchField, matchValue, equality ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n\nValidation.Rules.validate = function(field, params, database, getAlias, message)\n{\n // message, models, validations\n var messageOption = params || 'message';\n var messageTemplate = determineMessage( 'validate', message );\n\n return function(value, model, setMessage)\n {\n if ( isArray( value ) )\n {\n var invalid = new Collection();\n\n for (var i = 0; i < value.length; i++)\n {\n var model = value[ i ];\n\n if ( model && model.$validate && !model.$validate() )\n {\n invalid.push( model );\n }\n }\n\n if ( invalid.length )\n {\n switch (messageOption)\n {\n case 'models':\n setMessage( invalid );\n break;\n case 'validations':\n setMessage( invalid.pluck( '$validations', '$$key' ) );\n break;\n default: // message\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n break;\n }\n }\n }\n\n return value;\n };\n};\n\nValidation.Rules.validate.message = '{$alias} is not valid.';\n","// after:today\ndateRuleGenerator('after',\n '{$alias} must be after {$date}.',\n function isInvalid(value, date) {\n return value < endOfDay( date );\n }\n);\n\n// after_on:tomorrow\ndateRuleGenerator('after_on',\n '{$alias} must be after or equal to {$date}.',\n function isInvalid(value, date) {\n return value < date;\n }\n);\n\n// before:yesterday\ndateRuleGenerator('before',\n '{$alias} must be before {$date}.',\n function isInvalid(value, date) {\n return value > date;\n }\n);\n\n// before_on:+2days\ndateRuleGenerator('before_on',\n '{$alias} must be before or equal to {$date}.',\n function isInvalid(value, date) {\n return value > endOfDay( date );\n }\n);\n\n// date\nruleGenerator('date_like',\n '{$alias} must be a valid date.',\n function isInvalid(value, model, setValue) {\n var parsed = parseDate( value );\n var invalid = parsed === false;\n if ( !invalid ) {\n setValue( parsed.getTime() );\n }\n return invalid;\n }\n);\n\nfunction dateRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a date expression argument';\n }\n\n var dateExpression;\n\n if ( isString( params ) )\n {\n dateExpression = Validation.parseExpression( params, database );\n }\n else if ( isFunction( params ) )\n {\n dateExpression = params;\n }\n else\n {\n var parsed = parseDate( params );\n\n if ( parsed !== false )\n {\n var parsedTime = parsed.getTime();\n\n dateExpression = function()\n {\n return parsedTime;\n };\n }\n }\n\n if ( !dateExpression || dateExpression === noop )\n {\n throw params + ' is not a valid date expression for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $date: params\n };\n\n return function(value, model, setMessage)\n {\n var parsed = parseDate( value );\n\n if ( parsed !== false )\n {\n value = parsed.getTime();\n\n var date = dateExpression( value, model );\n\n if ( isNumber( date ) && isInvalid( value, date ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","\n// required_if:X,Y,...\nfieldListRuleGenerator('required_if',\n '{$alias} is required.',\n function isInvalid(value, model, field, values, map) {\n var required = map[ model.$get( field ) ];\n\n return required && isEmpty( value );\n }\n);\n\n// required_unless:X,Y,...\nfieldListRuleGenerator('required_unless',\n '{$alias} is required.',\n function isInvalid(value, model, field, values, map) {\n var required = !map[ model.$get( field ) ];\n\n return required && isEmpty( value );\n }\n);\n\nfunction fieldListRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a field and list arguments';\n }\n\n var matchField, matchValues;\n\n if ( isString( params ) )\n {\n var parts = split( params, /(,)/, '\\\\' );\n\n matchField = parts.shift();\n matchValues = parts;\n }\n else if ( isArray( params ) )\n {\n matchField = params.shift();\n matchValues = params;\n }\n else if ( isObject( params ) )\n {\n matchField = params.field;\n matchValues = params.values;\n }\n\n if ( indexOf( database.fields, matchField ) === false )\n {\n throw matchField + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var list = joinFriendly( matchValues );\n var extra = {\n $params: params,\n $matchField: matchField,\n $matchAlias: getAlias( matchField ),\n $list: list\n };\n var map = mapFromArray( matchValues, true );\n\n return function(value, model, setMessage)\n {\n if ( isInvalid( value, model, matchField, matchValues, map ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// confirmed:X\nfieldsRuleGenerator('confirmed',\n '{$alias} must match {$fieldAliases}.',\n function isInvalid(value, model, fields, setValue) {\n var confirmed = true;\n\n for (var i = 0; i < fields.length; i++)\n {\n if ( !equals( value, model.$get( fields[ i ] ) ) )\n {\n confirmed = false;\n }\n }\n\n return !confirmed;\n }\n);\n\n// different:X\nfieldsRuleGenerator('different',\n '{$alias} must not match {$fieldAliases}.',\n function isInvalid(value, model, fields, setValue) {\n var different = false;\n\n for (var i = 0; i < fields.length; i++)\n {\n if ( !equals( value, model.$get( fields[ i ] ) ) )\n {\n different = true;\n }\n }\n\n return !different;\n }\n);\n\n// if_valid:X\nfieldsRuleGenerator('if_valid',\n '',\n function isInvalid(value, model, fields, setValue) {\n var valid = true;\n\n for (var i = 0; i < fields.length && valid; i++)\n {\n if ( model.$validations[ fields[ i ] ] )\n {\n valid = false;\n }\n }\n\n if ( !valid )\n {\n setValue( Validation.Stop );\n }\n\n return false;\n }\n);\n\n// The field under validation must be present only if any of the other specified fields are present.\n// required_with:X,Y,...\nfieldsRuleGenerator('required_with',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = false;\n\n for (var i = 0; i < fields.length && !required; i++)\n {\n if ( !isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = true;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\n// The field under validation must be present only if all of the other specified fields are present.\n// required_with_all:X,Y,...\nfieldsRuleGenerator('required_with_all',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = true;\n\n for (var i = 0; i < fields.length && required; i++)\n {\n if ( isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = false;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\n// The field under validation must be present only when any of the other specified fields are not present.\n// required_without:X,Y,...\nfieldsRuleGenerator('required_without',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = false;\n\n for (var i = 0; i < fields.length && !required; i++)\n {\n if ( isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = true;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\n// The field under validation must be present only when all of the other specified fields are not present.\n// required_without_all:X,Y,...\nfieldsRuleGenerator('required_without_all',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = true;\n\n for (var i = 0; i < fields.length && required; i++)\n {\n if ( !isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = false;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\nfunction fieldsRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires an array of fields argument';\n }\n\n var fields = split( params, /(\\s*,\\s*)/, '\\\\' );\n\n for (var i = 0; i < fields.length; i++)\n {\n if ( indexOf( database.fields, fields[ i ] ) === -1 )\n {\n throw fields[ i ] + ' is not a valid field for the ' + ruleName + ' rule';\n }\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var fieldNames = joinFriendly( fields );\n var fieldAliases = joinFriendly( fields, false, false, getAlias );\n var extra = {\n $fields: fieldNames,\n $fieldAliases: fieldAliases\n };\n\n return function(value, model, setMessage)\n {\n function setValue( newValue )\n {\n value = newValue;\n }\n\n if ( isInvalid( value, model, fields, setValue ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n};\n","// exists:X,Y\nforeignRuleGenerator('exists',\n '{$alias} must match an existing {$matchAlias} in a {$class}',\n function isInvalid(value, model, models, fieldName)\n {\n return !models.contains(function isDifferentMatch(m)\n {\n return m !== model && equals( value, m.$get( fieldName ) );\n });\n }\n);\n\n// unique:X,Y\nforeignRuleGenerator('unique',\n '{$alias} must be a unique {$matchAlias} in a {$class}',\n function isInvalid(value, model, models, fieldName)\n {\n return models.contains(function isDifferentMatch(m)\n {\n return m !== model && equals( value, m.$get( fieldName ) );\n });\n }\n);\n\n// 'ruleName'\n// 'ruleName:name'\n// 'ruleName:,field'\n// 'ruleName:name,field'\n// 'ruleName:name,field': '...'\n// 'ruleName': {input: {field: 'field', model: 'name'}, message: '...'}\n// 'ruleName': {input: {field: 'field', model: ModelClass}, message: '...'}\n// 'ruleName': {input: {field: 'field', models: [...]}, message: '...'}\n// 'ruleName': {field: 'field', model: 'name'}\n// 'ruleName': {field: 'field', model: ModelClass}\n// 'ruleName': {field: 'field', models: [...]}\nfunction foreignRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n var modelName, models, fieldName;\n\n if ( !isValue( params ) || isString( params ) )\n {\n var parts = split( params || '', /(\\s*,\\s*)/, '\\\\' );\n modelName = parts[0] || database.name;\n fieldName = parts[1] || field;\n models = null;\n }\n else if ( isArray( params ) )\n {\n modelName = isString( params[0] ) ? params.shift() : database.name;\n fieldName = isString( params[0] ) ? params.shift() : field;\n models = new ModelCollection( database, params );\n }\n else if ( isObject( params ) )\n {\n modelName = params.model || database.name;\n fieldName = params.field || field;\n models = params.models;\n }\n\n if ( !models )\n {\n if ( !modelName )\n {\n throw 'model, model class, or models is required for ' + ruleName + ' rule';\n }\n\n if ( isString( modelName ) )\n {\n Rekord.get( modelName ).success(function(modelClass)\n {\n models = modelClass.all();\n });\n }\n else if ( isRekord( modelName ) )\n {\n models = modelName.all();\n }\n }\n\n if ( indexOf( database.fields, fieldName ) === false )\n {\n throw fieldName + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $class: modelName,\n $matchField: fieldName,\n $matchAlias: getAlias( fieldName )\n };\n\n return function(value, model, setMessage)\n {\n if ( models && isValue( value ) )\n {\n if ( isInvalid( value, model, models, fieldName ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// if:due_date:before:today|required\n\n// if all rules pass for the given field, continue with remaining rules\nsubRuleGenerator('if',\n function isInvalid(invalidCount, totalCount) {\n return invalidCount > 0;\n }\n);\n\n// if any rules pass for the given field, continue with remaining rules\nsubRuleGenerator('if_any',\n function isInvalid(invalidCount, totalCount) {\n return invalidCount >= totalCount;\n }\n);\n\n// if no rules pass for the given field, continue with remaining rules\nsubRuleGenerator('if_not',\n function isInvalid(invalidCount, totalCount) {\n return invalidCount < totalCount;\n }\n);\n\n\n\nfunction subRuleGenerator(ruleName, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a validation rule argument';\n }\n\n var otherField, otherRules;\n\n if ( isString( params ) )\n {\n var colon = params.indexOf( ':' );\n\n if ( colon === -1 )\n {\n throw params + ' is not a valid argument for the ' + ruleName + ' rule';\n }\n\n otherField = params.substring( 0, colon ) || field;\n otherRules = params.substring( colon + 1 );\n }\n else if ( isArray( params ) )\n {\n otherField = params.shift() || field;\n otherRules = params;\n }\n else if ( isObject( params ) )\n {\n otherField = params.field || field;\n otherRules = params.rules;\n }\n\n if ( indexOf( database.fields, otherField ) === -1 )\n {\n throw otherField + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n if ( !otherRules )\n {\n throw 'rules are required for the ' + ruleName + ' rule';\n }\n\n var validators = Validation.parseRules( otherRules, otherField, database, getAlias );\n\n return function(value, model, setMessage)\n {\n var invalids = 0;\n\n var setInvalid = function(message)\n {\n if ( message )\n {\n invalids++;\n }\n };\n\n for (var i = 0; i < validators.length; i++)\n {\n validators[ i ]( value, model, setInvalid );\n }\n\n return isInvalid( invalids, validators.length ) ? Validation.Stop : value;\n };\n };\n}\n","// in:X,Y,Z,...\nlistRuleGenerator('in',\n '{$alias} must be one of {$list}.',\n function isInvalid(value, model, inList)\n {\n return !inList( value, model );\n }\n);\n\n// not_in:X,Y,Z,...\nlistRuleGenerator('not_in',\n '{$alias} must not be one of {$list}.',\n function isInvalid(value, model, inList)\n {\n return inList( value, model )\n }\n);\n\nfunction listRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a list argument';\n }\n\n var values, inList = false;\n\n if ( isString( params ) )\n {\n values = split( params, /(,)/, '\\\\' );\n }\n else if ( isArray( params ) )\n {\n values = params;\n }\n else if ( isFunction( params ) )\n {\n values = inList;\n }\n\n if ( inList !== false )\n {\n if ( !values || values.length === 0 )\n {\n throw params + ' is not a valid list of values for the ' + ruleName + ' rule';\n }\n }\n\n if ( isPrimitiveArray( values ) )\n {\n var map = mapFromArray( values, true );\n\n inList = function(value)\n {\n return map[ value ];\n };\n }\n else\n {\n inList = function(value)\n {\n return indexOf( values, value, equals );\n };\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var list = joinFriendly( values, 'or' );\n var extra = {\n $params: params,\n $list: list\n };\n\n return function(value, model, setMessage)\n {\n if ( isInvalid( value, model, inList ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// between:3,10\nrangeRuleGenerator('between', {\n 'string': '{$alias} must have between {$start} to {$end} characters.',\n 'number': '{$alias} must be between {$start} and {$end}.',\n 'object': '{$alias} must have between {$start} to {$end} items.'\n },\n function isInvalid(value, start, end) {\n return value < start || value > end;\n }\n);\n\n// not_between\nrangeRuleGenerator('not_between', {\n 'string': '{$alias} must not have between {$start} to {$end} characters.',\n 'number': '{$alias} must not be between {$start} and {$end}.',\n 'object': '{$alias} must not have between {$start} to {$end} items.'\n },\n function isInvalid(value, start, end) {\n return value >= start && value <= end;\n }\n);\n\nfunction rangeRuleGenerator(ruleName, defaultMessages, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a range argument';\n }\n\n var start, end;\n\n if ( isString( params ) )\n {\n var range = split( params, /(\\s*,\\s*)/, '\\\\' );\n\n start = parseFloat( range[0] );\n end = parseFloat( range[1] );\n }\n else if ( isArray( params ) )\n {\n start = params[ 0 ];\n end = params[ 1 ];\n }\n else if ( isObject( params ) )\n {\n start = params.start;\n end = params.end;\n }\n\n if ( isNaN( start ) || isNaN( end ) )\n {\n throw params + ' is not a valid range of numbers for the ' + ruleName + ' rule';\n }\n\n if ( isString( message ) )\n {\n message = {\n 'string': message,\n 'number': message,\n 'object': message\n };\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $start: start,\n $end: end\n };\n\n return function(value, model, setMessage)\n {\n var size = sizeof( value );\n var type = typeof( value );\n var typeMessage = messageTemplate[ type ];\n\n if ( typeMessage && isInvalid( size, start, end ) )\n {\n extra.$size = size;\n\n setMessage( generateMessage( field, getAlias( field ), value, model, typeMessage, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessages;\n}\n","\n\nregexRuleGenerator('alpha',\n '{$alias} should only contain alphabetic characters.',\n /^[a-zA-Z]*$/\n);\n\nregexRuleGenerator('alpha_dash',\n '{$alias} should only contain alpha-numeric characters, dashes, and underscores.',\n /^[a-zA-Z0-9_-]*$/\n);\n\nregexRuleGenerator('alpha_num',\n '{$alias} should only contain alpha-numeric characters.',\n /^[a-zA-Z0-9]*$/\n);\n\nregexRuleGenerator('email',\n '{$alias} is not a valid email.',\n /^.+@.+\\..+$/\n);\n\nregexRuleGenerator('url',\n '{$alias} is not a valid URL.',\n /^(https?:\\/\\/)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)$/\n);\n\nregexRuleGenerator('uri',\n '{$alias} is not a valid URI.',\n /^(\\w+:\\/\\/)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)$/\n);\n\nregexRuleGenerator('phone',\n '{$alias} is not a valid phone number.',\n /^1?\\W*([2-9][0-8][0-9])\\W*([2-9][0-9]{2})\\W*([0-9]{4})(\\se?x?t?(\\d*))?$/\n);\n\nfunction regexRuleGenerator(ruleName, defaultMessage, regex)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n checkNoParams( ruleName, field, params );\n\n var messageTemplate = determineMessage( ruleName, message );\n\n return function(value, model, setMessage)\n {\n if ( !regex.test( value ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n\nValidation.Rules.regex = function(field, params, database, getAlias, message)\n{\n var regex;\n\n if ( isString( params ) )\n {\n var parsed = /^\\/(.*)\\/([gmi]*)$/.exec( params );\n\n if ( parsed )\n {\n regex = new RegExp( parsed[1], parsed[2] );\n }\n }\n else if ( isRegExp( params ) )\n {\n regex = params;\n }\n\n if ( !regex )\n {\n throw params + ' is not a valid regular expression for the regex rule';\n }\n\n var messageTemplate = determineMessage( 'regex', message );\n\n return function(value, model, setMessage)\n {\n if ( !regex.test( value ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n};\n\nValidation.Rules.regex.message = '{$alias} is not a valid value.';\n","// min:3\nsizeRuleGenerator('min', {\n 'string': '{$alias} must have a minimum of {$number} characters.',\n 'number': '{$alias} must be at least {$number}.',\n 'object': '{$alias} must have at least {$number} items.'\n },\n function isInvalid(value, number) {\n return value < number;\n }\n);\n\n// greater_than:0\nsizeRuleGenerator('greater_than', {\n 'string': '{$alias} must have more than {$number} characters.',\n 'number': '{$alias} must be greater than {$number}.',\n 'object': '{$alias} must have more than {$number} items.'\n },\n function isInvalid(value, number) {\n return value <= number;\n }\n);\n\n// max:10\nsizeRuleGenerator('max', {\n 'string': '{$alias} must have no more than {$number} characters.',\n 'number': '{$alias} must be no more than {$number}.',\n 'object': '{$alias} must have no more than {$number} items.'\n },\n function isInvalid(value, number) {\n return value > number;\n }\n);\n\n// less_than:5\nsizeRuleGenerator('less_than', {\n 'string': '{$alias} must have less than {$number} characters.',\n 'number': '{$alias} must be less than {$number}.',\n 'object': '{$alias} must have less than {$number} items.'\n },\n function isInvalid(value, number) {\n return value >= number;\n }\n);\n\n// equal:4.5\nsizeRuleGenerator('equal', {\n 'string': '{$alias} must have {$number} characters.',\n 'number': '{$alias} must equal {$number}.',\n 'object': '{$alias} must have {$number} items.'\n },\n function isInvalid(value, number) {\n return value !== number;\n }\n);\n\n// not_equal:0\nsizeRuleGenerator('not_equal', {\n 'string': '{$alias} must not have {$number} characters.',\n 'number': '{$alias} must not equal {$number}.',\n 'object': '{$alias} must not have {$number} items.'\n },\n function isInvalid(value, number) {\n return value === number;\n }\n);\n\nfunction sizeRuleGenerator(ruleName, defaultMessages, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n var number;\n\n if ( isString( params ) )\n {\n number = parseFloat( params );\n }\n else if ( isNumber( params ) )\n {\n number = params;\n }\n\n if ( isNaN( number ) )\n {\n throw '\"' + params + '\" is not a valid number for the ' + ruleName + ' rule';\n }\n\n if ( isString( message ) )\n {\n message = {\n 'string': message,\n 'number': message,\n 'object': message\n };\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $number: params\n };\n\n return function(value, model, setMessage)\n {\n var size = sizeof( value );\n var type = typeof( value );\n var typeMessage = messageTemplate[ type ];\n\n if ( typeMessage && isInvalid( size, number ) )\n {\n extra.$size = size;\n\n setMessage( generateMessage( field, getAlias( field ), value, model, typeMessage, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessages;\n}\n","Rekord.on( Rekord.Events.Plugins, function(model, db, options)\n{\n var validation = options.validation || Database.Defaults.validation;\n\n if ( isEmpty( validation ) )\n {\n return;\n }\n\n var rules = validation.rules || {};\n var messages = validation.messages || {};\n var aliases = validation.aliases || {};\n var required = !!validation.required;\n\n function getAlias(field)\n {\n return aliases[ field ] || field;\n }\n\n db.validations = {};\n\n for ( var field in rules )\n {\n db.validations[ field ] = Validation.parseRules( rules[ field ], field, db, getAlias, messages[ field ] )\n }\n\n addMethod( model.prototype, '$validate', function()\n {\n var $this = this;\n\n this.$trigger( Model.Events.PreValidate, [this] );\n\n this.$valid = true;\n this.$validations = {};\n this.$validationMessages.length = 0;\n\n for (var field in db.validations)\n {\n var chain = db.validations[ field ];\n var value = this.$get( field );\n var fieldValid = true;\n\n var setMessage = function(message)\n {\n // Only accept for the first valid message\n if ( message && fieldValid )\n {\n fieldValid = false;\n\n $this.$validations[ field ] = message;\n $this.$validationMessages.push( message );\n $this.$valid = false;\n }\n };\n\n for (var i = 0; i < chain.length && fieldValid && value !== Validation.Stop; i++)\n {\n value = chain[ i ]( value, this, setMessage );\n }\n }\n\n this.$trigger( this.$valid ? Model.Events.ValidatePass : Model.Events.ValidateFail, [this] );\n\n return this.$valid;\n });\n\n replaceMethod( model.prototype, '$init', function($init)\n {\n return function()\n {\n this.$valid = undefined;\n this.$validations = {};\n this.$validationMessages = [];\n\n return $init.apply( this, arguments );\n };\n });\n\n if ( required )\n {\n replaceMethod( model.prototype, '$save', function($save)\n {\n return function()\n {\n if ( this.$isDeleted() )\n {\n Rekord.debug( Rekord.Debugs.SAVE_DELETED, this.$db, this );\n\n return Promise.resolve( this );\n }\n\n if ( !this.$validate() )\n {\n return Promise.resolve( this );\n }\n\n return $save.apply( this, arguments );\n };\n });\n }\n});\n\nModel.Events.PreValidate = 'pre-validate';\n\nModel.Events.ValidatePass = 'validate-pass';\n\nModel.Events.ValidateFail = 'validate-fail';\n\nvar Validation =\n{\n Rules: {},\n Expression: {},\n Expressions: [],\n Delimiter: /([|])/,\n Escape: '\\\\',\n RuleSeparator: ':',\n Stop: {},\n\n parseRules: function(rules, field, database, getAlias, message)\n {\n var validators = [];\n\n if ( isString( rules ) )\n {\n rules = split( rules, this.Delimiter, this.Escape );\n }\n\n if ( isArray( rules ) )\n {\n for (var i = 0; i < rules.length; i++)\n {\n var rule = rules[ i ];\n var validator = this.parseRule( rule, field, database, getAlias, message );\n\n validators.push( validator );\n }\n }\n else if ( isObject( rules ) )\n {\n for (var rule in rules)\n {\n var ruleMessageOrData = rules[ rule ];\n\n var ruleMessage = isObject( ruleMessageOrData ) ? ruleMessageOrData.message :\n ( isString( ruleMessageOrData ) ? ruleMessageOrData : undefined );\n\n var ruleInput = isObject( ruleMessageOrData ) && ruleMessageOrData.message ? ruleMessageOrData.input :\n ( isString( ruleMessageOrData ) ? undefined : ruleMessageOrData );\n\n var validator = this.parseRule( rule, field, database, getAlias, ruleMessage || message, ruleInput );\n\n validators.push( validator );\n }\n }\n\n return validators;\n },\n\n parseRule: function(rule, field, database, getAlias, message, input)\n {\n var colon = rule.indexOf( this.RuleSeparator );\n var ruleName = colon === -1 ? rule : rule.substring( 0, colon );\n\n if ( ruleName.charAt( 0 ) === '$' )\n {\n return this.customValidator( ruleName, field, database, getAlias, message );\n }\n\n var ruleParams = colon === -1 ? input : rule.substring( colon + 1 );\n var validatorFactory = Validation.Rules[ ruleName ];\n\n if ( !validatorFactory )\n {\n throw ruleName + ' is not a valid rule';\n }\n\n return validatorFactory( field, ruleParams, database, getAlias, message );\n },\n\n parseExpression: function(expr, database)\n {\n var parsers = Validation.Expressions;\n\n for (var i = 0; i < parsers.length; i++)\n {\n var parser = parsers[ i ];\n var expressionFunction = parser( expr, database );\n\n if ( isFunction( expressionFunction ) )\n {\n return expressionFunction; // (value, model)\n }\n }\n\n return noop;\n },\n\n customValidator: function(functionName, field, database, getAlias, message)\n {\n return function(value, model, setMessage)\n {\n var result = model[ functionName ]( value, getAlias, message );\n\n if ( isString( result ) )\n {\n setMessage( result );\n }\n\n return value;\n };\n }\n};\n","Validation.Expression.date =\nValidation.Expressions.push(function(expr, database)\n{\n var parsed = parseDate( expr );\n\n if ( parsed !== false )\n {\n var parsedTime = parsed.getTime();\n\n return function(value, model)\n {\n return parsedTime;\n };\n }\n}) - 1;\n","Validation.Expression.field =\nValidation.Expressions.push(function(expr, database)\n{\n if ( indexOf( database.fields, expr ) )\n {\n return function(value, model)\n {\n return model.$get( expr );\n };\n }\n}) - 1;\n","\nvar RELATIVE_REGEX = /^([+-]\\d+(\\.\\d+)?)\\s*(.+)$/;\n\nvar RELATIVE_UNITS = {\n ms: 1,\n millisecond: 1,\n milliseconds: 1,\n s: 1000,\n second: 1000,\n seconds: 1000,\n min: 1000 * 60,\n mins: 1000 * 60,\n minute: 1000 * 60,\n minutes: 1000 * 60,\n hr: 1000 * 60 * 60,\n hour: 1000 * 60 * 60,\n hours: 1000 * 60 * 60,\n day: 1000 * 60 * 60 * 24,\n days: 1000 * 60 * 60 * 24,\n wk: 1000 * 60 * 60 * 24 * 7,\n week: 1000 * 60 * 60 * 24 * 7,\n weeks: 1000 * 60 * 60 * 24 * 7,\n month: ['getMonth', 'setMonth'],\n months: ['getMonth', 'setMonth'],\n yr: ['getFullYear', 'setFullYear'],\n year: ['getFullYear', 'setFullYear'],\n years: ['getFullYear', 'setFullYear']\n};\n\nValidation.Expression.relative =\nValidation.Expressions.push(function(expr, database)\n{\n var parsed = RELATIVE_REGEX.exec( expr );\n\n if ( parsed !== null )\n {\n var amount = parseFloat( parsed[ 1 ] );\n var unit = parsed[ 3 ];\n var unitScale = RELATIVE_UNITS[ unit ];\n\n if ( !unitScale )\n {\n throw unit + ' is not a valid unit.';\n }\n\n return function(value, model)\n {\n var relative = new Date();\n\n if ( isNumber( unitScale ) )\n {\n relative.setTime( relative.getTime() + unitScale * amount );\n }\n else\n {\n var getter = unitScale[0];\n var setter = unitScale[1];\n\n relative[ setter ]( relative[ getter ]() + amount );\n }\n\n return relative.getTime();\n };\n }\n}) - 1;\n","Validation.Expression.today =\nValidation.Expressions.push(function(expr, database)\n{\n if ( expr === 'today' )\n {\n return function(value, model)\n {\n var today = new Date();\n\n startOfDay( today );\n\n return today.getTime();\n };\n }\n}) - 1;\n","Validation.Expression.tomorrow =\nValidation.Expressions.push(function(expr, database)\n{\n if ( expr === 'tomorrow' )\n {\n return function(value, model)\n {\n var tomorrow = new Date();\n\n tomorrow.setDate( tomorrow.getDate() + 1 );\n startOfDay( tomorrow );\n\n return tomorrow.getTime();\n };\n }\n}) - 1;\n","Validation.Expression.yesterday =\nValidation.Expressions.push(function(expr, database)\n{\n if ( expr === 'yesterday' )\n {\n return function(value, model)\n {\n var yesterday = new Date();\n\n yesterday.setDate( yesterday.getDate() - 1 );\n startOfDay( yesterday );\n\n return yesterday.getTime();\n };\n }\n}) - 1;\n","// accepted\nValidation.Rules.accepted = function(field, params, database, getAlias, message)\n{\n checkNoParams( 'accepted', field, params );\n\n var messageTemplate = determineMessage( 'accepted', message );\n var acceptable = Validation.Rules.accepted.acceptable;\n\n return function(value, model, setMessage)\n {\n var valueString = (value + '').toLowerCase();\n var accepted = acceptable[ valueString ];\n\n if ( !accepted )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n};\n\nValidation.Rules.accepted.message = '{$alias} has not been accepted.';\n\nValidation.Rules.accepted.acceptable =\n{\n '1': true,\n 'yes': true,\n 'on': true,\n 'y': true,\n 'true': true\n};\n","// required\nruleGenerator('required',\n '{$alias} is required.',\n function isInvalid(value) {\n return isEmpty( value );\n }\n);\n","\nruleGenerator('array',\n '{$alias} must be an array.',\n function isInvalid(value) {\n return !isArray( value );\n }\n);\n\nruleGenerator('object',\n '{$alias} must be an object.',\n function isInvalid(value) {\n return !isObject( value );\n }\n);\n\nruleGenerator('string',\n '{$alias} must be a string.',\n function isInvalid(value) {\n return !isString( value );\n }\n);\n\nruleGenerator('number',\n '{$alias} must be a number.',\n function isInvalid(value) {\n return !isNumber( value );\n }\n);\n\nruleGenerator('boolean',\n '{$alias} must be a true or false.',\n function isInvalid(value) {\n return !isBoolean( value );\n }\n);\n\nruleGenerator('model',\n '{$alias} must have a value.',\n function isInvalid(value) {\n return !(value instanceof Model);\n }\n);\n\nruleGenerator('whole',\n '{$alias} must be a whole number.',\n function isInvalid(value, model, setValue) {\n var parsed = tryParseInt( value );\n var numeric = parseFloat( value );\n var invalid = !isNumber( parsed );\n if ( !invalid ) {\n invalid = Math.floor( parsed ) !== numeric;\n if ( !invalid ) {\n setValue( parsed );\n }\n }\n return invalid;\n }\n);\n\nruleGenerator('numeric',\n '{$alias} must be numeric.',\n function isInvalid(value, model, setValue) {\n var parsed = tryParseFloat( value );\n var invalid = !isNumber( parsed );\n if ( !invalid ) {\n setValue( parsed );\n }\n return invalid;\n }\n);\n\nruleGenerator('yesno',\n '{$alias} must be a yes or no.',\n function isInvalid(value, model, setValue) {\n var mapped = Validation.Rules.yesno.map[ value ];\n var invalid = !isBoolean( mapped );\n if ( !invalid ) {\n setValue( mapped );\n }\n return invalid;\n }\n);\n\nValidation.Rules.yesno.map =\n{\n 'true': true,\n 't': true,\n 'yes': true,\n 'y': true,\n '1': true,\n 'false': false,\n 'f': false,\n 'no': false,\n 'n': false,\n '0': false\n};\n","Validation.Rules.abs = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n\n if ( isNumber( value ) )\n {\n value = Math.abs( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.apply = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n model.$set( field, value );\n \n return value;\n };\n};\n","Validation.Rules.base64 = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n if ( global.btoa )\n {\n value = global.btoa( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.ceil = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n \n if ( isNumber( value ) )\n {\n value = Math.ceil( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.endOfDay = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n return endOfDay( value );\n };\n};\n","Validation.Rules.filter = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n if ( isArray( value ) )\n {\n for (var i = value.length - 1; i >= 0; i--)\n {\n if ( !isValue( value[ i ] ) )\n {\n value.splice( i, 1 );\n }\n }\n }\n else if ( isObject( value ) )\n {\n for (var prop in value)\n {\n if ( !isValue( value[ prop ] ) )\n {\n delete value[ prop ];\n }\n }\n }\n\n return value;\n };\n};\n","Validation.Rules.floor = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n \n if ( isNumber( value ) )\n {\n value = Math.floor( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.mod = function(field, params, database, alias, message)\n{\n var number = tryParseFloat( params );\n\n if ( !isNumber( number ) )\n {\n throw '\"' + number + '\" is not a valid number for the mod rule.';\n }\n\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n\n if ( isNumber( value ) )\n {\n value = value % number;\n }\n\n return value;\n };\n};\n","Validation.Rules.null = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n model.$set( field, null );\n\n return null;\n };\n};\n","Validation.Rules.round = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n\n if ( isNumber( value ) )\n {\n value = Math.round( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.startOfDay = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n return startOfDay( value );\n };\n};\n","Validation.Rules.trim = function(field, params, database, alias, message)\n{\n // String.trim polyfill\n if ( !String.prototype.trim )\n {\n var regex = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n String.prototype.trim = function()\n {\n return this.replace( regex, '' );\n };\n }\n\n return function(value, model, setMessage)\n {\n if ( isString( value ) )\n {\n value = value.trim();\n }\n\n return value;\n };\n};\n","Validation.Rules.unbase64 = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n if ( global.atob )\n {\n value = global.atob( value );\n }\n\n return value;\n };\n};\n","\n\n Rekord.Validation = Validation;\n\n Rekord.ruleGenerator = ruleGenerator;\n Rekord.rangeRuleGenerator = rangeRuleGenerator;\n Rekord.collectionRuleGenerator = collectionRuleGenerator;\n Rekord.dateRuleGenerator = dateRuleGenerator;\n Rekord.fieldListRuleGenerator = fieldListRuleGenerator;\n Rekord.fieldsRuleGenerator = fieldsRuleGenerator;\n Rekord.foreignRuleGenerator = foreignRuleGenerator;\n Rekord.subRuleGenerator = subRuleGenerator;\n Rekord.listRuleGenerator = listRuleGenerator;\n Rekord.regexRuleGenerator = regexRuleGenerator;\n Rekord.sizeRuleGenerator = sizeRuleGenerator;\n\n Rekord.joinFriendly = joinFriendly;\n Rekord.tryParseFloat = tryParseFloat;\n Rekord.tryParseInt = tryParseInt;\n Rekord.startOfDay = startOfDay;\n Rekord.endOfDay = endOfDay;\n Rekord.determineMessage = determineMessage;\n Rekord.mapFromArray = mapFromArray;\n Rekord.checkNoParams = checkNoParams;\n Rekord.generateMessage = generateMessage;\n\n})(this, Rekord);\n"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["header.js","util.js","rules/collection.js","rules/dates.js","rules/field_list.js","rules/fields.js","rules/foreign.js","rules/if.js","rules/list.js","rules/range.js","rules/regex.js","rules/sizes.js","validation.js","expressions/date.js","expressions/field.js","expressions/relative.js","expressions/today.js","expressions/tomorrow.js","expressions/yesterday.js","rules/accepted.js","rules/required.js","rules/types.js","transforms/abs.js","transforms/apply.js","transforms/base64.js","transforms/ceil.js","transforms/endOfDay.js","transforms/filter.js","transforms/floor.js","transforms/mod.js","transforms/null.js","transforms/round.js","transforms/startOfDay.js","transforms/trim.js","transforms/unbase64.js","footer.js"],"names":["global","Rekord","undefined","tryParseFloat","x","parsed","parseFloat","isNaN","tryParseInt","parseInt","startOfDay","d","isDate","setHours","isNumber","endOfDay","ruleGenerator","ruleName","defaultMessage","isInvalid","Validation","Rules","field","params","database","getAlias","message","checkNoParams","messageTemplate","determineMessage","value","model","setMessage","setValue","newValue","generateMessage","joinFriendly","arr","lastSeparatorCustom","itemSeparatorCustom","copy","slice","i","length","last","pop","lastSeparator","itemSeparator","join","mapFromArray","map","alias","extra","isFunction","base","$field","$alias","$value","transfer","isObject","format","collectionRuleGenerator","matchField","matchValue","equality","isString","comma","indexOf","substring","isArray","equals","equalsCompare","fields","$matchField","$matchAlias","$matchValue","dateRuleGenerator","dateExpression","parseExpression","parseDate","parsedTime","getTime","noop","$date","date","fieldListRuleGenerator","matchValues","parts","split","shift","values","list","$params","$list","fieldsRuleGenerator","fieldNames","fieldAliases","$fields","$fieldAliases","foreignRuleGenerator","modelName","models","fieldName","isValue","name","ModelCollection","get","success","modelClass","all","isRekord","$class","subRuleGenerator","otherField","otherRules","colon","rules","validators","parseRules","invalids","setInvalid","Stop","listRuleGenerator","inList","isPrimitiveArray","rangeRuleGenerator","defaultMessages","start","end","range","string","number","object","$start","$end","size","sizeof","type","typeMessage","$size","regexRuleGenerator","regex","test","sizeRuleGenerator","$number","Model","Database","Promise","Collection","isEmpty","isBoolean","isRegExp","addMethod","replaceMethod","on","Events","Plugins","db","options","aliases","validation","Defaults","messages","required","validations","prototype","$this","this","$trigger","PreValidate","$valid","$validations","$validationMessages","chain","$get","fieldValid","push","ValidatePass","ValidateFail","$init","apply","arguments","$save","$isDeleted","debug","Debugs","SAVE_DELETED","$db","resolve","$validate","Expression","Expressions","Delimiter","Escape","RuleSeparator","rule","defaultMessageValidator","parseRule","ruleProperty","ruleMessageOrData","ruleMessage","ruleInput","input","customMessageValidator","charAt","customValidator","ruleParams","validatorFactory","expr","parsers","parser","expressionFunction","functionName","result","RELATIVE_REGEX","RELATIVE_UNITS","ms","millisecond","milliseconds","s","second","seconds","min","mins","minute","minutes","hr","hour","hours","day","days","wk","week","weeks","month","months","yr","year","years","relative","exec","amount","unit","unitScale","Date","setTime","getter","setter","today","tomorrow","setDate","getDate","yesterday","accepted","acceptable","valueString","toLowerCase","1","yes","y","true","contains","m","validate","messageOption","invalid","related","pluck","confirmed","different","valid","invalidCount","totalCount","RegExp","numeric","Math","floor","mapped","yesno","t","false","f","no","n","0","abs","$set","base64","btoa","ceil","filter","splice","prop","mod","round","trim","String","replace","unbase64","atob"],"mappings":"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","file":"rekord-validation.min.js","sourcesContent":["(function(global, Rekord, undefined)\n{\n var Model = Rekord.Model;\n var Database = Rekord.Database;\n var Promise = Rekord.Promise;\n var Collection = Rekord.Collection;\n var ModelCollection = Rekord.ModelCollection;\n\n var isEmpty = Rekord.isEmpty;\n var isString = Rekord.isString;\n var isArray = Rekord.isArray;\n var isObject = Rekord.isObject;\n var isFunction = Rekord.isFunction;\n var isDate = Rekord.isDate;\n var isNumber = Rekord.isNumber;\n var isBoolean = Rekord.isBoolean;\n var isValue = Rekord.isValue;\n var isPrimitiveArray = Rekord.isPrimitiveArray;\n var isRegExp = Rekord.isRegExp;\n var isRekord = Rekord.isRekord;\n\n var noop = Rekord.noop;\n var equalsCompare = Rekord.equalsCompare;\n var equals = Rekord.equals;\n var indexOf = Rekord.indexOf;\n var sizeof = Rekord.sizeof;\n\n var split = Rekord.split;\n var transfer = Rekord.transfer;\n var format = Rekord.format;\n\n var parseDate = Rekord.parseDate;\n\n var addMethod = Rekord.addMethod;\n var replaceMethod = Rekord.replaceMethod;\n","function tryParseFloat(x)\n{\n var parsed = parseFloat( x );\n\n if ( !isNaN( parsed ) )\n {\n x = parsed;\n }\n\n return x;\n}\n\nfunction tryParseInt(x)\n{\n var parsed = parseInt( x );\n\n if ( !isNaN( parsed ) )\n {\n x = parsed;\n }\n\n return x;\n}\n\nfunction startOfDay(d)\n{\n if ( isDate( d ) )\n {\n d.setHours( 0, 0, 0, 0 );\n }\n else if ( isNumber( d ) )\n {\n d = d - (d % 86400000);\n }\n\n return d;\n}\n\nfunction endOfDay(d)\n{\n if ( isDate( d ) )\n {\n d.setHours( 23, 59, 59, 999 );\n }\n else if ( isNumber( d ) )\n {\n d = d - (d % 86400000) + 86400000 - 1;\n }\n\n return d;\n}\n\nfunction ruleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n checkNoParams( ruleName, field, params );\n\n var messageTemplate = determineMessage( ruleName, message );\n\n return function(value, model, setMessage)\n {\n function setValue( newValue )\n {\n value = newValue;\n }\n\n if ( isInvalid( value, model, setValue ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n\nfunction determineMessage(ruleName, message)\n{\n return message || Validation.Rules[ ruleName ].message;\n}\n\nfunction joinFriendly(arr, lastSeparatorCustom, itemSeparatorCustom, getAlias)\n{\n var copy = arr.slice();\n\n if ( getAlias )\n {\n for (var i = 0; i < copy.length; i++)\n {\n copy[ i ] = getAlias( copy[ i ] );\n }\n }\n\n var last = copy.pop();\n var lastSeparator = lastSeparatorCustom || 'and';\n var itemSeparator = itemSeparatorCustom || ', ';\n\n switch (copy.length) {\n case 0:\n return last;\n case 1:\n return copy[ 0 ] + ' ' + lastSeparator + ' ' + last;\n default:\n return copy.join( itemSeparator ) + itemSeparator + lastSeparator + ' ' + last;\n }\n}\n\nfunction mapFromArray(arr, value)\n{\n var map = {};\n\n for (var i = 0; i < arr.length; i++)\n {\n map[ arr[ i ] ] = value;\n }\n\n return map;\n}\n\nfunction checkNoParams(ruleName, field, params)\n{\n if ( params )\n {\n throw 'the rule ' + ruleName + ' for field ' + field + ' has no arguments';\n }\n}\n\nfunction generateMessage(field, alias, value, model, message, extra)\n{\n if ( isFunction( message ) )\n {\n message = message( field, alias, value, model, extra );\n }\n\n var base = {};\n base.$field = field;\n base.$alias = alias;\n base.$value = value;\n\n transfer( model, base );\n\n if ( isObject( extra ) )\n {\n transfer( extra, base );\n }\n\n return format( message, base );\n}\n","// contains:field,value\ncollectionRuleGenerator('contains',\n '{$alias} does not contain an item whose {$matchAlias} equals {$matchValue}.',\n function isInvalid(value, model, matchField, matchValue, equality)\n {\n return !value.contains(function isMatch(m)\n {\n return m !== model && equality( matchValue, m.$get( matchField ) );\n });\n }\n);\n\n// not_contains:field,value\ncollectionRuleGenerator('not_contains',\n '{$alias} contains an item whose {$matchAlias} equals {$matchValue}.',\n function isInvalid(value, model, matchField, matchValue, equality)\n {\n return value.contains(function isMatch(m)\n {\n return m !== model && equality( matchValue, m.$get( matchField ) );\n });\n }\n);\n\nfunction collectionRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires field & value arguments';\n }\n\n var matchField, matchValue, equality;\n\n if ( isString( params ) )\n {\n var comma = params.indexOf(',');\n\n if ( comma === -1 )\n {\n throw ruleName + ' validation rule requires field & value arguments';\n }\n\n matchField = params.substring( 0, comma );\n matchValue = params.substring( comma + 1 );\n }\n else if ( isArray( params ) )\n {\n matchField = params[ 0 ];\n matchValue = params[ 1 ];\n equality = params[ 2 ];\n }\n else if ( isObject( params ) )\n {\n matchField = params.field;\n matchValue = params.value;\n equality = params.equals;\n }\n\n if ( !isFunction( equality ) )\n {\n equality = equalsCompare;\n }\n\n if ( indexOf( database.fields, matchField ) === -1 )\n {\n throw matchField + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $matchField: matchField,\n $matchAlias: getAlias( matchField ),\n $matchValue: matchValue\n };\n\n return function(value, model, setMessage)\n {\n if ( isInvalid( value, model, matchField, matchValue, equality ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n\nValidation.Rules.validate = function(field, params, database, getAlias, message)\n{\n // message, models, validations\n var messageOption = params || 'message';\n var messageTemplate = determineMessage( 'validate', message );\n\n return function(value, model, setMessage)\n {\n if ( isArray( value ) )\n {\n var invalid = new Collection();\n\n for (var i = 0; i < value.length; i++)\n {\n var related = value[ i ];\n\n if ( related && related.$validate && !related.$validate() )\n {\n invalid.push( related );\n }\n }\n\n if ( invalid.length )\n {\n switch (messageOption)\n {\n case 'models':\n setMessage( invalid );\n break;\n case 'validations':\n setMessage( invalid.pluck( '$validations', '$$key' ) );\n break;\n default: // message\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n break;\n }\n }\n }\n\n return value;\n };\n};\n\nValidation.Rules.validate.message = '{$alias} is not valid.';\n","// after:today\ndateRuleGenerator('after',\n '{$alias} must be after {$date}.',\n function isInvalid(value, date) {\n return value < endOfDay( date );\n }\n);\n\n// after_on:tomorrow\ndateRuleGenerator('after_on',\n '{$alias} must be after or equal to {$date}.',\n function isInvalid(value, date) {\n return value < date;\n }\n);\n\n// before:yesterday\ndateRuleGenerator('before',\n '{$alias} must be before {$date}.',\n function isInvalid(value, date) {\n return value > date;\n }\n);\n\n// before_on:+2days\ndateRuleGenerator('before_on',\n '{$alias} must be before or equal to {$date}.',\n function isInvalid(value, date) {\n return value > endOfDay( date );\n }\n);\n\n// date\nruleGenerator('date_like',\n '{$alias} must be a valid date.',\n function isInvalid(value, model, setValue) {\n var parsed = parseDate( value );\n var invalid = parsed === false;\n if ( !invalid ) {\n setValue( parsed.getTime() );\n }\n return invalid;\n }\n);\n\nfunction dateRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a date expression argument';\n }\n\n var dateExpression;\n\n if ( isString( params ) )\n {\n dateExpression = Validation.parseExpression( params, database );\n }\n else if ( isFunction( params ) )\n {\n dateExpression = params;\n }\n else\n {\n var parsed = parseDate( params );\n\n if ( parsed !== false )\n {\n var parsedTime = parsed.getTime();\n\n dateExpression = function()\n {\n return parsedTime;\n };\n }\n }\n\n if ( !dateExpression || dateExpression === noop )\n {\n throw params + ' is not a valid date expression for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $date: params\n };\n\n return function(value, model, setMessage)\n {\n var parsed = parseDate( value );\n\n if ( parsed !== false )\n {\n value = parsed.getTime();\n\n var date = dateExpression( value, model );\n\n if ( isNumber( date ) && isInvalid( value, date ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","\n// required_if:X,Y,...\nfieldListRuleGenerator('required_if',\n '{$alias} is required.',\n function isInvalid(value, model, field, values, map) {\n var required = map[ model.$get( field ) ];\n\n return required && isEmpty( value );\n }\n);\n\n// required_unless:X,Y,...\nfieldListRuleGenerator('required_unless',\n '{$alias} is required.',\n function isInvalid(value, model, field, values, map) {\n var required = !map[ model.$get( field ) ];\n\n return required && isEmpty( value );\n }\n);\n\nfunction fieldListRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a field and list arguments';\n }\n\n var matchField, matchValues;\n\n if ( isString( params ) )\n {\n var parts = split( params, /(,)/, '\\\\' );\n\n matchField = parts.shift();\n matchValues = parts;\n }\n else if ( isArray( params ) )\n {\n matchField = params.shift();\n matchValues = params;\n }\n else if ( isObject( params ) )\n {\n matchField = params.field;\n matchValues = params.values;\n }\n\n if ( indexOf( database.fields, matchField ) === false )\n {\n throw matchField + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var list = joinFriendly( matchValues );\n var extra = {\n $params: params,\n $matchField: matchField,\n $matchAlias: getAlias( matchField ),\n $list: list\n };\n var map = mapFromArray( matchValues, true );\n\n return function(value, model, setMessage)\n {\n if ( isInvalid( value, model, matchField, matchValues, map ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// confirmed:X\nfieldsRuleGenerator('confirmed',\n '{$alias} must match {$fieldAliases}.',\n function isInvalid(value, model, fields, setValue) {\n var confirmed = true;\n\n for (var i = 0; i < fields.length; i++)\n {\n if ( !equals( value, model.$get( fields[ i ] ) ) )\n {\n confirmed = false;\n }\n }\n\n return !confirmed;\n }\n);\n\n// different:X\nfieldsRuleGenerator('different',\n '{$alias} must not match {$fieldAliases}.',\n function isInvalid(value, model, fields, setValue) {\n var different = false;\n\n for (var i = 0; i < fields.length; i++)\n {\n if ( !equals( value, model.$get( fields[ i ] ) ) )\n {\n different = true;\n }\n }\n\n return !different;\n }\n);\n\n// if_valid:X\nfieldsRuleGenerator('if_valid',\n '',\n function isInvalid(value, model, fields, setValue) {\n var valid = true;\n\n for (var i = 0; i < fields.length && valid; i++)\n {\n if ( model.$validations[ fields[ i ] ] )\n {\n valid = false;\n }\n }\n\n if ( !valid )\n {\n setValue( Validation.Stop );\n }\n\n return false;\n }\n);\n\n// The field under validation must be present only if any of the other specified fields are present.\n// required_with:X,Y,...\nfieldsRuleGenerator('required_with',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = false;\n\n for (var i = 0; i < fields.length && !required; i++)\n {\n if ( !isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = true;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\n// The field under validation must be present only if all of the other specified fields are present.\n// required_with_all:X,Y,...\nfieldsRuleGenerator('required_with_all',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = true;\n\n for (var i = 0; i < fields.length && required; i++)\n {\n if ( isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = false;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\n// The field under validation must be present only when any of the other specified fields are not present.\n// required_without:X,Y,...\nfieldsRuleGenerator('required_without',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = false;\n\n for (var i = 0; i < fields.length && !required; i++)\n {\n if ( isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = true;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\n// The field under validation must be present only when all of the other specified fields are not present.\n// required_without_all:X,Y,...\nfieldsRuleGenerator('required_without_all',\n '{$alias} is required.',\n function isInvalid(value, model, fields, setValue) {\n var required = true;\n\n for (var i = 0; i < fields.length && required; i++)\n {\n if ( !isEmpty( model.$get( fields[ i ] ) ) )\n {\n required = false;\n }\n }\n\n return required && isEmpty( value );\n }\n);\n\nfunction fieldsRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires an array of fields argument';\n }\n\n var fields = split( params, /(\\s*,\\s*)/, '\\\\' );\n\n for (var i = 0; i < fields.length; i++)\n {\n if ( indexOf( database.fields, fields[ i ] ) === -1 )\n {\n throw fields[ i ] + ' is not a valid field for the ' + ruleName + ' rule';\n }\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var fieldNames = joinFriendly( fields );\n var fieldAliases = joinFriendly( fields, false, false, getAlias );\n var extra = {\n $fields: fieldNames,\n $fieldAliases: fieldAliases\n };\n\n return function(value, model, setMessage)\n {\n function setValue( newValue )\n {\n value = newValue;\n }\n\n if ( isInvalid( value, model, fields, setValue ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// exists:X,Y\nforeignRuleGenerator('exists',\n '{$alias} must match an existing {$matchAlias} in a {$class}',\n function isInvalid(value, model, models, fieldName)\n {\n return !models.contains(function isDifferentMatch(m)\n {\n return m !== model && equals( value, m.$get( fieldName ) );\n });\n }\n);\n\n// unique:X,Y\nforeignRuleGenerator('unique',\n '{$alias} must be a unique {$matchAlias} in a {$class}',\n function isInvalid(value, model, models, fieldName)\n {\n return models.contains(function isDifferentMatch(m)\n {\n return m !== model && equals( value, m.$get( fieldName ) );\n });\n }\n);\n\n// 'ruleName'\n// 'ruleName:name'\n// 'ruleName:,field'\n// 'ruleName:name,field'\n// 'ruleName:name,field': '...'\n// 'ruleName': {input: {field: 'field', model: 'name'}, message: '...'}\n// 'ruleName': {input: {field: 'field', model: ModelClass}, message: '...'}\n// 'ruleName': {input: {field: 'field', models: [...]}, message: '...'}\n// 'ruleName': {field: 'field', model: 'name'}\n// 'ruleName': {field: 'field', model: ModelClass}\n// 'ruleName': {field: 'field', models: [...]}\nfunction foreignRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n var modelName, models, fieldName;\n\n if ( !isValue( params ) || isString( params ) )\n {\n var parts = split( params || '', /(\\s*,\\s*)/, '\\\\' );\n modelName = parts[0] || database.name;\n fieldName = parts[1] || field;\n models = null;\n }\n else if ( isArray( params ) )\n {\n modelName = isString( params[0] ) ? params.shift() : database.name;\n fieldName = isString( params[0] ) ? params.shift() : field;\n models = new ModelCollection( database, params );\n }\n else if ( isObject( params ) )\n {\n modelName = params.model || database.name;\n fieldName = params.field || field;\n models = params.models;\n }\n\n if ( !models )\n {\n if ( !modelName )\n {\n throw 'model, model class, or models is required for ' + ruleName + ' rule';\n }\n\n if ( isString( modelName ) )\n {\n Rekord.get( modelName ).success(function(modelClass)\n {\n models = modelClass.all();\n });\n }\n else if ( isRekord( modelName ) )\n {\n models = modelName.all();\n }\n }\n\n if ( indexOf( database.fields, fieldName ) === false )\n {\n throw fieldName + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $class: modelName,\n $matchField: fieldName,\n $matchAlias: getAlias( fieldName )\n };\n\n return function(value, model, setMessage)\n {\n if ( models && isValue( value ) )\n {\n if ( isInvalid( value, model, models, fieldName ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// if:due_date:before:today|required\n\n// if all rules pass for the given field, continue with remaining rules\nsubRuleGenerator('if',\n function isInvalid(invalidCount, totalCount) {\n return invalidCount > 0;\n }\n);\n\n// if any rules pass for the given field, continue with remaining rules\nsubRuleGenerator('if_any',\n function isInvalid(invalidCount, totalCount) {\n return invalidCount >= totalCount;\n }\n);\n\n// if no rules pass for the given field, continue with remaining rules\nsubRuleGenerator('if_not',\n function isInvalid(invalidCount, totalCount) {\n return invalidCount < totalCount;\n }\n);\n\n\n\nfunction subRuleGenerator(ruleName, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a validation rule argument';\n }\n\n var otherField, otherRules;\n\n if ( isString( params ) )\n {\n var colon = params.indexOf( ':' );\n\n if ( colon === -1 )\n {\n throw params + ' is not a valid argument for the ' + ruleName + ' rule';\n }\n\n otherField = params.substring( 0, colon ) || field;\n otherRules = params.substring( colon + 1 );\n }\n else if ( isArray( params ) )\n {\n otherField = params.shift() || field;\n otherRules = params;\n }\n else if ( isObject( params ) )\n {\n otherField = params.field || field;\n otherRules = params.rules;\n }\n\n if ( indexOf( database.fields, otherField ) === -1 )\n {\n throw otherField + ' is not a valid field for the ' + ruleName + ' rule';\n }\n\n if ( !otherRules )\n {\n throw 'rules are required for the ' + ruleName + ' rule';\n }\n\n var validators = Validation.parseRules( otherRules, otherField, database, getAlias );\n\n return function(value, model, setMessage)\n {\n var invalids = 0;\n\n var setInvalid = function(message)\n {\n if ( message )\n {\n invalids++;\n }\n };\n\n for (var i = 0; i < validators.length; i++)\n {\n validators[ i ]( value, model, setInvalid );\n }\n\n return isInvalid( invalids, validators.length ) ? Validation.Stop : value;\n };\n };\n}\n","// in:X,Y,Z,...\nlistRuleGenerator('in',\n '{$alias} must be one of {$list}.',\n function isInvalid(value, model, inList)\n {\n return !inList( value, model );\n }\n);\n\n// not_in:X,Y,Z,...\nlistRuleGenerator('not_in',\n '{$alias} must not be one of {$list}.',\n function isInvalid(value, model, inList)\n {\n return inList( value, model );\n }\n);\n\nfunction listRuleGenerator(ruleName, defaultMessage, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a list argument';\n }\n\n var values, inList = false;\n\n if ( isString( params ) )\n {\n values = split( params, /(,)/, '\\\\' );\n }\n else if ( isArray( params ) )\n {\n values = params;\n }\n else if ( isFunction( params ) )\n {\n values = inList;\n }\n\n if ( inList !== false )\n {\n if ( !values || values.length === 0 )\n {\n throw params + ' is not a valid list of values for the ' + ruleName + ' rule';\n }\n }\n\n if ( isPrimitiveArray( values ) )\n {\n var map = mapFromArray( values, true );\n\n inList = function(value)\n {\n return map[ value ];\n };\n }\n else\n {\n inList = function(value)\n {\n return indexOf( values, value, equals );\n };\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var list = joinFriendly( values, 'or' );\n var extra = {\n $params: params,\n $list: list\n };\n\n return function(value, model, setMessage)\n {\n if ( isInvalid( value, model, inList ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate, extra ) );\n }\n\n return value;\n };\n };\n\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n","// between:3,10\nrangeRuleGenerator('between', {\n 'string': '{$alias} must have between {$start} to {$end} characters.',\n 'number': '{$alias} must be between {$start} and {$end}.',\n 'object': '{$alias} must have between {$start} to {$end} items.'\n },\n function isInvalid(value, start, end) {\n return value < start || value > end;\n }\n);\n\n// not_between\nrangeRuleGenerator('not_between', {\n 'string': '{$alias} must not have between {$start} to {$end} characters.',\n 'number': '{$alias} must not be between {$start} and {$end}.',\n 'object': '{$alias} must not have between {$start} to {$end} items.'\n },\n function isInvalid(value, start, end) {\n return value >= start && value <= end;\n }\n);\n\nfunction rangeRuleGenerator(ruleName, defaultMessages, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n if ( !params )\n {\n throw ruleName + ' validation rule requires a range argument';\n }\n\n var start, end;\n\n if ( isString( params ) )\n {\n var range = split( params, /(\\s*,\\s*)/, '\\\\' );\n\n start = parseFloat( range[0] );\n end = parseFloat( range[1] );\n }\n else if ( isArray( params ) )\n {\n start = params[ 0 ];\n end = params[ 1 ];\n }\n else if ( isObject( params ) )\n {\n start = params.start;\n end = params.end;\n }\n\n if ( isNaN( start ) || isNaN( end ) )\n {\n throw params + ' is not a valid range of numbers for the ' + ruleName + ' rule';\n }\n\n if ( isString( message ) )\n {\n message = {\n 'string': message,\n 'number': message,\n 'object': message\n };\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $start: start,\n $end: end\n };\n\n return function(value, model, setMessage)\n {\n var size = sizeof( value );\n var type = typeof( value );\n var typeMessage = messageTemplate[ type ];\n\n if ( typeMessage && isInvalid( size, start, end ) )\n {\n extra.$size = size;\n\n setMessage( generateMessage( field, getAlias( field ), value, model, typeMessage, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessages;\n}\n","\n\nregexRuleGenerator('alpha',\n '{$alias} should only contain alphabetic characters.',\n /^[a-zA-Z]*$/\n);\n\nregexRuleGenerator('alpha_dash',\n '{$alias} should only contain alpha-numeric characters, dashes, and underscores.',\n /^[a-zA-Z0-9_-]*$/\n);\n\nregexRuleGenerator('alpha_num',\n '{$alias} should only contain alpha-numeric characters.',\n /^[a-zA-Z0-9]*$/\n);\n\nregexRuleGenerator('email',\n '{$alias} is not a valid email.',\n /^.+@.+\\..+$/\n);\n\nregexRuleGenerator('url',\n '{$alias} is not a valid URL.',\n /^(https?:\\/\\/)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)$/\n);\n\nregexRuleGenerator('uri',\n '{$alias} is not a valid URI.',\n /^(\\w+:\\/\\/)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)$/\n);\n\nregexRuleGenerator('phone',\n '{$alias} is not a valid phone number.',\n /^1?\\W*([2-9][0-8][0-9])\\W*([2-9][0-9]{2})\\W*([0-9]{4})(\\se?x?t?(\\d*))?$/\n);\n\nfunction regexRuleGenerator(ruleName, defaultMessage, regex)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n checkNoParams( ruleName, field, params );\n\n var messageTemplate = determineMessage( ruleName, message );\n\n return function(value, model, setMessage)\n {\n if ( !regex.test( value ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessage;\n}\n\nValidation.Rules.regex = function(field, params, database, getAlias, message)\n{\n var regex;\n\n if ( isString( params ) )\n {\n var parsed = /^\\/(.*)\\/([gmi]*)$/.exec( params );\n\n if ( parsed )\n {\n regex = new RegExp( parsed[1], parsed[2] );\n }\n }\n else if ( isRegExp( params ) )\n {\n regex = params;\n }\n\n if ( !regex )\n {\n throw params + ' is not a valid regular expression for the regex rule';\n }\n\n var messageTemplate = determineMessage( 'regex', message );\n\n return function(value, model, setMessage)\n {\n if ( !regex.test( value ) )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n};\n\nValidation.Rules.regex.message = '{$alias} is not a valid value.';\n","// min:3\nsizeRuleGenerator('min', {\n 'string': '{$alias} must have a minimum of {$number} characters.',\n 'number': '{$alias} must be at least {$number}.',\n 'object': '{$alias} must have at least {$number} items.'\n },\n function isInvalid(value, number) {\n return value < number;\n }\n);\n\n// greater_than:0\nsizeRuleGenerator('greater_than', {\n 'string': '{$alias} must have more than {$number} characters.',\n 'number': '{$alias} must be greater than {$number}.',\n 'object': '{$alias} must have more than {$number} items.'\n },\n function isInvalid(value, number) {\n return value <= number;\n }\n);\n\n// max:10\nsizeRuleGenerator('max', {\n 'string': '{$alias} must have no more than {$number} characters.',\n 'number': '{$alias} must be no more than {$number}.',\n 'object': '{$alias} must have no more than {$number} items.'\n },\n function isInvalid(value, number) {\n return value > number;\n }\n);\n\n// less_than:5\nsizeRuleGenerator('less_than', {\n 'string': '{$alias} must have less than {$number} characters.',\n 'number': '{$alias} must be less than {$number}.',\n 'object': '{$alias} must have less than {$number} items.'\n },\n function isInvalid(value, number) {\n return value >= number;\n }\n);\n\n// equal:4.5\nsizeRuleGenerator('equal', {\n 'string': '{$alias} must have {$number} characters.',\n 'number': '{$alias} must equal {$number}.',\n 'object': '{$alias} must have {$number} items.'\n },\n function isInvalid(value, number) {\n return value !== number;\n }\n);\n\n// not_equal:0\nsizeRuleGenerator('not_equal', {\n 'string': '{$alias} must not have {$number} characters.',\n 'number': '{$alias} must not equal {$number}.',\n 'object': '{$alias} must not have {$number} items.'\n },\n function isInvalid(value, number) {\n return value === number;\n }\n);\n\nfunction sizeRuleGenerator(ruleName, defaultMessages, isInvalid)\n{\n Validation.Rules[ ruleName ] = function(field, params, database, getAlias, message)\n {\n var number;\n\n if ( isString( params ) )\n {\n number = parseFloat( params );\n }\n else if ( isNumber( params ) )\n {\n number = params;\n }\n\n if ( isNaN( number ) )\n {\n throw '\"' + params + '\" is not a valid number for the ' + ruleName + ' rule';\n }\n\n if ( isString( message ) )\n {\n message = {\n 'string': message,\n 'number': message,\n 'object': message\n };\n }\n\n var messageTemplate = determineMessage( ruleName, message );\n var extra = {\n $number: params\n };\n\n return function(value, model, setMessage)\n {\n var size = sizeof( value );\n var type = typeof( value );\n var typeMessage = messageTemplate[ type ];\n\n if ( typeMessage && isInvalid( size, number ) )\n {\n extra.$size = size;\n\n setMessage( generateMessage( field, getAlias( field ), value, model, typeMessage, extra ) );\n }\n\n return value;\n };\n };\n\n Validation.Rules[ ruleName ].message = defaultMessages;\n}\n","Rekord.on( Rekord.Events.Plugins, function(model, db, options)\n{\n var validation = options.validation || Database.Defaults.validation;\n\n if ( isEmpty( validation ) )\n {\n return;\n }\n\n var rules = validation.rules || {};\n var messages = validation.messages || {};\n var aliases = validation.aliases || {};\n var required = !!validation.required;\n\n function getAlias(field)\n {\n return aliases[ field ] || field;\n }\n\n db.validations = {};\n\n for ( var field in rules )\n {\n db.validations[ field ] = Validation.parseRules( rules[ field ], field, db, getAlias, messages[ field ] );\n }\n\n addMethod( model.prototype, '$validate', function()\n {\n var $this = this;\n\n this.$trigger( Model.Events.PreValidate, [this] );\n\n this.$valid = true;\n this.$validations = {};\n this.$validationMessages.length = 0;\n\n for (var field in db.validations)\n {\n var chain = db.validations[ field ];\n var value = this.$get( field );\n var fieldValid = true;\n\n var setMessage = function(message) // jshint ignore:line\n {\n // Only accept for the first valid message\n if ( message && fieldValid )\n {\n fieldValid = false;\n\n $this.$validations[ field ] = message;\n $this.$validationMessages.push( message );\n $this.$valid = false;\n }\n };\n\n for (var i = 0; i < chain.length && fieldValid && value !== Validation.Stop; i++)\n {\n value = chain[ i ]( value, this, setMessage );\n }\n }\n\n this.$trigger( this.$valid ? Model.Events.ValidatePass : Model.Events.ValidateFail, [this] );\n\n return this.$valid;\n });\n\n replaceMethod( model.prototype, '$init', function($init)\n {\n return function()\n {\n this.$valid = undefined;\n this.$validations = {};\n this.$validationMessages = [];\n\n return $init.apply( this, arguments );\n };\n });\n\n if ( required )\n {\n replaceMethod( model.prototype, '$save', function($save)\n {\n return function()\n {\n if ( this.$isDeleted() )\n {\n Rekord.debug( Rekord.Debugs.SAVE_DELETED, this.$db, this );\n\n return Promise.resolve( this );\n }\n\n if ( !this.$validate() )\n {\n return Promise.resolve( this );\n }\n\n return $save.apply( this, arguments );\n };\n });\n }\n});\n\nModel.Events.PreValidate = 'pre-validate';\n\nModel.Events.ValidatePass = 'validate-pass';\n\nModel.Events.ValidateFail = 'validate-fail';\n\nvar Validation =\n{\n Rules: {},\n Expression: {},\n Expressions: [],\n Delimiter: /([|])/,\n Escape: '\\\\',\n RuleSeparator: ':',\n Stop: {},\n\n parseRules: function(rules, field, database, getAlias, message)\n {\n var validators = [];\n\n if ( isString( rules ) )\n {\n rules = split( rules, this.Delimiter, this.Escape );\n }\n\n if ( isArray( rules ) )\n {\n for (var i = 0; i < rules.length; i++)\n {\n var rule = rules[ i ];\n var defaultMessageValidator = this.parseRule( rule, field, database, getAlias, message );\n\n validators.push( defaultMessageValidator );\n }\n }\n else if ( isObject( rules ) )\n {\n for (var ruleProperty in rules)\n {\n var ruleMessageOrData = rules[ ruleProperty ];\n\n var ruleMessage = isObject( ruleMessageOrData ) ? ruleMessageOrData.message :\n ( isString( ruleMessageOrData ) ? ruleMessageOrData : undefined );\n\n var ruleInput = isObject( ruleMessageOrData ) && ruleMessageOrData.message ? ruleMessageOrData.input :\n ( isString( ruleMessageOrData ) ? undefined : ruleMessageOrData );\n\n var customMessageValidator = this.parseRule( ruleProperty, field, database, getAlias, ruleMessage || message, ruleInput );\n\n validators.push( customMessageValidator );\n }\n }\n\n return validators;\n },\n\n parseRule: function(rule, field, database, getAlias, message, input)\n {\n var colon = rule.indexOf( this.RuleSeparator );\n var ruleName = colon === -1 ? rule : rule.substring( 0, colon );\n\n if ( ruleName.charAt( 0 ) === '$' )\n {\n return this.customValidator( ruleName, field, database, getAlias, message );\n }\n\n var ruleParams = colon === -1 ? input : rule.substring( colon + 1 );\n var validatorFactory = Validation.Rules[ ruleName ];\n\n if ( !validatorFactory )\n {\n throw ruleName + ' is not a valid rule';\n }\n\n return validatorFactory( field, ruleParams, database, getAlias, message );\n },\n\n parseExpression: function(expr, database)\n {\n var parsers = Validation.Expressions;\n\n for (var i = 0; i < parsers.length; i++)\n {\n var parser = parsers[ i ];\n var expressionFunction = parser( expr, database );\n\n if ( isFunction( expressionFunction ) )\n {\n return expressionFunction; // (value, model)\n }\n }\n\n return noop;\n },\n\n customValidator: function(functionName, field, database, getAlias, message)\n {\n return function(value, model, setMessage)\n {\n var result = model[ functionName ]( value, getAlias, message );\n\n if ( isString( result ) )\n {\n setMessage( result );\n }\n\n return value;\n };\n }\n};\n","Validation.Expression.date =\nValidation.Expressions.push(function(expr, database)\n{\n var parsed = parseDate( expr );\n\n if ( parsed !== false )\n {\n var parsedTime = parsed.getTime();\n\n return function(value, model)\n {\n return parsedTime;\n };\n }\n}) - 1;\n","Validation.Expression.field =\nValidation.Expressions.push(function(expr, database)\n{\n if ( indexOf( database.fields, expr ) )\n {\n return function(value, model)\n {\n return model.$get( expr );\n };\n }\n}) - 1;\n","\nvar RELATIVE_REGEX = /^([+-]\\d+(\\.\\d+)?)\\s*(.+)$/;\n\nvar RELATIVE_UNITS = {\n ms: 1,\n millisecond: 1,\n milliseconds: 1,\n s: 1000,\n second: 1000,\n seconds: 1000,\n min: 1000 * 60,\n mins: 1000 * 60,\n minute: 1000 * 60,\n minutes: 1000 * 60,\n hr: 1000 * 60 * 60,\n hour: 1000 * 60 * 60,\n hours: 1000 * 60 * 60,\n day: 1000 * 60 * 60 * 24,\n days: 1000 * 60 * 60 * 24,\n wk: 1000 * 60 * 60 * 24 * 7,\n week: 1000 * 60 * 60 * 24 * 7,\n weeks: 1000 * 60 * 60 * 24 * 7,\n month: ['getMonth', 'setMonth'],\n months: ['getMonth', 'setMonth'],\n yr: ['getFullYear', 'setFullYear'],\n year: ['getFullYear', 'setFullYear'],\n years: ['getFullYear', 'setFullYear']\n};\n\nValidation.Expression.relative =\nValidation.Expressions.push(function(expr, database)\n{\n var parsed = RELATIVE_REGEX.exec( expr );\n\n if ( parsed !== null )\n {\n var amount = parseFloat( parsed[ 1 ] );\n var unit = parsed[ 3 ];\n var unitScale = RELATIVE_UNITS[ unit ];\n\n if ( !unitScale )\n {\n throw unit + ' is not a valid unit.';\n }\n\n return function(value, model)\n {\n var relative = new Date();\n\n if ( isNumber( unitScale ) )\n {\n relative.setTime( relative.getTime() + unitScale * amount );\n }\n else\n {\n var getter = unitScale[0];\n var setter = unitScale[1];\n\n relative[ setter ]( relative[ getter ]() + amount );\n }\n\n return relative.getTime();\n };\n }\n}) - 1;\n","Validation.Expression.today =\nValidation.Expressions.push(function(expr, database)\n{\n if ( expr === 'today' )\n {\n return function(value, model)\n {\n var today = new Date();\n\n startOfDay( today );\n\n return today.getTime();\n };\n }\n}) - 1;\n","Validation.Expression.tomorrow =\nValidation.Expressions.push(function(expr, database)\n{\n if ( expr === 'tomorrow' )\n {\n return function(value, model)\n {\n var tomorrow = new Date();\n\n tomorrow.setDate( tomorrow.getDate() + 1 );\n startOfDay( tomorrow );\n\n return tomorrow.getTime();\n };\n }\n}) - 1;\n","Validation.Expression.yesterday =\nValidation.Expressions.push(function(expr, database)\n{\n if ( expr === 'yesterday' )\n {\n return function(value, model)\n {\n var yesterday = new Date();\n\n yesterday.setDate( yesterday.getDate() - 1 );\n startOfDay( yesterday );\n\n return yesterday.getTime();\n };\n }\n}) - 1;\n","// accepted\nValidation.Rules.accepted = function(field, params, database, getAlias, message)\n{\n checkNoParams( 'accepted', field, params );\n\n var messageTemplate = determineMessage( 'accepted', message );\n var acceptable = Validation.Rules.accepted.acceptable;\n\n return function(value, model, setMessage)\n {\n var valueString = (value + '').toLowerCase();\n var accepted = acceptable[ valueString ];\n\n if ( !accepted )\n {\n setMessage( generateMessage( field, getAlias( field ), value, model, messageTemplate ) );\n }\n\n return value;\n };\n};\n\nValidation.Rules.accepted.message = '{$alias} has not been accepted.';\n\nValidation.Rules.accepted.acceptable =\n{\n '1': true,\n 'yes': true,\n 'on': true,\n 'y': true,\n 'true': true\n};\n","// required\nruleGenerator('required',\n '{$alias} is required.',\n function isInvalid(value) {\n return isEmpty( value );\n }\n);\n","\nruleGenerator('array',\n '{$alias} must be an array.',\n function isInvalid(value) {\n return !isArray( value );\n }\n);\n\nruleGenerator('object',\n '{$alias} must be an object.',\n function isInvalid(value) {\n return !isObject( value );\n }\n);\n\nruleGenerator('string',\n '{$alias} must be a string.',\n function isInvalid(value) {\n return !isString( value );\n }\n);\n\nruleGenerator('number',\n '{$alias} must be a number.',\n function isInvalid(value) {\n return !isNumber( value );\n }\n);\n\nruleGenerator('boolean',\n '{$alias} must be a true or false.',\n function isInvalid(value) {\n return !isBoolean( value );\n }\n);\n\nruleGenerator('model',\n '{$alias} must have a value.',\n function isInvalid(value) {\n return !(value instanceof Model);\n }\n);\n\nruleGenerator('whole',\n '{$alias} must be a whole number.',\n function isInvalid(value, model, setValue) {\n var parsed = tryParseInt( value );\n var numeric = parseFloat( value );\n var invalid = !isNumber( parsed );\n if ( !invalid ) {\n invalid = Math.floor( parsed ) !== numeric;\n if ( !invalid ) {\n setValue( parsed );\n }\n }\n return invalid;\n }\n);\n\nruleGenerator('numeric',\n '{$alias} must be numeric.',\n function isInvalid(value, model, setValue) {\n var parsed = tryParseFloat( value );\n var invalid = !isNumber( parsed );\n if ( !invalid ) {\n setValue( parsed );\n }\n return invalid;\n }\n);\n\nruleGenerator('yesno',\n '{$alias} must be a yes or no.',\n function isInvalid(value, model, setValue) {\n var mapped = Validation.Rules.yesno.map[ value ];\n var invalid = !isBoolean( mapped );\n if ( !invalid ) {\n setValue( mapped );\n }\n return invalid;\n }\n);\n\nValidation.Rules.yesno.map =\n{\n 'true': true,\n 't': true,\n 'yes': true,\n 'y': true,\n '1': true,\n 'false': false,\n 'f': false,\n 'no': false,\n 'n': false,\n '0': false\n};\n","Validation.Rules.abs = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n\n if ( isNumber( value ) )\n {\n value = Math.abs( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.apply = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n model.$set( field, value );\n \n return value;\n };\n};\n","Validation.Rules.base64 = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n if ( global.btoa )\n {\n value = global.btoa( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.ceil = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n \n if ( isNumber( value ) )\n {\n value = Math.ceil( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.endOfDay = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n return endOfDay( value );\n };\n};\n","Validation.Rules.filter = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n if ( isArray( value ) )\n {\n for (var i = value.length - 1; i >= 0; i--)\n {\n if ( !isValue( value[ i ] ) )\n {\n value.splice( i, 1 );\n }\n }\n }\n else if ( isObject( value ) )\n {\n for (var prop in value)\n {\n if ( !isValue( value[ prop ] ) )\n {\n delete value[ prop ];\n }\n }\n }\n\n return value;\n };\n};\n","Validation.Rules.floor = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n \n if ( isNumber( value ) )\n {\n value = Math.floor( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.mod = function(field, params, database, alias, message)\n{\n var number = tryParseFloat( params );\n\n if ( !isNumber( number ) )\n {\n throw '\"' + number + '\" is not a valid number for the mod rule.';\n }\n\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n\n if ( isNumber( value ) )\n {\n value = value % number;\n }\n\n return value;\n };\n};\n","Validation.Rules.null = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n model.$set( field, null );\n\n return null;\n };\n};\n","Validation.Rules.round = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n value = tryParseFloat( value );\n\n if ( isNumber( value ) )\n {\n value = Math.round( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.startOfDay = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n return startOfDay( value );\n };\n};\n","Validation.Rules.trim = function(field, params, database, alias, message)\n{\n var trim = (function()\n {\n if ( String.prototype.trim )\n {\n return function(x) {\n return x.trim();\n };\n }\n\n var regex = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n return function(x)\n {\n return x.replace( regex, '' );\n };\n\n })();\n\n return function(value, model, setMessage)\n {\n if ( isString( value ) )\n {\n value = trim( value );\n }\n\n return value;\n };\n};\n","Validation.Rules.unbase64 = function(field, params, database, alias, message)\n{\n return function(value, model, setMessage)\n {\n if ( global.atob )\n {\n value = global.atob( value );\n }\n\n return value;\n };\n};\n","\n\n Rekord.Validation = Validation;\n\n Rekord.ruleGenerator = ruleGenerator;\n Rekord.rangeRuleGenerator = rangeRuleGenerator;\n Rekord.collectionRuleGenerator = collectionRuleGenerator;\n Rekord.dateRuleGenerator = dateRuleGenerator;\n Rekord.fieldListRuleGenerator = fieldListRuleGenerator;\n Rekord.fieldsRuleGenerator = fieldsRuleGenerator;\n Rekord.foreignRuleGenerator = foreignRuleGenerator;\n Rekord.subRuleGenerator = subRuleGenerator;\n Rekord.listRuleGenerator = listRuleGenerator;\n Rekord.regexRuleGenerator = regexRuleGenerator;\n Rekord.sizeRuleGenerator = sizeRuleGenerator;\n\n Rekord.joinFriendly = joinFriendly;\n Rekord.tryParseFloat = tryParseFloat;\n Rekord.tryParseInt = tryParseInt;\n Rekord.startOfDay = startOfDay;\n Rekord.endOfDay = endOfDay;\n Rekord.determineMessage = determineMessage;\n Rekord.mapFromArray = mapFromArray;\n Rekord.checkNoParams = checkNoParams;\n Rekord.generateMessage = generateMessage;\n\n})(this, this.Rekord);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/package.json b/package.json index 8c807d3..a7be2b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rekord-validation", - "version": "1.0.0", + "version": "1.0.1", "description": "Advanced validation rules for rekord", "author": "Philip Diffenderfer", "license": "MIT", @@ -15,15 +15,20 @@ "gulp": "^3.9.0", "gulp-check-filesize": "^2.0.1", "gulp-concat": "^2.6.0", + "gulp-jshint": "^2.0.1", "gulp-load-plugins": "^1.1.0", "gulp-qunit": "^1.3.0", "gulp-shell": "^0.5.1", "gulp-sourcemaps": "^1.6.0", "gulp-uglify": "^1.5.1", "gulp-util": "^3.0.7", - "gulp-watch": "^4.3.5", + "gulp-watch": "^4.3.6", "jaguarjs-jsdoc": "0.0.1", "jsdoc": "^3.4.0", - "merge-stream": "^1.0.0" + "merge-stream": "^1.0.0", + "jshint": "^2.9.2" + }, + "dependencies": { + "rekord": "^1.2.0" } } diff --git a/src/footer.js b/src/footer.js index db96818..1b8f596 100644 --- a/src/footer.js +++ b/src/footer.js @@ -24,4 +24,4 @@ Rekord.checkNoParams = checkNoParams; Rekord.generateMessage = generateMessage; -})(this, Rekord); +})(this, this.Rekord); diff --git a/src/header.js b/src/header.js index fd80764..6b8c60b 100644 --- a/src/header.js +++ b/src/header.js @@ -4,6 +4,7 @@ var Database = Rekord.Database; var Promise = Rekord.Promise; var Collection = Rekord.Collection; + var ModelCollection = Rekord.ModelCollection; var isEmpty = Rekord.isEmpty; var isString = Rekord.isString; @@ -16,6 +17,7 @@ var isValue = Rekord.isValue; var isPrimitiveArray = Rekord.isPrimitiveArray; var isRegExp = Rekord.isRegExp; + var isRekord = Rekord.isRekord; var noop = Rekord.noop; var equalsCompare = Rekord.equalsCompare; diff --git a/src/lib/rules/collection.js b/src/lib/rules/collection.js index 857ccdf..e2ef6de 100644 --- a/src/lib/rules/collection.js +++ b/src/lib/rules/collection.js @@ -65,7 +65,7 @@ function collectionRuleGenerator(ruleName, defaultMessage, isInvalid) if ( indexOf( database.fields, matchField ) === -1 ) { - throw otherField + ' is not a valid field for the ' + ruleName + ' rule'; + throw matchField + ' is not a valid field for the ' + ruleName + ' rule'; } var messageTemplate = determineMessage( ruleName, message ); @@ -103,11 +103,11 @@ Validation.Rules.validate = function(field, params, database, getAlias, message) for (var i = 0; i < value.length; i++) { - var model = value[ i ]; + var related = value[ i ]; - if ( model && model.$validate && !model.$validate() ) + if ( related && related.$validate && !related.$validate() ) { - invalid.push( model ); + invalid.push( related ); } } diff --git a/src/lib/rules/fields.js b/src/lib/rules/fields.js index 54f7463..bd8058e 100644 --- a/src/lib/rules/fields.js +++ b/src/lib/rules/fields.js @@ -177,4 +177,4 @@ function fieldsRuleGenerator(ruleName, defaultMessage, isInvalid) }; Validation.Rules[ ruleName ].message = defaultMessage; -}; +} diff --git a/src/lib/rules/list.js b/src/lib/rules/list.js index 5b8d796..9c8da32 100644 --- a/src/lib/rules/list.js +++ b/src/lib/rules/list.js @@ -12,7 +12,7 @@ listRuleGenerator('not_in', '{$alias} must not be one of {$list}.', function isInvalid(value, model, inList) { - return inList( value, model ) + return inList( value, model ); } ); diff --git a/src/lib/transforms/trim.js b/src/lib/transforms/trim.js index f689c99..71ff337 100644 --- a/src/lib/transforms/trim.js +++ b/src/lib/transforms/trim.js @@ -1,21 +1,28 @@ Validation.Rules.trim = function(field, params, database, alias, message) { - // String.trim polyfill - if ( !String.prototype.trim ) + var trim = (function() { + if ( String.prototype.trim ) + { + return function(x) { + return x.trim(); + }; + } + var regex = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - String.prototype.trim = function() + return function(x) { - return this.replace( regex, '' ); + return x.replace( regex, '' ); }; - } + + })(); return function(value, model, setMessage) { if ( isString( value ) ) { - value = value.trim(); + value = trim( value ); } return value; diff --git a/src/lib/util.js b/src/lib/util.js index 07a1da1..1cb2cd6 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -82,7 +82,7 @@ function determineMessage(ruleName, message) return message || Validation.Rules[ ruleName ].message; } -function joinFriendly(arr, lastSeparator, itemSeparator, getAlias) +function joinFriendly(arr, lastSeparatorCustom, itemSeparatorCustom, getAlias) { var copy = arr.slice(); @@ -95,8 +95,8 @@ function joinFriendly(arr, lastSeparator, itemSeparator, getAlias) } var last = copy.pop(); - var lastSeparator = lastSeparator || 'and'; - var itemSeparator = itemSeparator || ', '; + var lastSeparator = lastSeparatorCustom || 'and'; + var itemSeparator = itemSeparatorCustom || ', '; switch (copy.length) { case 0: diff --git a/src/lib/validation.js b/src/lib/validation.js index 8c381f1..8f6cfee 100644 --- a/src/lib/validation.js +++ b/src/lib/validation.js @@ -21,7 +21,7 @@ Rekord.on( Rekord.Events.Plugins, function(model, db, options) for ( var field in rules ) { - db.validations[ field ] = Validation.parseRules( rules[ field ], field, db, getAlias, messages[ field ] ) + db.validations[ field ] = Validation.parseRules( rules[ field ], field, db, getAlias, messages[ field ] ); } addMethod( model.prototype, '$validate', function() @@ -40,7 +40,7 @@ Rekord.on( Rekord.Events.Plugins, function(model, db, options) var value = this.$get( field ); var fieldValid = true; - var setMessage = function(message) + var setMessage = function(message) // jshint ignore:line { // Only accept for the first valid message if ( message && fieldValid ) @@ -130,16 +130,16 @@ var Validation = for (var i = 0; i < rules.length; i++) { var rule = rules[ i ]; - var validator = this.parseRule( rule, field, database, getAlias, message ); + var defaultMessageValidator = this.parseRule( rule, field, database, getAlias, message ); - validators.push( validator ); + validators.push( defaultMessageValidator ); } } else if ( isObject( rules ) ) { - for (var rule in rules) + for (var ruleProperty in rules) { - var ruleMessageOrData = rules[ rule ]; + var ruleMessageOrData = rules[ ruleProperty ]; var ruleMessage = isObject( ruleMessageOrData ) ? ruleMessageOrData.message : ( isString( ruleMessageOrData ) ? ruleMessageOrData : undefined ); @@ -147,9 +147,9 @@ var Validation = var ruleInput = isObject( ruleMessageOrData ) && ruleMessageOrData.message ? ruleMessageOrData.input : ( isString( ruleMessageOrData ) ? undefined : ruleMessageOrData ); - var validator = this.parseRule( rule, field, database, getAlias, ruleMessage || message, ruleInput ); + var customMessageValidator = this.parseRule( ruleProperty, field, database, getAlias, ruleMessage || message, ruleInput ); - validators.push( validator ); + validators.push( customMessageValidator ); } }