11import MongoObject from 'mongo-object' ;
22import doValidation from './doValidation' ;
33
4+ /**
5+ * @typedef ValidationError
6+ * @type object
7+ * @property name {string} error name
8+ * @property type {string} error type name
9+ * @property value {string} actuall error message value
10+ */
11+
12+ /**
13+ * State representation of a validation for
14+ * a given schema.
15+ *
16+ *
17+ */
418export default class ValidationContext {
519 /**
620 * @param {SimpleSchema } ss SimpleSchema instance to use for validation
721 * @param {String } [name] Optional context name, accessible on context.name.
822 */
923 constructor ( ss , name ) {
1024 this . name = name ;
25+
1126 this . _simpleSchema = ss ;
1227 this . _schema = ss . schema ( ) ;
1328 this . _schemaKeys = Object . keys ( this . _schema ) ;
1429 this . _validationErrors = [ ] ;
30+ this . _deps = { } ;
1531
1632 // Set up validation dependencies
17- this . _deps = { } ;
1833 const { tracker } = ss . _constructorOptions ;
19- if ( tracker ) {
34+ this . reactive ( tracker ) ;
35+ }
36+ //---------------------------------------------------------------------------
37+ // PUBLIC
38+ //---------------------------------------------------------------------------
39+
40+ /**
41+ * Makes this validation context
42+ * reactive for Meteor-Tracker.
43+ * @param tracker {Tracker}
44+ */
45+ reactive ( tracker ) {
46+ if ( tracker && Object . keys ( this . _deps ) . length === 0 ) {
2047 this . _depsAny = new tracker . Dependency ( ) ;
2148 this . _schemaKeys . forEach ( ( key ) => {
2249 this . _deps [ key ] = new tracker . Dependency ( ) ;
2350 } ) ;
2451 }
2552 }
2653
27- _markKeyChanged ( key ) {
28- const genericKey = MongoObject . makeKeyGeneric ( key ) ;
29- if ( Object . prototype . hasOwnProperty . call ( this . _deps , genericKey ) ) this . _deps [ genericKey ] . changed ( ) ;
30- }
31-
32- _markKeysChanged ( keys ) {
33- if ( ! keys || ! Array . isArray ( keys ) || ! keys . length ) return ;
34-
35- keys . forEach ( ( key ) => this . _markKeyChanged ( key ) ) ;
36-
37- this . _depsAny && this . _depsAny . changed ( ) ;
38- }
39-
54+ /**
55+ * Merges existing with a list of new validation errors.
56+ * Reactive.
57+ * @param errors ValidationError[]
58+ */
4059 setValidationErrors ( errors ) {
4160 const previousValidationErrors = this . _validationErrors . map ( ( o ) => o . name ) ;
4261 const newValidationErrors = errors . map ( ( o ) => o . name ) ;
@@ -48,6 +67,10 @@ export default class ValidationContext {
4867 this . _markKeysChanged ( changedKeys ) ;
4968 }
5069
70+ /**
71+ * Adds new validation errors to the list.
72+ * @param errors ValidationError[]
73+ */
5174 addValidationErrors ( errors ) {
5275 const newValidationErrors = errors . map ( ( o ) => o . name ) ;
5376
@@ -57,11 +80,20 @@ export default class ValidationContext {
5780 this . _markKeysChanged ( newValidationErrors ) ;
5881 }
5982
60- // Reset the validationErrors array
83+ /**
84+ * Flushes/empties the list of validation errors.
85+ */
6186 reset ( ) {
6287 this . setValidationErrors ( [ ] ) ;
6388 }
6489
90+ /**
91+ * Returns a validation error for a given key.
92+ * @param key {string} the key of the field to access errors for
93+ * @param genericKey {string} generic version of the key, you usually don't need
94+ * to explcitly call this. If you do, you need to wrap it using `MongoObject.makeKeyGeneric`
95+ * @return {ValidationError|undefined }
96+ */
6597 getErrorForKey ( key , genericKey = MongoObject . makeKeyGeneric ( key ) ) {
6698 const errors = this . _validationErrors ;
6799 const errorForKey = errors . find ( ( error ) => error . name === key ) ;
@@ -70,17 +102,24 @@ export default class ValidationContext {
70102 return errors . find ( ( error ) => error . name === genericKey ) ;
71103 }
72104
73- _keyIsInvalid ( key , genericKey ) {
74- return ! ! this . getErrorForKey ( key , genericKey ) ;
75- }
76-
77- // Like the internal one, but with deps
105+ /**
106+ * Returns, whether there is an error for a given key. Reactive.
107+ * @param key {string}
108+ * @param genericKey {string}
109+ * @return {boolean }
110+ */
78111 keyIsInvalid ( key , genericKey = MongoObject . makeKeyGeneric ( key ) ) {
79112 if ( Object . prototype . hasOwnProperty . call ( this . _deps , genericKey ) ) this . _deps [ genericKey ] . depend ( ) ;
80113
81114 return this . _keyIsInvalid ( key , genericKey ) ;
82115 }
83116
117+ /**
118+ *
119+ * @param key
120+ * @param genericKey
121+ * @return {string|* }
122+ */
84123 keyErrorMessage ( key , genericKey = MongoObject . makeKeyGeneric ( key ) ) {
85124 if ( Object . prototype . hasOwnProperty . call ( this . _deps , genericKey ) ) this . _deps [ genericKey ] . depend ( ) ;
86125
@@ -91,7 +130,16 @@ export default class ValidationContext {
91130 }
92131
93132 /**
94- * Validates the object against the simple schema and sets a reactive array of error objects
133+ * Validates the object against the simple schema
134+ * and sets a reactive array of error objects.
135+ * @param obj {object} the document (object) to validate
136+ * @param extendedCustomcontext {object=}
137+ * @param ignoreTypes {string[]=} list of names of ValidationError types to ignore
138+ * @param keysToValidate {string[]=} list of field names (keys) to validate. Other keys are ignored then
139+ * @param isModifier {boolean=} set to true if the document contains MongoDB modifiers
140+ * @param mongoObject {MongoObject=} MongoObject instance to generate keyInfo
141+ * @param isUpsert {boolean=} set to true if the document contains upsert modifiers
142+ * @return {boolean } true if no ValidationError was found, otherwise false
95143 */
96144 validate ( obj , {
97145 extendedCustomContext = { } ,
@@ -131,11 +179,19 @@ export default class ValidationContext {
131179 return ! validationErrors . length ;
132180 }
133181
182+ /**
183+ * returns if this context has no errors. reactive.
184+ * @return {boolean }
185+ */
134186 isValid ( ) {
135187 this . _depsAny && this . _depsAny . depend ( ) ;
136188 return this . _validationErrors . length === 0 ;
137189 }
138190
191+ /**
192+ * returns the list of validation errors. reactive.
193+ * @return {ValidationError[] }
194+ */
139195 validationErrors ( ) {
140196 this . _depsAny && this . _depsAny . depend ( ) ;
141197 return this . _validationErrors ;
@@ -144,4 +200,25 @@ export default class ValidationContext {
144200 clean ( ...args ) {
145201 return this . _simpleSchema . clean ( ...args ) ;
146202 }
203+
204+ //---------------------------------------------------------------------------
205+ // PRIVATE
206+ //---------------------------------------------------------------------------
207+
208+ _markKeyChanged ( key ) {
209+ const genericKey = MongoObject . makeKeyGeneric ( key ) ;
210+ if ( Object . prototype . hasOwnProperty . call ( this . _deps , genericKey ) ) this . _deps [ genericKey ] . changed ( ) ;
211+ }
212+
213+ _markKeysChanged ( keys ) {
214+ if ( ! keys || ! Array . isArray ( keys ) || ! keys . length ) return ;
215+
216+ keys . forEach ( ( key ) => this . _markKeyChanged ( key ) ) ;
217+
218+ this . _depsAny && this . _depsAny . changed ( ) ;
219+ }
220+
221+ _keyIsInvalid ( key , genericKey ) {
222+ return ! ! this . getErrorForKey ( key , genericKey ) ;
223+ }
147224}
0 commit comments