0
# Utility Functions
1
2
Helper functions for type checking, introspection, and working with joi objects and errors.
3
4
## Capabilities
5
6
### Type Checking Functions
7
8
Functions for identifying joi objects and their types.
9
10
```typescript { .api }
11
/**
12
* Checks if value is a joi schema object
13
* @param schema - Value to check
14
* @param options - Optional checking options
15
* @returns True if value is a joi schema
16
*/
17
function isSchema(schema: any, options?: any): schema is Schema;
18
19
/**
20
* Checks if value is a reference object
21
* @param ref - Value to check
22
* @returns True if value is Reference object
23
*/
24
function isRef(ref: any): ref is Reference;
25
26
/**
27
* Checks if value is a template expression
28
* @param expression - Value to check
29
* @returns True if value is Template object
30
*/
31
function isExpression(expression: any): expression is Template;
32
33
/**
34
* Checks if error is a ValidationError instance
35
* @param error - Error object to check
36
* @returns True if error is ValidationError
37
*/
38
function isError(error: any): error is ValidationError;
39
```
40
41
**Usage Examples:**
42
43
```javascript
44
const Joi = require('joi');
45
46
const schema = Joi.string().min(3);
47
const ref = Joi.ref('field');
48
const template = Joi.expression('Hello {#name}');
49
const error = new Joi.ValidationError('Test error', [], null);
50
const regularString = 'not a joi object';
51
52
// Type checking
53
console.log(Joi.isSchema(schema)); // true
54
console.log(Joi.isSchema(ref)); // false
55
console.log(Joi.isSchema(regularString)); // false
56
57
console.log(Joi.isRef(ref)); // true
58
console.log(Joi.isRef(schema)); // false
59
60
console.log(Joi.isExpression(template)); // true
61
console.log(Joi.isExpression(schema)); // false
62
63
console.log(Joi.isError(error)); // true
64
console.log(Joi.isError(new Error())); // false
65
66
// Conditional logic based on type checking
67
function processJoiValue(value) {
68
if (Joi.isSchema(value)) {
69
return value.describe();
70
} else if (Joi.isRef(value)) {
71
return `Reference to: ${value.key}`;
72
} else if (Joi.isExpression(value)) {
73
return `Template: ${value.source}`;
74
} else {
75
return 'Not a joi object';
76
}
77
}
78
```
79
80
### Schema Introspection
81
82
Functions for examining and working with schema instances.
83
84
```typescript { .api }
85
/**
86
* Returns object containing all available schema types
87
* @returns Record mapping type names to schema instances
88
*/
89
function types(): Record<string, Schema>;
90
```
91
92
**Usage Examples:**
93
94
```javascript
95
// Get all available schema types
96
const allTypes = Joi.types();
97
98
console.log(Object.keys(allTypes));
99
// ['any', 'array', 'boolean', 'date', 'function', 'link',
100
// 'number', 'object', 'string', 'symbol', 'alternatives',
101
// 'binary', 'alt', 'bool', 'func']
102
103
// Access specific schema types
104
const stringSchema = allTypes.string;
105
const numberSchema = allTypes.number;
106
107
// Use in dynamic schema creation
108
function createSchemaByType(type, options = {}) {
109
const availableTypes = Joi.types();
110
if (availableTypes[type]) {
111
return availableTypes[type];
112
}
113
throw new Error(`Unknown schema type: ${type}`);
114
}
115
116
const dynamicSchema = createSchemaByType('string').min(5);
117
```
118
119
### Global Properties
120
121
Global constants and configuration objects.
122
123
```typescript { .api }
124
/**
125
* Library version string
126
*/
127
const version: string;
128
129
/**
130
* Cache configuration provider
131
*/
132
const cache: CacheProvider;
133
134
/**
135
* Special symbol for resetting allowed values
136
*/
137
const override: symbol;
138
139
interface CacheProvider {
140
provision(options?: CacheOptions): Cache;
141
}
142
143
interface CacheOptions {
144
max?: number; // Maximum cache entries
145
maxAge?: number; // Maximum age in milliseconds
146
}
147
148
interface Cache {
149
get(key: string): any;
150
set(key: string, value: any, ttl?: number): void;
151
has(key: string): boolean;
152
clear(): void;
153
}
154
```
155
156
**Usage Examples:**
157
158
```javascript
159
// Check joi version
160
console.log(`Using joi version: ${Joi.version}`);
161
162
// Use override symbol to reset allowed values
163
const schema = Joi.string()
164
.valid('a', 'b', 'c')
165
.valid(Joi.override, 'x', 'y', 'z'); // Replaces previous valid values
166
167
// Custom cache configuration
168
const customCache = Joi.cache.provision({
169
max: 1000, // Maximum 1000 cached schemas
170
maxAge: 300000 // Cache for 5 minutes
171
});
172
173
// Use cache with schema validation
174
const cachedSchema = Joi.string().cache(customCache);
175
```
176
177
### ValidationError Class
178
179
Error class specifically for joi validation failures.
180
181
```typescript { .api }
182
/**
183
* Joi validation error constructor
184
*/
185
class ValidationError extends Error {
186
name: 'ValidationError';
187
isJoi: true;
188
details: ValidationErrorItem[];
189
_original: any;
190
191
/**
192
* Creates a new ValidationError
193
* @param message - Error message
194
* @param details - Array of error details
195
* @param original - Original input value
196
*/
197
constructor(message: string, details: ValidationErrorItem[], original: any);
198
199
/**
200
* Returns formatted error message with annotations
201
* @param options - Formatting options
202
* @returns Annotated error string
203
*/
204
annotate(options?: AnnotateOptions): string;
205
206
/**
207
* Static method to check if error is ValidationError
208
* @param error - Error to check
209
* @returns True if error is ValidationError instance
210
*/
211
static isError(error: any): error is ValidationError;
212
}
213
214
interface ValidationErrorItem {
215
message: string; // Error message
216
path: (string | number)[]; // Path to error location
217
type: string; // Error type identifier
218
context?: { // Error context
219
key?: string; // Field key
220
label?: string; // Field label
221
value?: any; // Invalid value
222
limit?: any; // Constraint limit
223
encoding?: string; // Expected encoding
224
[key: string]: any; // Additional context
225
};
226
}
227
228
interface AnnotateOptions {
229
stripColors?: boolean; // Remove color codes
230
}
231
```
232
233
**Usage Examples:**
234
235
```javascript
236
// Create custom ValidationError
237
const customError = new Joi.ValidationError(
238
'Custom validation failed',
239
[{
240
message: 'Value is invalid',
241
path: ['field'],
242
type: 'custom.invalid',
243
context: { key: 'field', value: 'bad-value' }
244
}],
245
{ field: 'bad-value' }
246
);
247
248
// Check error type
249
console.log(Joi.ValidationError.isError(customError)); // true
250
console.log(customError.isJoi); // true
251
252
// Use in validation
253
try {
254
const result = schema.validate(invalidData);
255
if (result.error) {
256
throw result.error;
257
}
258
} catch (error) {
259
if (Joi.ValidationError.isError(error)) {
260
console.log('Validation failed:', error.annotate());
261
console.log('Original value:', error._original);
262
console.log('Error details:', error.details);
263
} else {
264
console.log('Other error:', error.message);
265
}
266
}
267
```
268
269
### Error Handling Utilities
270
271
Helper functions for working with validation errors.
272
273
```typescript { .api }
274
interface ErrorUtilities {
275
/**
276
* Formats error details for display
277
* @param error - ValidationError instance
278
* @returns Formatted error information
279
*/
280
formatError(error: ValidationError): FormattedError;
281
282
/**
283
* Extracts error paths from ValidationError
284
* @param error - ValidationError instance
285
* @returns Array of error paths
286
*/
287
getErrorPaths(error: ValidationError): string[];
288
289
/**
290
* Groups errors by path
291
* @param error - ValidationError instance
292
* @returns Map of paths to error details
293
*/
294
groupErrorsByPath(error: ValidationError): Map<string, ValidationErrorItem[]>;
295
}
296
297
interface FormattedError {
298
message: string;
299
errors: {
300
path: string;
301
message: string;
302
type: string;
303
value?: any;
304
}[];
305
}
306
```
307
308
**Usage Examples:**
309
310
```javascript
311
// Custom error handling utilities
312
function formatValidationError(error) {
313
if (!Joi.ValidationError.isError(error)) {
314
return { message: error.message, errors: [] };
315
}
316
317
return {
318
message: error.message,
319
errors: error.details.map(detail => ({
320
path: detail.path.join('.'),
321
message: detail.message,
322
type: detail.type,
323
value: detail.context?.value
324
}))
325
};
326
}
327
328
function getErrorPaths(error) {
329
if (!Joi.ValidationError.isError(error)) {
330
return [];
331
}
332
333
return error.details.map(detail => detail.path.join('.'));
334
}
335
336
function groupErrorsByPath(error) {
337
const groups = new Map();
338
339
if (Joi.ValidationError.isError(error)) {
340
error.details.forEach(detail => {
341
const path = detail.path.join('.');
342
if (!groups.has(path)) {
343
groups.set(path, []);
344
}
345
groups.get(path).push(detail);
346
});
347
}
348
349
return groups;
350
}
351
352
// Usage in error handling
353
const schema = Joi.object({
354
name: Joi.string().min(3).required(),
355
email: Joi.string().email().required(),
356
age: Joi.number().min(18)
357
});
358
359
const { error } = schema.validate({
360
name: 'Jo',
361
email: 'invalid-email',
362
age: 16
363
});
364
365
if (error) {
366
console.log('Formatted error:', formatValidationError(error));
367
console.log('Error paths:', getErrorPaths(error));
368
console.log('Grouped errors:', groupErrorsByPath(error));
369
}
370
```
371
372
### Schema Description and Metadata
373
374
Functions for extracting schema information and metadata.
375
376
```typescript { .api }
377
interface SchemaIntrospection {
378
/**
379
* Gets schema description with full metadata
380
* @param schema - Schema to describe
381
* @returns Complete schema description
382
*/
383
describe(schema: Schema): SchemaDescription;
384
385
/**
386
* Extracts schema type information
387
* @param schema - Schema to analyze
388
* @returns Schema type details
389
*/
390
getSchemaType(schema: Schema): SchemaTypeInfo;
391
392
/**
393
* Gets all validation rules for schema
394
* @param schema - Schema to analyze
395
* @returns Array of validation rules
396
*/
397
getSchemaRules(schema: Schema): RuleInfo[];
398
}
399
400
interface SchemaDescription {
401
type: string;
402
flags?: Record<string, any>;
403
rules?: RuleDescription[];
404
preferences?: ValidationOptions;
405
allow?: any[];
406
invalid?: any[];
407
labels?: Record<string, string>;
408
metas?: any[];
409
notes?: string[];
410
tags?: string[];
411
examples?: ExampleDescription[];
412
}
413
414
interface SchemaTypeInfo {
415
type: string;
416
isRequired: boolean;
417
isOptional: boolean;
418
isForbidden: boolean;
419
hasDefault: boolean;
420
allowedValues?: any[];
421
invalidValues?: any[];
422
}
423
```
424
425
**Usage Examples:**
426
427
```javascript
428
// Schema introspection utilities
429
function analyzeSchema(schema) {
430
const description = schema.describe();
431
432
return {
433
type: description.type,
434
isRequired: description.flags?.presence === 'required',
435
isOptional: description.flags?.presence === 'optional',
436
isForbidden: description.flags?.presence === 'forbidden',
437
hasRules: Array.isArray(description.rules) && description.rules.length > 0,
438
allowedValues: description.allow,
439
invalidValues: description.invalid,
440
hasExamples: Array.isArray(description.examples) && description.examples.length > 0
441
};
442
}
443
444
// Usage
445
const complexSchema = Joi.object({
446
username: Joi.string().min(3).max(20).required(),
447
email: Joi.string().email().optional(),
448
role: Joi.string().valid('user', 'admin').default('user')
449
});
450
451
const analysis = analyzeSchema(complexSchema);
452
console.log('Schema analysis:', analysis);
453
454
// Extract specific schema information
455
const usernameSchema = complexSchema.extract(['username']);
456
const usernameAnalysis = analyzeSchema(usernameSchema);
457
console.log('Username field analysis:', usernameAnalysis);
458
```