or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-jest-validate

Generic configuration validation tool that helps with warnings, errors and deprecation messages as well as showing users examples of correct configuration.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/jest-validate@30.1.x

To install, run

npx @tessl/cli install tessl/npm-jest-validate@30.1.0

0

# jest-validate

1

2

jest-validate is a generic configuration validation tool that helps with warnings, errors and deprecation messages as well as showing users examples of correct configuration. Originally developed for Jest, it provides a comprehensive validation framework for JavaScript/Node.js applications with extensive customization options.

3

4

## Package Information

5

6

- **Package Name**: jest-validate

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install jest-validate`

10

11

## Core Imports

12

13

```typescript

14

import { validate, validateCLIOptions, multipleValidOptions, ValidationError, format, formatPrettyObject, createDidYouMeanMessage, logValidationWarning } from "jest-validate";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { validate, validateCLIOptions, multipleValidOptions, ValidationError, format, formatPrettyObject, createDidYouMeanMessage, logValidationWarning } = require("jest-validate");

21

```

22

23

## Basic Usage

24

25

```typescript

26

import { validate, multipleValidOptions } from "jest-validate";

27

28

// Define example configuration (required)

29

const exampleConfig = {

30

transform: {},

31

testMatch: ["**/__tests__/**/*.(js|ts)"],

32

verbose: false,

33

timeout: 5000,

34

retries: multipleValidOptions(1, false) // allows number or boolean

35

};

36

37

// Validate user configuration

38

const result = validate(userConfig, { exampleConfig });

39

40

if (result.isValid) {

41

console.log("Configuration is valid!");

42

if (result.hasDeprecationWarnings) {

43

console.log("Note: Some deprecated options were found");

44

}

45

}

46

```

47

48

## Architecture

49

50

jest-validate is built around several key components:

51

52

- **Core Validation**: `validate()` function that compares configurations against example schemas

53

- **CLI Validation**: `validateCLIOptions()` for command-line argument validation with deprecation support

54

- **Type Checking**: Automatic type validation based on example configurations using JavaScript's native type system

55

- **Multiple Type Support**: `multipleValidOptions()` utility for options that accept different types

56

- **Error System**: Custom `ValidationError` class with formatted, colorized output

57

- **Deprecation Management**: Built-in handling for deprecated options with customizable warning messages

58

- **Extensible Handlers**: Pluggable error, warning, and unknown option handlers

59

60

## Capabilities

61

62

### Configuration Validation

63

64

Core validation functionality that compares user configurations against example schemas with comprehensive error reporting and type checking.

65

66

```typescript { .api }

67

/**

68

* Validates a configuration object against an example configuration schema

69

* @param config - The configuration object to validate

70

* @param options - Validation options including required exampleConfig

71

* @returns Validation result with deprecation warnings flag and validity status

72

*/

73

function validate(

74

config: Record<string, unknown>,

75

options: ValidationOptions

76

): { hasDeprecationWarnings: boolean; isValid: boolean };

77

78

interface ValidationOptions {

79

/** Additional comment text to display with error/warning messages */

80

comment?: string;

81

/** Custom validation condition function for comparing option values */

82

condition?: (option: unknown, validOption: unknown) => boolean;

83

/** Custom deprecation handler function */

84

deprecate?: (

85

config: Record<string, unknown>,

86

option: string,

87

deprecatedOptions: DeprecatedOptions,

88

options: ValidationOptions

89

) => boolean;

90

/** Object mapping deprecated option names to deprecation message functions */

91

deprecatedConfig?: DeprecatedOptions;

92

/** Custom error handler function */

93

error?: (

94

option: string,

95

received: unknown,

96

defaultValue: unknown,

97

options: ValidationOptions,

98

path?: Array<string>

99

) => void;

100

/** Required example configuration object that defines valid structure and types */

101

exampleConfig: Record<string, unknown>;

102

/** Whether to recursively validate nested objects (default: true) */

103

recursive?: boolean;

104

/** Array of key paths to exclude from recursive validation */

105

recursiveDenylist?: Array<string>;

106

/** Custom titles for error/warning messages */

107

title?: Title;

108

/** Custom handler for unknown/unrecognized options */

109

unknown?: (

110

config: Record<string, unknown>,

111

exampleConfig: Record<string, unknown>,

112

option: string,

113

options: ValidationOptions,

114

path?: Array<string>

115

) => void;

116

}

117

118

interface Title {

119

deprecation?: string;

120

error?: string;

121

warning?: string;

122

}

123

124

type DeprecatedOptions = Record<string, DeprecatedOptionFunc>;

125

type DeprecatedOptionFunc = (arg: Record<string, unknown>) => string;

126

```

127

128

**Usage Examples:**

129

130

```typescript

131

import { validate } from "jest-validate";

132

133

// Basic validation

134

const result = validate(userConfig, {

135

exampleConfig: {

136

verbose: true,

137

testTimeout: 5000,

138

setupFiles: []

139

}

140

});

141

142

// Custom validation with deprecation handling

143

const result = validate(userConfig, {

144

exampleConfig: { verbose: true },

145

deprecatedConfig: {

146

silent: () => 'Option "silent" has been replaced by "verbose"'

147

},

148

comment: 'See documentation at https://example.com/config'

149

});

150

151

// Recursive validation with denylist

152

const result = validate(userConfig, {

153

exampleConfig: { nested: { allowed: true, ignored: {} } },

154

recursive: true,

155

recursiveDenylist: ['nested.ignored'] // Skip validating nested.ignored

156

});

157

```

158

159

### CLI Options Validation

160

161

Validates command-line options against allowed option schemas with support for deprecated options, aliases, and automatic suggestion generation.

162

163

```typescript { .api }

164

/**

165

* Validates CLI options and arguments with deprecation support

166

* @param argv - Parsed command-line arguments object (typically from yargs)

167

* @param options - Object defining allowed options and their configuration

168

* @param rawArgv - Optional raw argument array for filtering

169

* @returns true if validation passes, throws ValidationError if not

170

*/

171

function validateCLIOptions(

172

argv: Config.Argv,

173

options: Record<string, Options> & { deprecationEntries?: DeprecatedOptions },

174

rawArgv?: Array<string>

175

): boolean;

176

177

interface Options {

178

/** Alias for the option (single string or array of strings) */

179

alias?: string | string[];

180

/** Additional option properties from yargs */

181

[key: string]: any;

182

}

183

184

type Config.Argv = Record<string, unknown>;

185

```

186

187

**Usage Examples:**

188

189

```typescript

190

import { validateCLIOptions } from "jest-validate";

191

192

// Define allowed CLI options

193

const allowedOptions = {

194

verbose: { alias: 'v' },

195

config: { alias: 'c' },

196

watch: { alias: 'w' },

197

help: { alias: 'h' }

198

};

199

200

// Validate CLI arguments

201

try {

202

validateCLIOptions(parsedArgs, allowedOptions);

203

console.log("CLI options are valid");

204

} catch (error) {

205

console.error(error.message);

206

}

207

208

// With deprecation entries

209

const optionsWithDeprecation = {

210

...allowedOptions,

211

deprecationEntries: {

212

runInBand: () => 'Option "runInBand" has been replaced by "maxWorkers=1"'

213

}

214

};

215

216

validateCLIOptions(parsedArgs, optionsWithDeprecation);

217

```

218

219

### Multiple Valid Options

220

221

Utility for creating configuration options that accept multiple types, enabling flexible API design while maintaining type safety.

222

223

```typescript { .api }

224

/**

225

* Creates a configuration that accepts multiple valid types for a single option

226

* Uses internal symbol marking to allow validation against multiple type examples

227

* @param args - Variable number of example values of different types

228

* @returns Array containing the examples, marked internally for multi-type validation

229

*/

230

function multipleValidOptions<T extends Array<unknown>>(...args: T): T[number];

231

```

232

233

**Usage Examples:**

234

235

```typescript

236

import { validate, multipleValidOptions } from "jest-validate";

237

238

// Allow string or number for maxWorkers

239

const exampleConfig = {

240

maxWorkers: multipleValidOptions("50%", 4),

241

verbose: multipleValidOptions(true, "full"), // boolean or specific string

242

timeout: multipleValidOptions(5000, "30s") // number or string

243

};

244

245

const result = validate({

246

maxWorkers: "75%", // Valid - matches string type

247

verbose: true, // Valid - matches boolean type

248

timeout: "45s" // Valid - matches string type

249

}, { exampleConfig });

250

```

251

252

### Error Handling

253

254

Custom error class for validation failures with formatted, colorized output designed for developer-friendly error messages.

255

256

```typescript { .api }

257

/**

258

* Custom error class for validation failures with formatted output

259

*/

260

class ValidationError extends Error {

261

override name: string;

262

override message: string;

263

264

/**

265

* Creates a new validation error with formatted message

266

* @param name - Error name/title to display

267

* @param message - Main error message content

268

* @param comment - Optional additional comment or documentation reference

269

*/

270

constructor(name: string, message: string, comment?: string | null);

271

}

272

```

273

274

### Utility Functions

275

276

Helper functions for formatting values and creating user-friendly error messages.

277

278

```typescript { .api }

279

/**

280

* Formats values for display in error messages

281

* @param value - Value to format (any type)

282

* @returns Formatted string representation

283

*/

284

function format(value: unknown): string;

285

286

/**

287

* Formats values as pretty-printed objects for display

288

* @param value - Value to format (any type)

289

* @returns Pretty-formatted string representation with indentation

290

*/

291

function formatPrettyObject(value: unknown): string;

292

293

/**

294

* Creates suggestion messages for similar option names using edit distance

295

* @param unrecognized - The unrecognized option name

296

* @param allowedOptions - Array of valid option names

297

* @returns Suggestion message or empty string if no close matches

298

*/

299

function createDidYouMeanMessage(

300

unrecognized: string,

301

allowedOptions: Array<string>

302

): string;

303

304

/**

305

* Logs validation warnings to console with formatted output

306

* @param name - Warning name/title

307

* @param message - Warning message content

308

* @param comment - Optional additional comment

309

*/

310

function logValidationWarning(

311

name: string,

312

message: string,

313

comment?: string | null

314

): void;

315

```

316

317

**Usage Examples:**

318

319

```typescript

320

import { ValidationError, format, createDidYouMeanMessage } from "jest-validate";

321

322

// Custom error handling

323

try {

324

// Some validation logic

325

throw new ValidationError(

326

"Custom Validation Error",

327

`Invalid value: ${format(userValue)}`,

328

"Check the documentation for valid options"

329

);

330

} catch (error) {

331

console.error(error.message); // Formatted, colorized output

332

}

333

334

// Generate suggestions

335

const suggestion = createDidYouMeanMessage("verbos", ["verbose", "version"]);

336

console.log(suggestion); // "Did you mean verbose?"

337

338

// Format various value types

339

console.log(format("hello")); // "hello"

340

console.log(format(42)); // 42

341

console.log(format([1, 2, 3])); // [1, 2, 3]

342

console.log(format(undefined)); // undefined

343

344

// Format with pretty printing for objects

345

console.log(formatPrettyObject({ name: "test", value: 42 }));

346

// Output:

347

// {

348

// "name": "test",

349

// "value": 42

350

// }

351

```

352

353

## Advanced Configuration

354

355

### Custom Validation Conditions

356

357

```typescript

358

import { validate } from "jest-validate";

359

360

const result = validate(userConfig, {

361

exampleConfig: { port: 3000 },

362

condition: (option, validOption) => {

363

// Custom logic for port validation

364

if (typeof option === 'number' && typeof validOption === 'number') {

365

return option > 0 && option < 65536;

366

}

367

return option === validOption;

368

}

369

});

370

```

371

372

### Custom Error Handlers

373

374

```typescript

375

import { validate, ValidationError } from "jest-validate";

376

377

const result = validate(userConfig, {

378

exampleConfig: { timeout: 5000 },

379

error: (option, received, defaultValue, options, path) => {

380

const fullPath = path ? `${path.join('.')}.${option}` : option;

381

throw new ValidationError(

382

"Configuration Error",

383

`Option "${fullPath}" expected ${typeof defaultValue} but got ${typeof received}`,

384

"Please check your configuration file"

385

);

386

}

387

});

388

```

389

390

### Handling Unknown Options

391

392

```typescript

393

import { validate } from "jest-validate";

394

395

const result = validate(userConfig, {

396

exampleConfig: { knownOption: true },

397

unknown: (config, exampleConfig, option, options, path) => {

398

const fullPath = path ? `${path.join('.')}.${option}` : option;

399

console.warn(`Unknown option "${fullPath}" will be ignored`);

400

// Could also delete the unknown option: delete config[option];

401

}

402

});

403

```