1
1
import MongoObject from 'mongo-object' ;
2
2
import doValidation from './doValidation' ;
3
3
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
+ */
4
18
export default class ValidationContext {
5
19
/**
6
20
* @param {SimpleSchema } ss SimpleSchema instance to use for validation
7
21
* @param {String } [name] Optional context name, accessible on context.name.
8
22
*/
9
23
constructor ( ss , name ) {
10
24
this . name = name ;
25
+
11
26
this . _simpleSchema = ss ;
12
27
this . _schema = ss . schema ( ) ;
13
28
this . _schemaKeys = Object . keys ( this . _schema ) ;
14
29
this . _validationErrors = [ ] ;
30
+ this . _deps = { } ;
15
31
16
32
// Set up validation dependencies
17
- this . _deps = { } ;
18
33
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 ) {
20
47
this . _depsAny = new tracker . Dependency ( ) ;
21
48
this . _schemaKeys . forEach ( ( key ) => {
22
49
this . _deps [ key ] = new tracker . Dependency ( ) ;
23
50
} ) ;
24
51
}
25
52
}
26
53
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
+ */
40
59
setValidationErrors ( errors ) {
41
60
const previousValidationErrors = this . _validationErrors . map ( ( o ) => o . name ) ;
42
61
const newValidationErrors = errors . map ( ( o ) => o . name ) ;
@@ -48,6 +67,10 @@ export default class ValidationContext {
48
67
this . _markKeysChanged ( changedKeys ) ;
49
68
}
50
69
70
+ /**
71
+ * Adds new validation errors to the list.
72
+ * @param errors ValidationError[]
73
+ */
51
74
addValidationErrors ( errors ) {
52
75
const newValidationErrors = errors . map ( ( o ) => o . name ) ;
53
76
@@ -57,11 +80,20 @@ export default class ValidationContext {
57
80
this . _markKeysChanged ( newValidationErrors ) ;
58
81
}
59
82
60
- // Reset the validationErrors array
83
+ /**
84
+ * Flushes/empties the list of validation errors.
85
+ */
61
86
reset ( ) {
62
87
this . setValidationErrors ( [ ] ) ;
63
88
}
64
89
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
+ */
65
97
getErrorForKey ( key , genericKey = MongoObject . makeKeyGeneric ( key ) ) {
66
98
const errors = this . _validationErrors ;
67
99
const errorForKey = errors . find ( ( error ) => error . name === key ) ;
@@ -70,17 +102,24 @@ export default class ValidationContext {
70
102
return errors . find ( ( error ) => error . name === genericKey ) ;
71
103
}
72
104
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
+ */
78
111
keyIsInvalid ( key , genericKey = MongoObject . makeKeyGeneric ( key ) ) {
79
112
if ( Object . prototype . hasOwnProperty . call ( this . _deps , genericKey ) ) this . _deps [ genericKey ] . depend ( ) ;
80
113
81
114
return this . _keyIsInvalid ( key , genericKey ) ;
82
115
}
83
116
117
+ /**
118
+ *
119
+ * @param key
120
+ * @param genericKey
121
+ * @return {string|* }
122
+ */
84
123
keyErrorMessage ( key , genericKey = MongoObject . makeKeyGeneric ( key ) ) {
85
124
if ( Object . prototype . hasOwnProperty . call ( this . _deps , genericKey ) ) this . _deps [ genericKey ] . depend ( ) ;
86
125
@@ -91,7 +130,16 @@ export default class ValidationContext {
91
130
}
92
131
93
132
/**
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
95
143
*/
96
144
validate ( obj , {
97
145
extendedCustomContext = { } ,
@@ -131,11 +179,19 @@ export default class ValidationContext {
131
179
return ! validationErrors . length ;
132
180
}
133
181
182
+ /**
183
+ * returns if this context has no errors. reactive.
184
+ * @return {boolean }
185
+ */
134
186
isValid ( ) {
135
187
this . _depsAny && this . _depsAny . depend ( ) ;
136
188
return this . _validationErrors . length === 0 ;
137
189
}
138
190
191
+ /**
192
+ * returns the list of validation errors. reactive.
193
+ * @return {ValidationError[] }
194
+ */
139
195
validationErrors ( ) {
140
196
this . _depsAny && this . _depsAny . depend ( ) ;
141
197
return this . _validationErrors ;
@@ -144,4 +200,25 @@ export default class ValidationContext {
144
200
clean ( ...args ) {
145
201
return this . _simpleSchema . clean ( ...args ) ;
146
202
}
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
+ }
147
224
}
0 commit comments