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.mddocs/

0

# Validation

1

2

Comprehensive validation system supporting object validation, MongoDB modifiers, custom validators, and detailed error reporting.

3

4

## Capabilities

5

6

### Object Validation

7

8

Primary validation method that throws errors on validation failure.

9

10

```typescript { .api }

11

/**

12

* Validates an object against the schema, throwing an error if validation fails

13

* @param obj - Object to validate

14

* @param options - Validation options

15

* @throws ValidationError if validation fails

16

*/

17

validate(obj: any, options?: ValidationOptions): void;

18

19

interface ValidationOptions {

20

/** Extended custom context for validation functions */

21

extendedCustomContext?: Record<string | number | symbol, unknown>;

22

/** Array of field keys to ignore during validation */

23

ignore?: string[];

24

/** Array of field keys to validate (validates only these keys) */

25

keys?: string[];

26

/** Whether to validate as MongoDB modifier document */

27

modifier?: boolean;

28

/** MongoObject instance for modifier validation */

29

mongoObject?: any;

30

/** Whether this is an upsert operation */

31

upsert?: boolean;

32

}

33

```

34

35

**Usage Examples:**

36

37

```typescript

38

import SimpleSchema from "simpl-schema";

39

40

const userSchema = new SimpleSchema({

41

name: String,

42

email: String,

43

age: Number

44

});

45

46

// Basic validation - throws on error

47

try {

48

userSchema.validate({ name: "John", email: "john@example.com", age: 25 });

49

console.log("Valid!");

50

} catch (error) {

51

console.log("Validation failed:", error.message);

52

}

53

54

// Validate specific keys only

55

userSchema.validate(

56

{ name: "John", age: 25 },

57

{ keys: ['name', 'age'] }

58

);

59

60

// Validate MongoDB modifier document

61

userSchema.validate(

62

{ $set: { name: "John Doe" } },

63

{ modifier: true }

64

);

65

```

66

67

### Static Validation

68

69

Class-level validation method for one-off validations without creating schema instances.

70

71

```typescript { .api }

72

/**

73

* Static validation method for validating against schema definitions

74

* @param obj - Object to validate

75

* @param schema - Schema instance or definition to validate against

76

* @param options - Validation options

77

* @throws ValidationError if validation fails

78

*/

79

static validate(obj: any, schema: SimpleSchema | SchemaDefinition, options?: ValidationOptions): void;

80

```

81

82

**Usage Examples:**

83

84

```typescript

85

// Validate against schema definition directly

86

SimpleSchema.validate(

87

{ name: "John", age: 25 },

88

{ name: String, age: Number }

89

);

90

91

// Validate against existing schema

92

const userSchema = new SimpleSchema({ name: String, age: Number });

93

SimpleSchema.validate({ name: "John", age: 25 }, userSchema);

94

```

95

96

### Async Validation

97

98

Async validation method that returns validation errors as a promise instead of throwing.

99

100

```typescript { .api }

101

/**

102

* Validates an object and returns validation errors as a promise

103

* @param obj - Object to validate

104

* @param options - Validation options

105

* @returns Promise that resolves to array of validation errors

106

*/

107

async validateAndReturnErrorsPromise(obj: any, options: ValidationOptions): Promise<ValidationError[]>;

108

```

109

110

**Usage Examples:**

111

112

```typescript

113

const userSchema = new SimpleSchema({

114

name: { type: String, min: 2 },

115

email: { type: String, regEx: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ },

116

age: { type: Number, min: 0 }

117

});

118

119

// Async validation that returns errors instead of throwing

120

const errors = await userSchema.validateAndReturnErrorsPromise({

121

name: "J", // Too short

122

email: "invalid", // Invalid format

123

age: -5 // Below minimum

124

});

125

126

console.log(errors);

127

// [

128

// { name: 'name', type: 'minString', value: 'J', message: 'Name must be at least 2 characters' },

129

// { name: 'email', type: 'regEx', value: 'invalid', message: 'Email failed regular expression validation' },

130

// { name: 'age', type: 'minNumber', value: -5, message: 'Age must be at least 0' }

131

// ]

132

133

// Handle validation in async context

134

try {

135

const validationErrors = await userSchema.validateAndReturnErrorsPromise(userData);

136

if (validationErrors.length > 0) {

137

// Handle validation errors

138

validationErrors.forEach(error => {

139

console.log(`Field ${error.name}: ${error.message}`);

140

});

141

} else {

142

console.log('Validation passed!');

143

}

144

} catch (error) {

145

console.log('Validation system error:', error);

146

}

147

```

148

149

### Validator Functions

150

151

Create reusable validator functions for repeated validation scenarios.

152

153

```typescript { .api }

154

/**

155

* Returns a validator function that can be called repeatedly

156

* @param options - Validation options with additional configuration

157

* @returns Function that validates objects and returns boolean or throws

158

*/

159

validator(options?: ValidationOptions & {

160

clean?: boolean;

161

returnErrorsPromise?: boolean;

162

}): Function;

163

164

/**

165

* Returns a form-specific validator function that returns errors as a promise

166

* @param options - Form validation options

167

* @returns Function that validates and returns promise with validation errors

168

*/

169

getFormValidator(options?: ValidationOptions): (obj: Record<string, any>) => Promise<ValidationError[]>;

170

```

171

172

**Usage Examples:**

173

174

```typescript

175

const userSchema = new SimpleSchema({

176

name: String,

177

email: String

178

});

179

180

// Create validator that throws on error

181

const validateUser = userSchema.validator();

182

validateUser({ name: "John", email: "john@example.com" });

183

184

// Create validator that cleans before validating

185

const cleanAndValidate = userSchema.validator({ clean: true });

186

187

// Create validator that returns promise with errors

188

const asyncValidator = userSchema.validator({ returnErrorsPromise: true });

189

asyncValidator(userData).then(errors => {

190

if (errors.length > 0) {

191

console.log("Validation errors:", errors);

192

}

193

});

194

195

// Create form validator (always returns promise with errors)

196

const formValidator = userSchema.getFormValidator();

197

formValidator(formData).then(errors => {

198

if (errors.length > 0) {

199

// Display form errors to user

200

errors.forEach(error => {

201

displayFieldError(error.name, error.message);

202

});

203

} else {

204

// Submit form

205

submitForm(formData);

206

}

207

});

208

```

209

210

### Validation Contexts

211

212

Create validation contexts for collecting errors without throwing exceptions.

213

214

```typescript { .api }

215

/**

216

* Creates a new validation context for this schema

217

* @returns New ValidationContext instance

218

*/

219

newContext(): ValidationContext;

220

221

/**

222

* Gets or creates a named validation context

223

* @param name - Context name for reuse

224

* @returns Named ValidationContext instance

225

*/

226

namedContext(name?: string): ValidationContext;

227

```

228

229

**Usage Examples:**

230

231

```typescript

232

const userSchema = new SimpleSchema({

233

name: String,

234

email: String

235

});

236

237

// Create new context

238

const context = userSchema.newContext();

239

const isValid = context.validate({ name: "John" }); // false

240

if (!isValid) {

241

console.log(context.validationErrors()); // Array of errors

242

}

243

244

// Use named context for persistence

245

const formContext = userSchema.namedContext('userForm');

246

formContext.validate(formData);

247

// Later, reuse the same context

248

const sameContext = userSchema.namedContext('userForm');

249

console.log(sameContext.validationErrors());

250

```

251

252

### Custom Validators

253

254

Add custom validation logic at the schema or field level.

255

256

```typescript { .api }

257

/**

258

* Adds a custom validator function to this schema instance

259

* @param func - Validator function to add

260

*/

261

addValidator(func: ValidatorFunction): void;

262

263

/**

264

* Adds a document-level validator function to this schema instance

265

* @param func - Document validator function to add

266

*/

267

addDocValidator(func: DocValidatorFunction): void;

268

269

/**

270

* Adds a custom validator function globally to all schema instances

271

* @param func - Validator function to add globally

272

*/

273

static addValidator(func: ValidatorFunction): void;

274

275

/**

276

* Adds a document-level validator function globally to all schema instances

277

* @param func - Document validator function to add globally

278

*/

279

static addDocValidator(func: DocValidatorFunction): void;

280

281

// Validator function types

282

type ValidatorFunction = (this: ValidatorContext) => void | undefined | boolean | string | ValidationErrorResult;

283

type DocValidatorFunction = (this: DocValidatorContext, obj: Record<string, unknown>) => ValidationError[];

284

285

interface ValidatorContext {

286

key: string;

287

keyPath: string;

288

value: any;

289

definition: StandardSchemaKeyDefinitionWithSimpleTypes;

290

isSet: boolean;

291

operator: string | null;

292

validationContext: ValidationContext;

293

field(key: string): FieldInfo<any>;

294

siblingField(key: string): FieldInfo<any>;

295

addValidationErrors(errors: ValidationError[]): void;

296

}

297

```

298

299

**Usage Examples:**

300

301

```typescript

302

// Field-level custom validator

303

const userSchema = new SimpleSchema({

304

email: {

305

type: String,

306

custom() {

307

if (!this.value.includes('@')) {

308

return 'emailInvalid';

309

}

310

}

311

},

312

password: {

313

type: String,

314

min: 8,

315

custom() {

316

if (!/[A-Z]/.test(this.value)) {

317

return 'passwordNeedsUppercase';

318

}

319

}

320

}

321

});

322

323

// Schema-level custom validator

324

userSchema.addValidator(function() {

325

if (this.key === 'confirmPassword') {

326

const password = this.field('password').value;

327

if (password !== this.value) {

328

return 'passwordMismatch';

329

}

330

}

331

});

332

333

// Document-level validator

334

userSchema.addDocValidator(function(obj) {

335

const errors = [];

336

if (obj.age < 18 && obj.hasAccount) {

337

errors.push({

338

name: 'hasAccount',

339

type: 'minorWithAccount',

340

value: obj.hasAccount

341

});

342

}

343

return errors;

344

});

345

346

// Global validator affecting all schemas

347

SimpleSchema.addValidator(function() {

348

if (this.key.endsWith('Email') && this.isSet) {

349

if (!this.value.includes('@')) {

350

return 'mustBeEmail';

351

}

352

}

353

});

354

```

355

356

### MongoDB Modifier Validation

357

358

Validate MongoDB update modifier documents like `$set`, `$unset`, `$push`, etc.

359

360

```typescript { .api }

361

// Enable modifier validation in options

362

interface ValidationOptions {

363

/** Whether to validate as MongoDB modifier document */

364

modifier?: boolean;

365

/** MongoObject instance for advanced modifier validation */

366

mongoObject?: any;

367

/** Whether this is an upsert operation */

368

upsert?: boolean;

369

}

370

```

371

372

**Usage Examples:**

373

374

```typescript

375

const userSchema = new SimpleSchema({

376

'profile.name': String,

377

'profile.age': Number,

378

tags: [String],

379

lastLogin: Date

380

});

381

382

// Validate $set modifier

383

userSchema.validate({

384

$set: {

385

'profile.name': 'John Doe',

386

'profile.age': 30

387

}

388

}, { modifier: true });

389

390

// Validate $push modifier

391

userSchema.validate({

392

$push: {

393

tags: 'javascript'

394

}

395

}, { modifier: true });

396

397

// Validate $unset modifier

398

userSchema.validate({

399

$unset: {

400

'profile.age': ""

401

}

402

}, { modifier: true });

403

404

// Complex modifier with multiple operations

405

userSchema.validate({

406

$set: { 'profile.name': 'Jane Doe' },

407

$push: { tags: 'react' },

408

$currentDate: { lastLogin: true }

409

}, { modifier: true });

410

```

411

412

### Async Validation

413

414

Handle validation operations that return promises for async validation scenarios.

415

416

```typescript { .api }

417

/**

418

* Validates and returns errors as a promise

419

* @param obj - Object to validate

420

* @param options - Validation options

421

* @returns Promise resolving to array of ValidationError objects

422

*/

423

validateAndReturnErrorsPromise(obj: any, options: ValidationOptions): Promise<ValidationError[]>;

424

```

425

426

**Usage Examples:**

427

428

```typescript

429

const userSchema = new SimpleSchema({

430

username: {

431

type: String,

432

custom() {

433

// Simulate async validation (e.g., checking uniqueness)

434

return new Promise((resolve) => {

435

setTimeout(() => {

436

if (this.value === 'admin') {

437

resolve('usernameNotAllowed');

438

} else {

439

resolve();

440

}

441

}, 100);

442

});

443

}

444

}

445

});

446

447

// Use async validation

448

userSchema.validateAndReturnErrorsPromise({ username: 'admin' })

449

.then(errors => {

450

if (errors.length > 0) {

451

console.log('Validation errors:', errors);

452

} else {

453

console.log('Valid!');

454

}

455

});

456

```

457

458

## Types

459

460

```typescript { .api }

461

interface ValidationError {

462

/** Localized error message */

463

message?: string;

464

/** Field name that failed validation */

465

name: string;

466

/** Type of validation error */

467

type: string;

468

/** Value that failed validation */

469

value: any;

470

/** Additional error properties */

471

[prop: string]: any;

472

}

473

474

interface ValidationErrorResult {

475

type: string;

476

value?: any;

477

message?: string;

478

}

479

480

interface FieldInfo<ValueType> {

481

value: ValueType;

482

isSet: boolean;

483

operator: string | null;

484

}

485

```