or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-cleaning.mdindex.mdschema-definition.mdschema-introspection.mdutility-functions.mdvalidation-context.mdvalidation.md

validation-context.mddocs/

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

```