0
# Validation Context
1
2
Validation context management for collecting validation errors, checking validity, and providing detailed error information without throwing exceptions.
3
4
## Capabilities
5
6
### ValidationContext Class
7
8
The ValidationContext class provides a way to collect validation errors instead of throwing exceptions immediately.
9
10
```typescript { .api }
11
/**
12
* Validation context for collecting and managing validation errors
13
*/
14
class ValidationContext {
15
/** Optional context name for identification */
16
name?: string;
17
18
/**
19
* Validates an object and returns success status
20
* @param obj - Object to validate
21
* @param options - Validation options
22
* @returns true if valid, false if validation errors occurred
23
*/
24
validate(obj: ObjectToValidate, options?: ValidationOptions): boolean;
25
26
/**
27
* Checks if the context currently has no validation errors
28
* @returns true if no errors, false if errors exist
29
*/
30
isValid(): boolean;
31
32
/**
33
* Gets all current validation errors
34
* @returns Array of ValidationError objects
35
*/
36
validationErrors(): ValidationError[];
37
38
/**
39
* Sets the validation errors, replacing any existing errors
40
* @param errors - Array of ValidationError objects to set
41
*/
42
setValidationErrors(errors: ValidationError[]): void;
43
44
/**
45
* Adds validation errors to the existing errors
46
* @param errors - Array of ValidationError objects to add
47
*/
48
addValidationErrors(errors: ValidationError[]): void;
49
50
/**
51
* Clears all validation errors from the context
52
*/
53
reset(): void;
54
55
/**
56
* Gets the first validation error for a specific key
57
* @param key - Field key to get error for
58
* @param genericKey - Generic version of key for array items
59
* @returns ValidationError object or undefined if no error
60
*/
61
getErrorForKey(key: string, genericKey?: string): ValidationError | undefined;
62
63
/**
64
* Checks if a specific key has validation errors
65
* @param key - Field key to check
66
* @param genericKey - Generic version of key for array items
67
* @returns true if key has errors, false otherwise
68
*/
69
keyIsInvalid(key: string, genericKey?: string): boolean;
70
71
/**
72
* Gets formatted error message for a specific key
73
* @param key - Field key to get message for
74
* @param genericKey - Generic version of key for array items
75
* @returns Error message string or empty string if no error
76
*/
77
keyErrorMessage(key: string, genericKey?: string): string;
78
79
/**
80
* Cleans a document using the context's schema
81
* @param doc - Document to clean
82
* @param options - Cleaning options
83
* @returns Cleaned document
84
*/
85
clean(doc: Record<string | number | symbol, unknown>, options?: CleanOptions): Record<string | number | symbol, unknown>;
86
}
87
88
interface ValidationOptions {
89
extendedCustomContext?: Record<string | number | symbol, unknown>;
90
ignore?: string[];
91
keys?: string[];
92
modifier?: boolean;
93
mongoObject?: any;
94
upsert?: boolean;
95
}
96
97
type ObjectToValidate = Record<string | number | symbol, unknown>;
98
```
99
100
**Usage Examples:**
101
102
```typescript
103
import SimpleSchema from "simpl-schema";
104
105
const userSchema = new SimpleSchema({
106
name: {
107
type: String,
108
min: 2,
109
max: 50
110
},
111
email: {
112
type: String,
113
regEx: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
114
},
115
age: {
116
type: Number,
117
min: 18,
118
max: 120
119
}
120
});
121
122
// Create a validation context
123
const context = userSchema.newContext();
124
125
// Validate invalid data
126
const userData = {
127
name: "A", // Too short
128
email: "invalid-email", // Invalid format
129
age: 15 // Too young
130
};
131
132
const isValid = context.validate(userData);
133
console.log(isValid); // false
134
135
// Get all errors
136
const errors = context.validationErrors();
137
console.log(errors);
138
// [
139
// { name: 'name', type: 'minString', value: 'A' },
140
// { name: 'email', type: 'regEx', value: 'invalid-email' },
141
// { name: 'age', type: 'minNumber', value: 15 }
142
// ]
143
144
// Check validity
145
console.log(context.isValid()); // false
146
147
// Get specific error
148
const nameError = context.getErrorForKey('name');
149
console.log(nameError); // { name: 'name', type: 'minString', value: 'A' }
150
151
// Check if specific key is invalid
152
console.log(context.keyIsInvalid('email')); // true
153
console.log(context.keyIsInvalid('nonexistent')); // false
154
155
// Get error message for key
156
console.log(context.keyErrorMessage('age')); // "Age must be at least 18"
157
```
158
159
### Creating Validation Contexts
160
161
Methods to create and manage validation contexts.
162
163
```typescript { .api }
164
/**
165
* Creates a new validation context for the schema
166
* @returns New ValidationContext instance
167
*/
168
newContext(): ValidationContext;
169
170
/**
171
* Gets or creates a named validation context that persists
172
* @param name - Context name for reuse and identification
173
* @returns Named ValidationContext instance
174
*/
175
namedContext(name?: string): ValidationContext;
176
```
177
178
**Usage Examples:**
179
180
```typescript
181
const userSchema = new SimpleSchema({
182
name: String,
183
email: String
184
});
185
186
// Create new context each time
187
const context1 = userSchema.newContext();
188
const context2 = userSchema.newContext();
189
console.log(context1 === context2); // false - different instances
190
191
// Use named contexts for persistence
192
const formContext = userSchema.namedContext('userForm');
193
formContext.validate({ name: 'John' }); // Invalid - missing email
194
195
// Later, get the same named context
196
const sameContext = userSchema.namedContext('userForm');
197
console.log(formContext === sameContext); // true - same instance
198
console.log(sameContext.validationErrors()); // Still has errors from before
199
200
// Different named context
201
const adminContext = userSchema.namedContext('adminForm');
202
console.log(adminContext.validationErrors()); // Empty - different context
203
```
204
205
### Error Management
206
207
Methods for managing validation errors within a context.
208
209
```typescript { .api }
210
/**
211
* Manually set validation errors, replacing existing ones
212
* @param errors - Array of ValidationError objects
213
*/
214
setValidationErrors(errors: ValidationError[]): void;
215
216
/**
217
* Add additional validation errors to existing ones
218
* @param errors - Array of ValidationError objects to add
219
*/
220
addValidationErrors(errors: ValidationError[]): void;
221
222
/**
223
* Clear all validation errors from the context
224
*/
225
reset(): void;
226
```
227
228
**Usage Examples:**
229
230
```typescript
231
const context = userSchema.newContext();
232
233
// Manually set errors
234
context.setValidationErrors([
235
{ name: 'email', type: 'required', value: undefined },
236
{ name: 'age', type: 'minNumber', value: 15 }
237
]);
238
239
console.log(context.validationErrors().length); // 2
240
241
// Add more errors
242
context.addValidationErrors([
243
{ name: 'name', type: 'minString', value: 'A' }
244
]);
245
246
console.log(context.validationErrors().length); // 3
247
248
// Clear all errors
249
context.reset();
250
console.log(context.validationErrors().length); // 0
251
console.log(context.isValid()); // true
252
```
253
254
### Key-Specific Error Queries
255
256
Methods for checking errors on specific fields.
257
258
```typescript { .api }
259
/**
260
* Get the first error for a specific field key
261
* @param key - Field key to check
262
* @param genericKey - Generic key for array items (e.g., 'items.$')
263
* @returns ValidationError or undefined
264
*/
265
getErrorForKey(key: string, genericKey?: string): ValidationError | undefined;
266
267
/**
268
* Check if a specific field key is invalid
269
* @param key - Field key to check
270
* @param genericKey - Generic key for array items
271
* @returns true if field has errors
272
*/
273
keyIsInvalid(key: string, genericKey?: string): boolean;
274
275
/**
276
* Get formatted error message for a specific field key
277
* @param key - Field key to get message for
278
* @param genericKey - Generic key for array items
279
* @returns Error message string
280
*/
281
keyErrorMessage(key: string, genericKey?: string): string;
282
```
283
284
**Usage Examples:**
285
286
```typescript
287
const schema = new SimpleSchema({
288
name: String,
289
tags: [String],
290
'tags.$': {
291
type: String,
292
min: 2
293
}
294
});
295
296
const context = schema.newContext();
297
298
// Validate data with errors
299
context.validate({
300
name: '', // Required but empty
301
tags: ['ok', 'x'] // Second tag too short
302
});
303
304
// Check specific field errors
305
console.log(context.keyIsInvalid('name')); // true
306
console.log(context.keyIsInvalid('tags')); // false - array itself is valid
307
console.log(context.keyIsInvalid('tags.1')); // true - specific array item invalid
308
309
// Get specific errors
310
const nameError = context.getErrorForKey('name');
311
console.log(nameError?.type); // 'required'
312
313
const tagError = context.getErrorForKey('tags.1', 'tags.$');
314
console.log(tagError?.type); // 'minString'
315
316
// Get error messages
317
console.log(context.keyErrorMessage('name')); // "Name is required"
318
console.log(context.keyErrorMessage('tags.1')); // "Tags $ must be at least 2 characters"
319
```
320
321
### Context-Based Cleaning
322
323
Use validation context for cleaning operations.
324
325
```typescript { .api }
326
/**
327
* Clean a document using the context's schema
328
* @param doc - Document to clean
329
* @param options - Cleaning options
330
* @returns Cleaned document
331
*/
332
clean(doc: Record<string | number | symbol, unknown>, options?: CleanOptions): Record<string | number | symbol, unknown>;
333
```
334
335
**Usage Examples:**
336
337
```typescript
338
const schema = new SimpleSchema({
339
name: {
340
type: String,
341
trim: true
342
},
343
age: Number
344
});
345
346
const context = schema.newContext();
347
348
const dirtyData = {
349
name: ' John Doe ',
350
age: '25',
351
extra: 'field'
352
};
353
354
// Clean using context
355
const cleaned = context.clean(dirtyData, {
356
autoConvert: true,
357
trimStrings: true,
358
filter: true
359
});
360
361
console.log(cleaned);
362
// { name: 'John Doe', age: 25 }
363
364
// Validate the cleaned data
365
const isValid = context.validate(cleaned);
366
console.log(isValid); // true
367
```
368
369
### Working with MongoDB Modifiers
370
371
Validate MongoDB update modifiers using validation contexts.
372
373
```typescript { .api }
374
// ValidationContext works with modifier validation
375
context.validate(modifierDoc, { modifier: true });
376
```
377
378
**Usage Examples:**
379
380
```typescript
381
const schema = new SimpleSchema({
382
'profile.name': String,
383
'profile.age': Number,
384
tags: [String]
385
});
386
387
const context = schema.newContext();
388
389
// Validate $set modifier
390
const isValidSet = context.validate({
391
$set: {
392
'profile.name': 'John Doe',
393
'profile.age': 30
394
}
395
}, { modifier: true });
396
397
console.log(isValidSet); // true
398
399
// Validate invalid $push modifier
400
const isValidPush = context.validate({
401
$push: {
402
tags: null // Invalid - can't push null
403
}
404
}, { modifier: true });
405
406
console.log(isValidPush); // false
407
console.log(context.validationErrors());
408
```
409
410
### Form Integration Patterns
411
412
Common patterns for using validation contexts with forms.
413
414
**Usage Examples:**
415
416
```typescript
417
// Form validation helper
418
class FormValidator {
419
constructor(schema, formName) {
420
this.schema = schema;
421
this.context = schema.namedContext(formName);
422
}
423
424
validate(formData) {
425
// Clean and validate
426
const cleaned = this.context.clean(formData, {
427
autoConvert: true,
428
trimStrings: true,
429
filter: true
430
});
431
432
const isValid = this.context.validate(cleaned);
433
434
return {
435
isValid,
436
errors: this.context.validationErrors(),
437
cleanedData: cleaned
438
};
439
}
440
441
getFieldError(fieldName) {
442
return this.context.keyErrorMessage(fieldName);
443
}
444
445
isFieldInvalid(fieldName) {
446
return this.context.keyIsInvalid(fieldName);
447
}
448
449
reset() {
450
this.context.reset();
451
}
452
}
453
454
// Usage
455
const userSchema = new SimpleSchema({...});
456
const validator = new FormValidator(userSchema, 'userRegistration');
457
458
const result = validator.validate(formData);
459
if (!result.isValid) {
460
console.log('Form errors:', result.errors);
461
}
462
```
463
464
## Types
465
466
```typescript { .api }
467
interface ValidationError {
468
/** Field name that failed validation */
469
name: string;
470
/** Type of validation error */
471
type: string;
472
/** Value that failed validation */
473
value: any;
474
/** Localized error message (optional) */
475
message?: string;
476
/** Additional error properties */
477
[prop: string]: any;
478
}
479
```