├── .gitignore ├── HISTORY.md ├── LICENSE ├── README.md ├── lib ├── module │ ├── create_validator.js │ ├── ejson.js │ ├── field_validator.js │ ├── get_error.js │ ├── global.js │ ├── init_class.js │ ├── init_definition.js │ ├── validate.js │ ├── validation_error.js │ ├── validation_error_event.js │ └── validator.js └── validators │ ├── comparison │ ├── choice.js │ ├── equal.js │ ├── equal_to.js │ ├── regexp.js │ └── unique.js │ ├── existence │ ├── not_null.js │ ├── null.js │ └── required.js │ ├── logical │ ├── and.js │ ├── if.js │ ├── or.js │ └── switch.js │ ├── nested │ ├── contains.js │ ├── every.js │ └── has.js │ ├── size │ ├── gt.js │ ├── gte.js │ ├── length.js │ ├── lt.js │ ├── lte.js │ ├── max_length.js │ └── min_length.js │ └── type │ ├── array.js │ ├── boolean.js │ ├── date.js │ ├── email.js │ ├── number.js │ ├── object.js │ ├── string.js │ └── url.js └── package.js /.gitignore: -------------------------------------------------------------------------------- 1 | .meteor/local 2 | .meteor/meteorite 3 | .build* 4 | .versions 5 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # 1.1.2 (2015-11-25) 2 | 3 | - Removes all existing errors for a field on validation, if it's optional and now changed to null 4 | 5 | # 1.1.1 (2015-10-31) 6 | 7 | - Removed the `ui` package to not load `blaze` and `jquery` packages unnecessary 8 | 9 | # 1.1.0 (2015-10-28) 10 | 11 | - Ability to validate nested fields from the top level document. 12 | - Now you can do `doc.validate('field.nestedField')` 13 | - Now you can do `doc.getValidationError('field.nestedField')` 14 | - Now you can do `doc.hasValidationError('field.nestedField')` 15 | - All the following methods also work with the nested fields: `doc.getValidationErrors()`, `doc.hasValidationErrors()`, `doc.clearValidationErrors()`, `doc.throwValidationException()`, `doc.catchValidationException()` 16 | 17 | # 1.0.4 (2015-10-11) 18 | 19 | - Use ReactiveMap 2.0 20 | 21 | # 1.0.3 (2015-10-08) 22 | 23 | - Fixed wrong property name in the `afterSet` event 24 | 25 | # 1.0.2 (2015-10-02) 26 | 27 | - Fixed validation error when no validators defined 28 | 29 | # 1.0.1 (2015-10-01) 30 | 31 | - Don't use the `initSchema` event for the validators module 32 | 33 | # 1.0.0 (2015-09-28) 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 jagi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Validators module for Meteor Astronomy 2 | 3 | The validators module introduces a nice way of checking fields values' validity. For instance, we can check whether the given field's value is an email string or matches a regular expression. You can also write your own validators. You can add it to your Meteor project using the following command. 4 | 5 | A detailed information about module can be found [here](http://astronomy.jagi.io/#validators). 6 | -------------------------------------------------------------------------------- /lib/module/create_validator.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator = function(validatorDefinition) { 2 | var validator = new Astro.Validator(validatorDefinition); 3 | Validators[validator.name] = validator.createFieldValidatorGenerator(); 4 | 5 | return Validators[validator.name]; 6 | }; 7 | -------------------------------------------------------------------------------- /lib/module/ejson.js: -------------------------------------------------------------------------------- 1 | var events = {}; 2 | 3 | events.toJSONValue = function(e) { 4 | var doc = this; 5 | var json; 6 | 7 | Tracker.nonreactive(function() { 8 | json = { 9 | errors: doc._errors.all() 10 | } 11 | }); 12 | 13 | _.extend(e.data, json); 14 | }; 15 | 16 | events.fromJSONValue = function(e) { 17 | var doc = this; 18 | var json = e.data; 19 | 20 | doc._errors.set(json.errors); 21 | }; 22 | 23 | Astro.eventManager.on('toJSONValue', events.toJSONValue); 24 | Astro.eventManager.on('fromJSONValue', events.fromJSONValue); 25 | -------------------------------------------------------------------------------- /lib/module/field_validator.js: -------------------------------------------------------------------------------- 1 | var FieldValidator = 2 | Astro.FieldValidator = function FieldValidator(fieldValidatorDefinition) { 3 | var self = this; 4 | 5 | // self.name = fieldValidatorDefinition.validator.name; 6 | self.validator = fieldValidatorDefinition.validator; 7 | self.param = fieldValidatorDefinition.param; 8 | self.message = fieldValidatorDefinition.message; 9 | }; 10 | 11 | FieldValidator.prototype.validate = function(doc, fieldName, fieldValue) { 12 | var self = this; 13 | 14 | // If a function was passed as a validator's param, then it may mean that we 15 | // want it to evalute to some value. 16 | var param = _.isFunction(self.param) ? self.param.call(doc) : self.param; 17 | 18 | if (!self.validator.validate.call(doc, fieldValue, fieldName, param)) { 19 | // Throw error. 20 | throw new Astro.ValidationError({ 21 | document: doc, 22 | fieldValidator: self, 23 | fieldName: fieldName, 24 | fieldValue: fieldValue, 25 | param: param 26 | }); 27 | } 28 | 29 | return true; 30 | }; 31 | -------------------------------------------------------------------------------- /lib/module/get_error.js: -------------------------------------------------------------------------------- 1 | var methods = {}; 2 | 3 | methods.getValidationError = function(fieldName) { 4 | var doc = this; 5 | var error; 6 | 7 | Astro.utils.fields.traverseNestedDocs( 8 | doc, 9 | fieldName, 10 | function(nestedDoc, nestedFieldName, Class, field, index) { 11 | if (nestedDoc instanceof Astro.BaseClass) { 12 | error = nestedDoc._errors.get(nestedFieldName); 13 | } 14 | } 15 | ); 16 | 17 | return error; 18 | }; 19 | 20 | methods.getValidationErrors = function() { 21 | var doc = this; 22 | var Class = doc.constructor; 23 | 24 | var errors = this._errors.all(); 25 | var fields = Class.getFields(); 26 | _.each(fields, function(field, fieldName) { 27 | if (doc[fieldName] && field.class) { 28 | if (field instanceof Astro.fields.object) { 29 | var nestedErrors = doc[fieldName].getValidationErrors(); 30 | _.each(nestedErrors, function(nestedError, nestedFieldName) { 31 | errors[fieldName + '.' + nestedFieldName] = nestedError; 32 | }); 33 | } else if (field instanceof Astro.fields.array) { 34 | _.each(doc[fieldName], function(nestedDoc, index) { 35 | if (nestedDoc) { 36 | var nestedErrors = nestedDoc.getValidationErrors(); 37 | _.each(nestedErrors, function(nestedError, nestedFieldName) { 38 | errors[ 39 | fieldName + '.' + index + '.' + nestedFieldName 40 | ] = nestedError; 41 | }); 42 | } 43 | }); 44 | } 45 | } 46 | }); 47 | 48 | return errors; 49 | }; 50 | 51 | methods.hasValidationError = function(fieldName) { 52 | var doc = this; 53 | var has; 54 | 55 | Astro.utils.fields.traverseNestedDocs( 56 | doc, 57 | fieldName, 58 | function(nestedDoc, nestedFieldName, Class, field, index) { 59 | if (nestedDoc instanceof Astro.BaseClass) { 60 | has = nestedDoc._errors.has(nestedFieldName); 61 | } 62 | } 63 | ); 64 | 65 | return has; 66 | }; 67 | 68 | methods.hasValidationErrors = function() { 69 | var errors = this.getValidationErrors(); 70 | return _.size(errors) > 0; 71 | }; 72 | 73 | methods.clearValidationErrors = function() { 74 | var doc = this; 75 | var Class = doc.constructor; 76 | 77 | doc._errors.clear(); 78 | 79 | var fields = Class.getFields(); 80 | _.each(fields, function(field, fieldName) { 81 | if ( 82 | doc[fieldName] && field instanceof Astro.fields.object && field.class 83 | ) { 84 | doc[fieldName]._errors.clear(); 85 | } else if ( 86 | doc[fieldName] && field instanceof Astro.fields.array && field.class 87 | ) { 88 | _.each(doc[fieldName], function(nestedDoc, index) { 89 | if (nestedDoc instanceof Astro.BaseClass) { 90 | nestedDoc._errors.clear(); 91 | } 92 | }); 93 | } 94 | }); 95 | }; 96 | 97 | methods.throwValidationException = function() { 98 | throw new Meteor.Error('validation-error', this.getValidationErrors()); 99 | }; 100 | 101 | methods.catchValidationException = function(exception) { 102 | if (!(exception instanceof Meteor.Error) || 103 | exception.error !== 'validation-error' || 104 | !_.isObject(exception.reason) 105 | ) { 106 | return false; 107 | } 108 | 109 | var doc = this; 110 | var errors = exception.reason; 111 | 112 | _.each(errors, function(error, fieldName) { 113 | Astro.utils.fields.traverseNestedDocs( 114 | doc, 115 | fieldName, 116 | function(nestedDoc, nestedFieldName, Class, field, index) { 117 | if (nestedDoc instanceof Astro.BaseClass) { 118 | nestedDoc._errors.set(nestedFieldName, error); 119 | } 120 | } 121 | ); 122 | }); 123 | return true; 124 | }; 125 | 126 | _.extend(Astro.BaseClass.prototype, methods); 127 | -------------------------------------------------------------------------------- /lib/module/global.js: -------------------------------------------------------------------------------- 1 | Astro.validators = Validators = {}; 2 | -------------------------------------------------------------------------------- /lib/module/init_class.js: -------------------------------------------------------------------------------- 1 | var checkFieldName = function(fieldName) { 2 | if (!this.hasField(fieldName)) { 3 | throw new Error( 4 | 'The "' + fieldName + 5 | '" field does not exist in the "' + this.getName() + '" class' 6 | ); 7 | } 8 | }; 9 | 10 | var checkValidator = function(fieldName, validator) { 11 | if (!Match.test( 12 | validator, 13 | Match.OneOf(Function, Astro.FieldValidator, [Astro.FieldValidator]) 14 | )) { 15 | throw new TypeError( 16 | 'The validator for the "' + fieldName + 17 | '" field in the "' + this.getName() + '" class schema has to be a ' + 18 | 'function or an array of validators or a single validator object' 19 | ); 20 | } 21 | }; 22 | 23 | var checkValidatorsList = function(validators) { 24 | if (!Match.test(validators, Object)) { 25 | throw new TypeError( 26 | 'The validators definitions in the "' + this.getName() + 27 | '" class schema has to be an object' 28 | ); 29 | } 30 | }; 31 | 32 | var checkValidationOrder = function(validationOrder) { 33 | if (!Match.test(validationOrder, [String])) { 34 | throw new TypeError( 35 | 'The validation order definition in the "' + this.getName() + 36 | '" class schema has to be an array of fields names' 37 | ); 38 | } 39 | }; 40 | 41 | var classMethods = { 42 | getValidator: function(fieldName) { 43 | return this.schema.validators[fieldName]; 44 | }, 45 | 46 | getValidators: function(fieldsNames) { 47 | if (_.isArray(fieldsNames)) { 48 | return _.pick(this.schema.validators, fieldsNames); 49 | } 50 | return this.schema.validators; 51 | }, 52 | 53 | getValidationOrder: function() { 54 | var Class = this; 55 | 56 | // Create a list of all fields where the fields from the validation order 57 | // are at the beginning. 58 | var order = Class.schema.validationOrder; 59 | if (order) { 60 | // Get a list of all fields in the class. 61 | var allFieldsNames = Class.getFieldsNames(); 62 | // Detect what fields are not in the validation order. 63 | var diff = _.difference(allFieldsNames, order); 64 | // If not all fields had been included in the validation order, then add 65 | // them at the and. 66 | if (diff.length > 0) { 67 | order = order.concat(diff); 68 | } 69 | } else { 70 | order = Class.getFieldsNames(); 71 | } 72 | 73 | return order; 74 | } 75 | }; 76 | 77 | var events = {}; 78 | 79 | events.afterSet = function(e) { 80 | var fieldName = e.data.fieldName; 81 | 82 | // If a validator is defined for given field then clear error message for 83 | // that field. 84 | if (this._errors) { 85 | this._errors.delete(fieldName); 86 | } 87 | }; 88 | 89 | events.beforeInit = function() { 90 | var doc = this; 91 | 92 | doc._errors = new ReactiveMap(); 93 | }; 94 | 95 | Astro.eventManager.on('afterSet', events.afterSet); 96 | Astro.eventManager.on('beforeInit', events.beforeInit) 97 | 98 | Astro.eventManager.on( 99 | 'initClass', function onInitClassValidators() { 100 | var Class = this; 101 | var schema = Class.schema; 102 | 103 | _.extend(Class, classMethods); 104 | 105 | schema.validators = schema.validators || {}; 106 | } 107 | ); 108 | -------------------------------------------------------------------------------- /lib/module/init_definition.js: -------------------------------------------------------------------------------- 1 | var checkValidator = function( 2 | validator, fieldName, className 3 | ) { 4 | if (!Match.test( 5 | validator, 6 | Match.OneOf(Astro.FieldValidator, [Astro.FieldValidator]) 7 | )) { 8 | throw new TypeError( 9 | 'The validator for the "' + fieldName + 10 | '" field in the "' + className + '" class schema has to be a ' + 11 | 'function, an array of validators or a single validator' 12 | ); 13 | } 14 | }; 15 | 16 | Astro.eventManager.on( 17 | 'initDefinition', function onInitDefinitionValidators(schemaDefinition) { 18 | var Class = this; 19 | var schema = Class.schema; 20 | var validatorsDefinitions = {}; 21 | var validationOrder; 22 | 23 | if (_.has(schemaDefinition, 'validationOrder')) { 24 | validationOrder = [].concat(schemaDefinition.validationOrder); 25 | } 26 | 27 | if (_.has(schemaDefinition, 'fields')) { 28 | _.each(schemaDefinition.fields, function(fieldDefinition, fieldName) { 29 | if (_.has(fieldDefinition, 'validator')) { 30 | var validator = fieldDefinition.validator; 31 | 32 | if (_.isArray(validator)) { 33 | validator = Validators.and(validator); 34 | } 35 | 36 | if (validator) { 37 | // Check validity of the validator definition. 38 | checkValidator(validator, fieldName, Class.getName()); 39 | validatorsDefinitions[fieldName] = validator; 40 | } 41 | } 42 | }); 43 | } 44 | 45 | if (_.has(schemaDefinition, 'validators')) { 46 | _.each(schemaDefinition.validators, function(validator, fieldName) { 47 | var validator; 48 | 49 | if (_.isArray(validator)) { 50 | validator = Validators.and(validator); 51 | } 52 | 53 | if (validator) { 54 | // Check validity of the validator definition. 55 | checkValidator(validator, fieldName, Class.getName()); 56 | validatorsDefinitions[fieldName] = validator; 57 | } 58 | }); 59 | } 60 | 61 | if (_.size(validatorsDefinitions) > 0) { 62 | // Add validators to the schema. 63 | _.extend(schema.validators, validatorsDefinitions); 64 | } 65 | if (validationOrder) { 66 | // Add validation order to the schema. 67 | schema.validationOrder = validationOrder; 68 | } 69 | } 70 | ); 71 | -------------------------------------------------------------------------------- /lib/module/validate.js: -------------------------------------------------------------------------------- 1 | var methods = {}; 2 | 3 | methods._validateOne = function(fieldName, stopOnFirstError) { 4 | var doc = this; 5 | var result = true; 6 | 7 | Astro.utils.fields.traverseNestedDocs( 8 | doc, 9 | fieldName, 10 | function(nestedDoc, nestedFieldName, Class, field, index) { 11 | // Get value of the field. 12 | var nestedFieldValue = nestedDoc.get(nestedFieldName); 13 | 14 | // If value of the field is optional and it's null, then we passed 15 | // validation. Clear any existing error 16 | if (_.isNull(nestedFieldValue) && field.optional) { 17 | nestedDoc._errors.delete(nestedFieldName); 18 | return; 19 | } 20 | 21 | try { 22 | // Get a validator for the given field name and run validation if it 23 | // exists. 24 | var nestedFieldValidator = Class.getValidator(nestedFieldName); 25 | if (nestedFieldValidator) { 26 | nestedFieldValidator.validate( 27 | nestedDoc, 28 | nestedFieldName, 29 | nestedFieldValue 30 | ); 31 | } 32 | 33 | // Remove a validator error message when no error occured. 34 | nestedDoc._errors.delete(nestedFieldName); 35 | 36 | // Depending on the nested field type execute validation on the nested 37 | // values. The nested field has also have defined class. 38 | if (nestedFieldValue && field.class) { 39 | if (field instanceof Astro.fields.object) { 40 | result = nestedFieldValue.validate(stopOnFirstError); 41 | } else if (field instanceof Astro.fields.array) { 42 | if (stopOnFirstError) { 43 | result = _.every(nestedFieldValue, function(nestedDoc) { 44 | if (nestedDoc) { 45 | return nestedDoc.validate(stopOnFirstError); 46 | } 47 | return true; 48 | }); 49 | } else { 50 | _.each(nestedFieldValue, function(nestedDoc) { 51 | if (nestedDoc && !nestedDoc.validate(stopOnFirstError)) { 52 | result = false; 53 | } 54 | }); 55 | } 56 | } 57 | } 58 | } catch (e) { 59 | // If the error is not an instance of the Astro.ValidationError then 60 | // throw error again. 61 | if (!(e instanceof Astro.ValidationError)) { 62 | throw e; 63 | } 64 | 65 | // Generate an error message from the validator that didn't pass. 66 | var errorMessage = e.generateMessage(); 67 | 68 | // Set validation error for the field. 69 | nestedDoc._errors.set(nestedFieldName, errorMessage); 70 | 71 | result = false; 72 | } 73 | } 74 | ); 75 | 76 | return result; 77 | }; 78 | 79 | methods._validateMany = function(fieldsNames, stopOnFirstError) { 80 | var doc = this; 81 | var Class = doc.constructor; 82 | 83 | // Run validation for each field. If the "stopOnFirstError" flag is set, then 84 | // we stop validating after the first error. Otherwise, we continue until we 85 | // reach the last validator. 86 | if (stopOnFirstError) { 87 | return _.every(fieldsNames, function(fieldName) { 88 | return doc._validateOne(fieldName, stopOnFirstError); 89 | }); 90 | } else { 91 | var valid = true; 92 | _.each(fieldsNames, function(fieldName) { 93 | if (!doc._validateOne(fieldName, stopOnFirstError)) { 94 | valid = false; 95 | } 96 | }); 97 | return valid; 98 | } 99 | }; 100 | 101 | // Public. 102 | 103 | methods.validate = function(fieldsNames, stopOnFirstError) { 104 | var doc = this; 105 | var Class = doc.constructor; 106 | 107 | if (arguments.length === 0) { 108 | 109 | // Get list of all fields in the proper validation order. 110 | fieldsNames = Class.getValidationOrder(); 111 | 112 | } else if (arguments.length === 1) { 113 | 114 | if (_.isString(fieldsNames)) { 115 | fieldsNames = [fieldsNames]; 116 | } else if (_.isBoolean(fieldsNames)) { 117 | // Rewrite value of the "fieldsNames" argument into the 118 | // "stopOnFirstError" argument. 119 | stopOnFirstError = fieldsNames; 120 | // Get list of all validators. 121 | fieldsNames = Class.getValidationOrder(); 122 | } 123 | 124 | } else if (arguments.length === 2) { 125 | 126 | if (_.isString(fieldsNames)) { 127 | fieldsNames = [fieldsNames]; 128 | } 129 | 130 | } 131 | 132 | // Set default value of the "stopOnFirstError" argument. 133 | if (_.isUndefined(stopOnFirstError)) { 134 | stopOnFirstError = true; 135 | } 136 | 137 | return doc._validateMany(fieldsNames, stopOnFirstError); 138 | }; 139 | 140 | _.extend(Astro.BaseClass.prototype, methods); 141 | -------------------------------------------------------------------------------- /lib/module/validation_error.js: -------------------------------------------------------------------------------- 1 | var ValidationError = 2 | Astro.ValidationError = function ValidationError(data) { 3 | this.name = 'ValidationError'; 4 | this.stack = (new Error()).stack; 5 | this.document = data.document; 6 | this.fieldValidator = data.fieldValidator; 7 | this.fieldName = data.fieldName; 8 | this.fieldValue = data.fieldValue; 9 | this.param = data.param; 10 | }; 11 | 12 | ValidationError.prototype = Object.create(Error.prototype); 13 | 14 | ValidationError.prototype.generateMessage = function() { 15 | var doc = this.document; 16 | var Class = doc.constructor; 17 | 18 | if (this.fieldValidator.message) { 19 | // Use the user defined error message in a field validator. 20 | return this.fieldValidator.message; 21 | } 22 | 23 | // Prepare an event object for the "validationError" event. 24 | var event = new Astro.ValidationErrorEvent({ 25 | validator: this.fieldValidator.validator, 26 | fieldValue: this.fieldValue, 27 | fieldName: this.fieldName, 28 | param: this.param, 29 | message: this.message 30 | }); 31 | event.target = doc; 32 | 33 | // Generate an error message using the "validationError" event. 34 | Class.emitEvent(event); 35 | var message = event.getMessage(); 36 | if (event.stopped) { 37 | return message; 38 | } 39 | 40 | // Get a default validation error by executing the "validatioError" event on 41 | // the validator. 42 | this.fieldValidator.validator.emit(event); 43 | var message = event.getMessage(); 44 | if (message) { 45 | return message; 46 | } 47 | 48 | // Default validation error. 49 | return 'The value of the "' + this.fieldName + '" field is invalid'; 50 | }; 51 | -------------------------------------------------------------------------------- /lib/module/validation_error_event.js: -------------------------------------------------------------------------------- 1 | Astro.ValidationErrorEvent = function(data) { 2 | var type = 'validationError'; 3 | data = _.extend({ 4 | validator: null, 5 | fieldName: null, 6 | fieldValue: null, 7 | param: null, 8 | message: null 9 | }, data); 10 | 11 | Astro.Event.call(this, type, data); 12 | }; 13 | 14 | Astro.utils.class.inherits(Astro.ValidationErrorEvent, Astro.Event); 15 | 16 | Astro.ValidationErrorEvent.prototype.setMessage = function(message) { 17 | this.data.message = message; 18 | }; 19 | 20 | Astro.ValidationErrorEvent.prototype.getMessage = function() { 21 | return this.data.message; 22 | }; 23 | -------------------------------------------------------------------------------- /lib/module/validator.js: -------------------------------------------------------------------------------- 1 | var checkValidatorDefinition = function(validatorDefinition) { 2 | // Check if the validator definition is an object. 3 | if (!Match.test(validatorDefinition, Object)) { 4 | throw new Error( 5 | 'The validator definition has to be an object' 6 | ); 7 | } 8 | // Check if the validator name is provided. 9 | if (!_.has(validatorDefinition, 'name')) { 10 | throw new Error( 11 | 'Provide a validator name' 12 | ); 13 | } 14 | // Check if the validator name is a string. 15 | if (!Match.test(validatorDefinition.name, String)) { 16 | throw new Error( 17 | 'The validator name has to be a string' 18 | ); 19 | } 20 | // Check if the validator with the given name already exists. 21 | if (_.has(Validators, validatorDefinition.name)) { 22 | throw new Error( 23 | 'Validator with the name "' + validatorDefinition.name + 24 | '" is already defined' 25 | ); 26 | } 27 | // Check if the validation function is provided. 28 | if (!_.has(validatorDefinition, 'validate')) { 29 | throw new Error( 30 | 'Provide the "validate" function' 31 | ); 32 | } 33 | // Check if the "validate" attribute is function. 34 | if (!Match.test(validatorDefinition.validate, Function)) { 35 | throw new Error( 36 | 'The "validate" attribute has to be a function' 37 | ); 38 | } 39 | }; 40 | 41 | var Validator = Astro.Validator = function Validator(validatorDefinition) { 42 | checkValidatorDefinition.apply(this, arguments); 43 | var self = this; 44 | 45 | self.name = validatorDefinition.name; 46 | self.validate = validatorDefinition.validate; 47 | 48 | if (_.has(validatorDefinition, 'events')) { 49 | _.each(validatorDefinition.events, function(eventHandler, eventName) { 50 | self.on(eventName, eventHandler); 51 | }); 52 | } 53 | }; 54 | 55 | Validator.prototype.createFieldValidatorGenerator = function() { 56 | var self = this; 57 | 58 | return function fieldValidatorGenerator(param, message) { 59 | return new Astro.FieldValidator({ 60 | validator: self, 61 | param: param, 62 | message: message 63 | }); 64 | }; 65 | }; 66 | 67 | Astro.Events.mixin(Validator.prototype); 68 | -------------------------------------------------------------------------------- /lib/validators/comparison/choice.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'choice', 3 | validate: function(fieldValue, fieldName, choices) { 4 | return _.contains(choices, fieldValue); 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var choices = e.data.param; 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to be one of "' + choices.join('", "') + '"' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/comparison/equal.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'equal', 3 | validate: function(fieldValue, fieldName, compareValue) { 4 | return fieldValue === compareValue; 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var compareValue = e.data.param; 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to be equal "' + compareValue + '"' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/comparison/equal_to.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'equalTo', 3 | validate: function(fieldValue, fieldName, compareFieldName) { 4 | var compareValue = this.get(compareFieldName); 5 | 6 | return fieldValue === compareValue; 7 | }, 8 | events: { 9 | validationerror: function(e) { 10 | var fieldName = e.data.fieldName; 11 | var compareFieldName = e.data.param; 12 | var compareValue = this.get(compareFieldName); 13 | 14 | e.setMessage( 15 | 'The values of the "' + fieldName + '" and "' + 16 | compareFieldName + '" fields have to be equal' 17 | ); 18 | } 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /lib/validators/comparison/regexp.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'regexp', 3 | validate: function(fieldValue, fieldName, pattern) { 4 | return pattern.test(fieldValue); 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var pattern = e.data.param.toString(); 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to match the "' + pattern + '" regular expression' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/comparison/unique.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'unique', 3 | validate: function(fieldValue, fieldName) { 4 | var doc = this; 5 | var Class = doc.constructor; 6 | var Collection = Class.getCollection(); 7 | 8 | // If a Class is not related with any collection then document is unique. 9 | if (!Collection) { 10 | return true; 11 | } 12 | 13 | // Prepare selector. 14 | var selector = {}; 15 | selector[fieldName] = fieldValue; 16 | 17 | // If the "_id" fields is present, then object is being updated. 18 | // In this case, ignore the object itself. 19 | if (this._id) { 20 | selector._id = { 21 | $ne: this._id 22 | }; 23 | } 24 | 25 | // Check if a record with the given field value exists. 26 | return _.isUndefined(Collection.findOne(selector)); 27 | }, 28 | events: { 29 | validationerror: function(e) { 30 | var fieldName = e.data.fieldName; 31 | 32 | e.setMessage( 33 | 'The value of the "' + fieldName + '" field has to be unique' 34 | ); 35 | } 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /lib/validators/existence/not_null.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'notNull', 3 | validate: function(fieldValue) { 4 | return !_.isNull(fieldValue); 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | 10 | e.setMessage( 11 | 'The value of the "' + fieldName + '" field can not be null' 12 | ); 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /lib/validators/existence/null.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'null', 3 | validate: _.isNull, 4 | events: { 5 | validationerror: function(e) { 6 | var fieldName = e.data.fieldName; 7 | 8 | e.setMessage( 9 | 'The value of the "' + fieldName + '" field has to be null' 10 | ); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /lib/validators/existence/required.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'required', 3 | validate: function(fieldValue) { 4 | return !_.isNull(fieldValue) && fieldValue !== ''; 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | 10 | e.setMessage( 11 | 'The value of the "' + fieldName + '" field is required' 12 | ); 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /lib/validators/logical/and.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'and', 3 | validate: function(fieldValue, fieldName, fieldValidators) { 4 | var doc = this; 5 | 6 | return _.every(fieldValidators, function(fieldValidator) { 7 | return fieldValidator.validate( 8 | doc, fieldName, fieldValue 9 | ); 10 | }); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /lib/validators/logical/if.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'if', 3 | validate: function(fieldValue, fieldName, options) { 4 | var doc = this; 5 | 6 | if (!_.has(options, 'condition') || !_.isFunction(options.condition)) { 7 | throw new Error( 8 | 'The "condition" option in the "if" validator is required' 9 | ); 10 | } 11 | 12 | if ( 13 | !_.has(options, 'true') || !options.true instanceof Astro.FieldValidator 14 | ) { 15 | throw new Error( 16 | 'The "true" option in the "if" validator is required' 17 | ); 18 | } 19 | 20 | if (options.condition.call(doc, fieldValue, fieldName)) { 21 | return options.true.validate(doc, fieldName, fieldValue); 22 | } 23 | 24 | if ( 25 | _.has(options, 'false') && 26 | options.false instanceof Astro.FieldValidator 27 | ) { 28 | return options.false.validate(doc, fieldName, fieldValue); 29 | } 30 | 31 | return true; 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /lib/validators/logical/or.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'or', 3 | validate: function(fieldValue, fieldName, fieldValidators) { 4 | var doc = this; 5 | var error; 6 | var doc = this; 7 | 8 | if (!_.some(fieldValidators, function(fieldValidator) { 9 | try { 10 | return fieldValidator.validate( 11 | doc, fieldName, fieldValue 12 | ); 13 | } catch (e) { 14 | if (e instanceof Astro.ValidationError) { 15 | // We get the first error that occured. We will throw it again if 16 | // there are no validators that pass. 17 | if (!error) { 18 | error = e; 19 | } 20 | return false; 21 | } else { 22 | throw e; 23 | } 24 | } 25 | })) { 26 | throw error; 27 | } 28 | 29 | return true; 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /lib/validators/logical/switch.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'switch', 3 | validate: function(fieldValue, fieldName, options) { 4 | var doc = this; 5 | 6 | if (!_.has(options, 'cases') || !_.isObject(options.cases)) { 7 | throw new Error( 8 | 'The "cases" option in the "switch" validator is required' 9 | ); 10 | } 11 | 12 | if (_.has(options, 'expression') && !_.isFunction(options.expression)) { 13 | throw new Error( 14 | 'The "expression" option in the "switch" validator has to be a function' 15 | ); 16 | } 17 | 18 | var expression; 19 | if (_.has(options, 'expression')) { 20 | expression = options.expression.call(doc, fieldValue, fieldName); 21 | } else { 22 | expression = fieldValue; 23 | } 24 | 25 | if (_.has(options.cases, expression)) { 26 | return options.cases[expression].validate(doc, fieldName, fieldValue); 27 | } 28 | 29 | return true; 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /lib/validators/nested/contains.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'contains', 3 | validate: function(fieldValue, fieldName, sought) { 4 | if (!(_.isArray(fieldValue) || _.isObject(fieldValue))) { 5 | return false; 6 | } 7 | 8 | return _.contains(fieldValue, sought); 9 | }, 10 | events: { 11 | validationerror: function(e) { 12 | var fieldName = e.data.fieldName; 13 | var sought = e.data.param; 14 | 15 | e.setMessage( 16 | 'The value of the "' + fieldName + 17 | '" field has to contain the "' + sought + '" value' 18 | ); 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /lib/validators/nested/every.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'every', 3 | validate: function(fieldValue, fieldName, fieldValidator) { 4 | var doc = this; 5 | 6 | if (!_.isArray(fieldValue)) { 7 | return true; 8 | } 9 | 10 | return _.every(fieldValue, function(value) { 11 | return fieldValidator.validate( 12 | doc, 13 | fieldName, 14 | value 15 | ); 16 | }); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /lib/validators/nested/has.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'has', 3 | validate: function(fieldValue, fieldName, propertyName) { 4 | if (!_.isObject(fieldValue)) { 5 | return false; 6 | } 7 | 8 | return _.has(fieldValue, propertyName); 9 | }, 10 | events: { 11 | validationerror: function(e) { 12 | var fieldName = e.data.fieldName; 13 | var propertyName = e.data.param; 14 | 15 | e.setMessage( 16 | 'The value of the "' + fieldName + 17 | '" field has to have "' + propertyName + '" property' 18 | ); 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /lib/validators/size/gt.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'gt', 3 | validate: function(fieldValue, fieldName, compareValue) { 4 | return fieldValue > compareValue; 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var compareValue = e.data.param; 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to be greater than "' + compareValue + '"' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/size/gte.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'gte', 3 | validate: function(fieldValue, fieldName, compareValue) { 4 | return fieldValue >= compareValue; 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var compareValue = e.data.param; 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to be greater than or equal "' + compareValue + '"' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/size/length.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'length', 3 | validate: function(fieldValue, fieldName, length) { 4 | if (_.isNull(fieldValue) || !_.has(fieldValue, 'length')) { 5 | return false; 6 | } 7 | 8 | return fieldValue.length === length; 9 | }, 10 | events: { 11 | validationerror: function(e) { 12 | var fieldName = e.data.fieldName; 13 | var length = e.data.param; 14 | 15 | e.setMessage( 16 | 'The length of the value of the "' + fieldName + 17 | '" field has to be ' + length 18 | ); 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /lib/validators/size/lt.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'lt', 3 | validate: function(fieldValue, fieldName, compareValue) { 4 | return fieldValue < compareValue; 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var compareValue = e.data.param; 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to be less than "' + compareValue + '"' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/size/lte.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'lte', 3 | validate: function(fieldValue, fieldName, compareValue) { 4 | return fieldValue <= compareValue; 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | var compareValue = e.data.param; 10 | 11 | e.setMessage( 12 | 'The value of the "' + fieldName + 13 | '" field has to be less than or equal "' + compareValue + '"' 14 | ); 15 | } 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /lib/validators/size/max_length.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'maxLength', 3 | validate: function(fieldValue, fieldName, maxLength) { 4 | if (_.isNull(fieldValue) || !_.has(fieldValue, 'length')) { 5 | return false; 6 | } 7 | 8 | return fieldValue.length <= maxLength; 9 | }, 10 | events: { 11 | validationerror: function(e) { 12 | var fieldName = e.data.fieldName; 13 | var maxLength = e.data.param; 14 | 15 | e.setMessage( 16 | 'The length of the value of the "' + fieldName + 17 | '" field has to be at most ' + maxLength 18 | ); 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /lib/validators/size/min_length.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'minLength', 3 | validate: function(fieldValue, fieldName, minLength) { 4 | if (_.isNull(fieldValue) || !_.has(fieldValue, 'length')) { 5 | return false; 6 | } 7 | 8 | return fieldValue.length >= minLength; 9 | }, 10 | events: { 11 | validationerror: function(e) { 12 | var fieldName = e.data.fieldName; 13 | var minLength = e.data.param; 14 | 15 | e.setMessage( 16 | 'The length of the value of the "' + fieldName + 17 | '" field has to be at least ' + minLength 18 | ); 19 | } 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /lib/validators/type/array.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'array', 3 | validate: _.isArray, 4 | events: { 5 | validationerror: function(e) { 6 | var fieldName = e.data.fieldName; 7 | 8 | e.setMessage( 9 | 'The value of the "' + fieldName + '" field has to be an array' 10 | ); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /lib/validators/type/boolean.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'boolean', 3 | validate: _.isBoolean, 4 | events: { 5 | validationerror: function(e) { 6 | var fieldName = e.data.fieldName; 7 | 8 | e.setMessage( 9 | 'The value of the "' + fieldName + '" field has to be a boolean' 10 | ); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /lib/validators/type/date.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'date', 3 | validate: function(fieldValue) { 4 | return _.isDate(fieldValue) && !_.isNaN(fieldValue.valueOf()); 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | 10 | e.setMessage( 11 | 'The value of the "' + fieldName + '" field has to be a date' 12 | ); 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /lib/validators/type/email.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'email', 3 | validate: function(fieldValue) { 4 | // Create email regular expression. 5 | var re = /^[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,}$/i; 6 | 7 | return re.test(fieldValue); 8 | }, 9 | events: { 10 | validationerror: function(e) { 11 | var fieldName = e.data.fieldName; 12 | 13 | e.setMessage( 14 | 'The value of the "' + fieldName + 15 | '" field has to be an appropiate email address' 16 | ); 17 | } 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /lib/validators/type/number.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'number', 3 | validate: function(fieldValue) { 4 | return _.isNumber(fieldValue) && !_.isNaN(fieldValue); 5 | }, 6 | events: { 7 | validationerror: function(e) { 8 | var fieldName = e.data.fieldName; 9 | 10 | e.setMessage( 11 | 'The value of the "' + fieldName + '" field has to be a number' 12 | ); 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /lib/validators/type/object.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'object', 3 | validate: _.isObject, 4 | events: { 5 | validationerror: function(e) { 6 | var fieldName = e.data.fieldName; 7 | 8 | e.setMessage( 9 | 'The value of the "' + fieldName + '" field has to be an object' 10 | ); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /lib/validators/type/string.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'string', 3 | validate: _.isString, 4 | events: { 5 | validationError: function(e) { 6 | var fieldName = e.data.fieldName; 7 | 8 | e.setMessage( 9 | 'The value of the "' + fieldName + '" field has to be a string' 10 | ); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /lib/validators/type/url.js: -------------------------------------------------------------------------------- 1 | Astro.createValidator({ 2 | name: 'url', 3 | validate: function(fieldValue, fieldName, maxLength) { 4 | var re = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; 5 | return re.test(fieldValue); 6 | }, 7 | events: { 8 | validationError: function(e) { 9 | var fieldName = e.data.fieldName; 10 | e.setMessage( 11 | 'The value of the "' + fieldName + 12 | '" field has to be an appropiate url' 13 | ); 14 | } 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jagi:astronomy-validators', 3 | version: '1.1.2', 4 | summary: 'Validators for Meteor Astronomy', 5 | git: 'https://github.com/jagi/meteor-astronomy-validators.git' 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | api.versionsFrom('1.1.0.2'); 10 | 11 | api.use('jagi:astronomy@1.2.3'); 12 | api.use('jagi:reactive-map@2.0.0'); 13 | api.use('underscore'); 14 | api.use('check'); 15 | api.use('tracker'); 16 | api.use('ejson'); 17 | 18 | api.imply('jagi:astronomy'); 19 | 20 | // Module. 21 | api.addFiles([ 22 | 'lib/module/global.js', 23 | 'lib/module/validation_error.js', 24 | 'lib/module/validation_error_event.js', 25 | 'lib/module/validator.js', 26 | 'lib/module/field_validator.js', 27 | 'lib/module/create_validator.js', 28 | 'lib/module/validate.js', 29 | 'lib/module/get_error.js', 30 | 'lib/module/ejson.js', 31 | 'lib/module/init_class.js', 32 | 'lib/module/init_definition.js' 33 | ], ['client', 'server']); 34 | 35 | // Type validators. 36 | api.addFiles([ 37 | 'lib/validators/type/string.js', 38 | 'lib/validators/type/number.js', 39 | 'lib/validators/type/boolean.js', 40 | 'lib/validators/type/array.js', 41 | 'lib/validators/type/object.js', 42 | 'lib/validators/type/date.js', 43 | 'lib/validators/type/email.js', 44 | 'lib/validators/type/url.js' 45 | ], ['client', 'server']); 46 | 47 | // Existence validators. 48 | api.addFiles([ 49 | 'lib/validators/existence/required.js', 50 | 'lib/validators/existence/null.js', 51 | 'lib/validators/existence/not_null.js', 52 | ], ['client', 'server']); 53 | 54 | // Size validators. 55 | api.addFiles([ 56 | 'lib/validators/size/length.js', 57 | 'lib/validators/size/min_length.js', 58 | 'lib/validators/size/max_length.js', 59 | 'lib/validators/size/gt.js', 60 | 'lib/validators/size/gte.js', 61 | 'lib/validators/size/lt.js', 62 | 'lib/validators/size/lte.js' 63 | ], ['client', 'server']); 64 | 65 | // Comparison validators. 66 | api.addFiles([ 67 | 'lib/validators/comparison/choice.js', 68 | 'lib/validators/comparison/unique.js', 69 | 'lib/validators/comparison/equal.js', 70 | 'lib/validators/comparison/equal_to.js', 71 | 'lib/validators/comparison/regexp.js' 72 | ], ['client', 'server']); 73 | 74 | // Logical validators. 75 | api.addFiles([ 76 | 'lib/validators/logical/and.js', 77 | 'lib/validators/logical/or.js', 78 | 'lib/validators/logical/if.js', 79 | 'lib/validators/logical/switch.js' 80 | ], ['client', 'server']); 81 | 82 | // Embeded validators. 83 | api.addFiles([ 84 | 'lib/validators/nested/every.js', 85 | 'lib/validators/nested/has.js', 86 | 'lib/validators/nested/contains.js' 87 | ], ['client', 'server']); 88 | 89 | api.export(['Validators'], ['client', 'server']); 90 | }); 91 | --------------------------------------------------------------------------------